diff --git a/content/en/docs/examples/security-headers.md b/content/en/docs/examples/security-headers.md new file mode 100644 index 000000000..80e11fa88 --- /dev/null +++ b/content/en/docs/examples/security-headers.md @@ -0,0 +1,75 @@ +--- +title: "Security Headers" +draft: false +--- + +It's important to use security headers to protect your web application from common security vulnerabilities. This example shows you how to add security headers to your Gin application and also how to avoid Host Header Injection related attacks (SSRF, Open Redirection). + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + expectedHost := "localhost:8080" + + // Setup Security Headers + r.Use(func(c *gin.Context) { + if c.Request.Host != expectedHost { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"}) + return + } + c.Header("X-Frame-Options", "DENY") + c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';") + c.Header("X-XSS-Protection", "1; mode=block") + c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") + c.Header("Referrer-Policy", "strict-origin") + c.Header("X-Content-Type-Options", "nosniff") + c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()") + c.Next() + }) + + r.GET("/ping", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "pong", + }) + }) + + r.Run() // listen and serve on 0.0.0.0:8080 +} +``` + +You can test it via `curl`: + +```bash +// Check Headers + +curl localhost:8080/ping -I + +HTTP/1.1 404 Not Found +Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline'; +Content-Type: text/plain +Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=() +Referrer-Policy: strict-origin +Strict-Transport-Security: max-age=31536000; includeSubDomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Xss-Protection: 1; mode=block +Date: Sat, 30 Mar 2024 08:20:44 GMT +Content-Length: 18 + +// Check Host Header Injection + +curl localhost:8080/ping -I -H "Host:neti.ee" + +HTTP/1.1 400 Bad Request +Content-Type: application/json; charset=utf-8 +Date: Sat, 30 Mar 2024 08:21:09 GMT +Content-Length: 31 +``` \ No newline at end of file diff --git a/content/es/docs/examples/security-headers.md b/content/es/docs/examples/security-headers.md new file mode 100644 index 000000000..7f06f31a1 --- /dev/null +++ b/content/es/docs/examples/security-headers.md @@ -0,0 +1,74 @@ +--- +title: "Encabezados de seguridad" +draft: false +--- +Es importante utilizar cabeceras de seguridad para proteger su aplicación web de vulnerabilidades de seguridad comunes. Este ejemplo le muestra cómo añadir cabeceras de seguridad a su aplicación Gin y también cómo evitar ataques relacionados con Host Header Injection (SSRF, Open Redirection). + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + expectedHost := "localhost:8080" + + // Setup Security Headers + r.Use(func(c *gin.Context) { + if c.Request.Host != expectedHost { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"}) + return + } + c.Header("X-Frame-Options", "DENY") + c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';") + c.Header("X-XSS-Protection", "1; mode=block") + c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") + c.Header("Referrer-Policy", "strict-origin") + c.Header("X-Content-Type-Options", "nosniff") + c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()") + c.Next() + }) + + r.GET("/ping", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "pong", + }) + }) + + r.Run() // listen and serve on 0.0.0.0:8080 +} +``` + +Puede probarlo mediante `curl`: + +```bash +// ヘッダーのチェック + +curl localhost:8080/ping -I + +HTTP/1.1 404 Not Found +Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline'; +Content-Type: text/plain +Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=() +Referrer-Policy: strict-origin +Strict-Transport-Security: max-age=31536000; includeSubDomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Xss-Protection: 1; mode=block +Date: Sat, 30 Mar 2024 08:20:44 GMT +Content-Length: 18 + +// ホスト・ヘッダー・インジェクションのチェック + +curl localhost:8080/ping -I -H "Host:neti.ee" + +HTTP/1.1 400 Bad Request +Content-Type: application/json; charset=utf-8 +Date: Sat, 30 Mar 2024 08:21:09 GMT +Content-Length: 31 +``` \ No newline at end of file diff --git a/content/fa/docs/examples/security-headers.md b/content/fa/docs/examples/security-headers.md new file mode 100644 index 000000000..80e11fa88 --- /dev/null +++ b/content/fa/docs/examples/security-headers.md @@ -0,0 +1,75 @@ +--- +title: "Security Headers" +draft: false +--- + +It's important to use security headers to protect your web application from common security vulnerabilities. This example shows you how to add security headers to your Gin application and also how to avoid Host Header Injection related attacks (SSRF, Open Redirection). + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + expectedHost := "localhost:8080" + + // Setup Security Headers + r.Use(func(c *gin.Context) { + if c.Request.Host != expectedHost { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"}) + return + } + c.Header("X-Frame-Options", "DENY") + c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';") + c.Header("X-XSS-Protection", "1; mode=block") + c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") + c.Header("Referrer-Policy", "strict-origin") + c.Header("X-Content-Type-Options", "nosniff") + c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()") + c.Next() + }) + + r.GET("/ping", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "pong", + }) + }) + + r.Run() // listen and serve on 0.0.0.0:8080 +} +``` + +You can test it via `curl`: + +```bash +// Check Headers + +curl localhost:8080/ping -I + +HTTP/1.1 404 Not Found +Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline'; +Content-Type: text/plain +Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=() +Referrer-Policy: strict-origin +Strict-Transport-Security: max-age=31536000; includeSubDomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Xss-Protection: 1; mode=block +Date: Sat, 30 Mar 2024 08:20:44 GMT +Content-Length: 18 + +// Check Host Header Injection + +curl localhost:8080/ping -I -H "Host:neti.ee" + +HTTP/1.1 400 Bad Request +Content-Type: application/json; charset=utf-8 +Date: Sat, 30 Mar 2024 08:21:09 GMT +Content-Length: 31 +``` \ No newline at end of file diff --git a/content/ja/docs/examples/security-headers.md b/content/ja/docs/examples/security-headers.md new file mode 100644 index 000000000..521eeeef2 --- /dev/null +++ b/content/ja/docs/examples/security-headers.md @@ -0,0 +1,76 @@ +--- +title: "セキュリティ・ヘッダ" +draft: false +--- + +セキュリティヘッダの使用は、一般的なセキュリティの脆弱性からウェブアプリケーションを守るために重要です。この例では、Gin アプリケーションにセキュリティヘッダーを追加する方法と、ホストヘッダーインジェクションに関連する攻撃(SSRF、Open Redirection)を回避する方法を示します。 + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + expectedHost := "localhost:8080" + + // Setup Security Headers + r.Use(func(c *gin.Context) { + if c.Request.Host != expectedHost { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"}) + return + } + c.Header("X-Frame-Options", "DENY") + c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';") + c.Header("X-XSS-Protection", "1; mode=block") + c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") + c.Header("Referrer-Policy", "strict-origin") + c.Header("X-Content-Type-Options", "nosniff") + c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()") + c.Next() + }) + + r.GET("/ping", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "pong", + }) + }) + + r.Run() // listen and serve on 0.0.0.0:8080 +} +``` + +`curl`でテストできます: + + +```bash +// ヘッダーのチェック + +curl localhost:8080/ping -I + +HTTP/1.1 404 Not Found +Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline'; +Content-Type: text/plain +Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=() +Referrer-Policy: strict-origin +Strict-Transport-Security: max-age=31536000; includeSubDomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Xss-Protection: 1; mode=block +Date: Sat, 30 Mar 2024 08:20:44 GMT +Content-Length: 18 + +// ホスト・ヘッダー・インジェクションのチェック + +curl localhost:8080/ping -I -H "Host:neti.ee" + +HTTP/1.1 400 Bad Request +Content-Type: application/json; charset=utf-8 +Date: Sat, 30 Mar 2024 08:21:09 GMT +Content-Length: 31 +``` \ No newline at end of file diff --git a/content/ko-kr/docs/examples/security-headers.md b/content/ko-kr/docs/examples/security-headers.md new file mode 100644 index 000000000..cd308b6d5 --- /dev/null +++ b/content/ko-kr/docs/examples/security-headers.md @@ -0,0 +1,76 @@ +--- +title: "보안 헤더" +draft: false +--- + +일반적인 보안 취약점으로부터 웹 애플리케이션을 보호하려면 보안 헤더를 사용하는 것이 중요합니다. 이 예에서는 Gin 애플리케이션에 보안 헤더를 추가하는 방법과 호스트 헤더 인젝션 관련 공격(SSRF, 오픈 리디렉션)을 방지하는 방법을 설명합니다. + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + expectedHost := "localhost:8080" + + // Setup Security Headers + r.Use(func(c *gin.Context) { + if c.Request.Host != expectedHost { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"}) + return + } + c.Header("X-Frame-Options", "DENY") + c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';") + c.Header("X-XSS-Protection", "1; mode=block") + c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") + c.Header("Referrer-Policy", "strict-origin") + c.Header("X-Content-Type-Options", "nosniff") + c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()") + c.Next() + }) + + r.GET("/ping", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "pong", + }) + }) + + r.Run() // listen and serve on 0.0.0.0:8080 +} +``` + +`curl` 로 테스트할 수 있습니다: + + +```bash +// 헤더 확인 + +curl localhost:8080/ping -I + +HTTP/1.1 404 Not Found +Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline'; +Content-Type: text/plain +Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=() +Referrer-Policy: strict-origin +Strict-Transport-Security: max-age=31536000; includeSubDomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Xss-Protection: 1; mode=block +Date: Sat, 30 Mar 2024 08:20:44 GMT +Content-Length: 18 + +// 호스트 헤더 주입 확인 + +curl localhost:8080/ping -I -H "Host:neti.ee" + +HTTP/1.1 400 Bad Request +Content-Type: application/json; charset=utf-8 +Date: Sat, 30 Mar 2024 08:21:09 GMT +Content-Length: 31 +``` \ No newline at end of file diff --git a/content/pt/docs/examples/security-headers.md b/content/pt/docs/examples/security-headers.md new file mode 100644 index 000000000..15f75f58d --- /dev/null +++ b/content/pt/docs/examples/security-headers.md @@ -0,0 +1,75 @@ +--- +title: "Cabeçalhos de segurança" +draft: false +--- + +É importante utilizar cabeçalhos de segurança para proteger a sua aplicação Web de vulnerabilidades de segurança comuns. Este exemplo mostra-lhe como adicionar cabeçalhos de segurança à sua aplicação Gin e também como evitar ataques relacionados com a injeção de cabeçalhos de anfitrião (SSRF, Open Redirection). + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + expectedHost := "localhost:8080" + + // Setup Security Headers + r.Use(func(c *gin.Context) { + if c.Request.Host != expectedHost { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"}) + return + } + c.Header("X-Frame-Options", "DENY") + c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';") + c.Header("X-XSS-Protection", "1; mode=block") + c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") + c.Header("Referrer-Policy", "strict-origin") + c.Header("X-Content-Type-Options", "nosniff") + c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()") + c.Next() + }) + + r.GET("/ping", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "pong", + }) + }) + + r.Run() // listen and serve on 0.0.0.0:8080 +} +``` + +Pode testá-lo através de `curl`: + +```bash +// Verificar cabeçalhos + +curl localhost:8080/ping -I + +HTTP/1.1 404 Not Found +Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline'; +Content-Type: text/plain +Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=() +Referrer-Policy: strict-origin +Strict-Transport-Security: max-age=31536000; includeSubDomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Xss-Protection: 1; mode=block +Date: Sat, 30 Mar 2024 08:20:44 GMT +Content-Length: 18 + +// Verificar a injeção do cabeçalho do anfitrião + +curl localhost:8080/ping -I -H "Host:neti.ee" + +HTTP/1.1 400 Bad Request +Content-Type: application/json; charset=utf-8 +Date: Sat, 30 Mar 2024 08:21:09 GMT +Content-Length: 31 +``` \ No newline at end of file diff --git a/content/tr/docs/examples/security-headers.md b/content/tr/docs/examples/security-headers.md new file mode 100644 index 000000000..89dabcce9 --- /dev/null +++ b/content/tr/docs/examples/security-headers.md @@ -0,0 +1,75 @@ +--- +title: "Güvenlik Üst Bilgileri" +draft: false +--- + +Web uygulamanızı yaygın güvenlik açıklarından korumak için güvenlik başlıklarını kullanmak önemlidir. Bu örnek, Gin uygulamanıza güvenlik başlıklarını nasıl ekleyeceğinizi ve ayrıca Host Header Injection ile ilgili saldırılardan (SSRF, Open Redirection) nasıl kaçınacağınızı gösterir. + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + expectedHost := "localhost:8080" + + // Setup Security Headers + r.Use(func(c *gin.Context) { + if c.Request.Host != expectedHost { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"}) + return + } + c.Header("X-Frame-Options", "DENY") + c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';") + c.Header("X-XSS-Protection", "1; mode=block") + c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") + c.Header("Referrer-Policy", "strict-origin") + c.Header("X-Content-Type-Options", "nosniff") + c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()") + c.Next() + }) + + r.GET("/ping", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "pong", + }) + }) + + r.Run() // listen and serve on 0.0.0.0:8080 +} +``` + +You can test it via `curl`: + +```bash +// Başlıkları Kontrol Edin + +curl localhost:8080/ping -I + +HTTP/1.1 404 Not Found +Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline'; +Content-Type: text/plain +Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=() +Referrer-Policy: strict-origin +Strict-Transport-Security: max-age=31536000; includeSubDomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Xss-Protection: 1; mode=block +Date: Sat, 30 Mar 2024 08:20:44 GMT +Content-Length: 18 + +// Ana Bilgisayar Başlık Enjeksiyonunu Kontrol Et + +curl localhost:8080/ping -I -H "Host:neti.ee" + +HTTP/1.1 400 Bad Request +Content-Type: application/json; charset=utf-8 +Date: Sat, 30 Mar 2024 08:21:09 GMT +Content-Length: 31 +``` \ No newline at end of file diff --git a/content/zh-cn/docs/examples/security-headers.md b/content/zh-cn/docs/examples/security-headers.md new file mode 100644 index 000000000..d3cf79085 --- /dev/null +++ b/content/zh-cn/docs/examples/security-headers.md @@ -0,0 +1,75 @@ +--- +title: "安全页眉" +draft: false +--- + +使用安全标头保护网络应用程序免受常见安全漏洞的攻击非常重要。本示例将向您展示如何在 Gin 应用程序中添加安全标头,以及如何避免与主机标头注入相关的攻击(SSRF、开放重定向)。 + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + expectedHost := "localhost:8080" + + // Setup Security Headers + r.Use(func(c *gin.Context) { + if c.Request.Host != expectedHost { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"}) + return + } + c.Header("X-Frame-Options", "DENY") + c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';") + c.Header("X-XSS-Protection", "1; mode=block") + c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") + c.Header("Referrer-Policy", "strict-origin") + c.Header("X-Content-Type-Options", "nosniff") + c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()") + c.Next() + }) + + r.GET("/ping", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "pong", + }) + }) + + r.Run() // listen and serve on 0.0.0.0:8080 +} +``` + +您可以通过 `curl` 进行测试。 + +```bash +// 检查页眉 + +curl localhost:8080/ping -I + +HTTP/1.1 404 Not Found +Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline'; +Content-Type: text/plain +Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=() +Referrer-Policy: strict-origin +Strict-Transport-Security: max-age=31536000; includeSubDomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Xss-Protection: 1; mode=block +Date: Sat, 30 Mar 2024 08:20:44 GMT +Content-Length: 18 + +// 检查主机标头注入 + +curl localhost:8080/ping -I -H "Host:neti.ee" + +HTTP/1.1 400 Bad Request +Content-Type: application/json; charset=utf-8 +Date: Sat, 30 Mar 2024 08:21:09 GMT +Content-Length: 31 +``` \ No newline at end of file diff --git a/content/zh-tw/docs/examples/security-headers.md b/content/zh-tw/docs/examples/security-headers.md new file mode 100644 index 000000000..d3cf79085 --- /dev/null +++ b/content/zh-tw/docs/examples/security-headers.md @@ -0,0 +1,75 @@ +--- +title: "安全页眉" +draft: false +--- + +使用安全标头保护网络应用程序免受常见安全漏洞的攻击非常重要。本示例将向您展示如何在 Gin 应用程序中添加安全标头,以及如何避免与主机标头注入相关的攻击(SSRF、开放重定向)。 + +```go +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + expectedHost := "localhost:8080" + + // Setup Security Headers + r.Use(func(c *gin.Context) { + if c.Request.Host != expectedHost { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"}) + return + } + c.Header("X-Frame-Options", "DENY") + c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';") + c.Header("X-XSS-Protection", "1; mode=block") + c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") + c.Header("Referrer-Policy", "strict-origin") + c.Header("X-Content-Type-Options", "nosniff") + c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()") + c.Next() + }) + + r.GET("/ping", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "pong", + }) + }) + + r.Run() // listen and serve on 0.0.0.0:8080 +} +``` + +您可以通过 `curl` 进行测试。 + +```bash +// 检查页眉 + +curl localhost:8080/ping -I + +HTTP/1.1 404 Not Found +Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline'; +Content-Type: text/plain +Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=() +Referrer-Policy: strict-origin +Strict-Transport-Security: max-age=31536000; includeSubDomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Xss-Protection: 1; mode=block +Date: Sat, 30 Mar 2024 08:20:44 GMT +Content-Length: 18 + +// 检查主机标头注入 + +curl localhost:8080/ping -I -H "Host:neti.ee" + +HTTP/1.1 400 Bad Request +Content-Type: application/json; charset=utf-8 +Date: Sat, 30 Mar 2024 08:21:09 GMT +Content-Length: 31 +``` \ No newline at end of file