Skip to content

Commit

Permalink
feat: Added security headers docs (#266)
Browse files Browse the repository at this point in the history
  • Loading branch information
KostLinux committed Apr 18, 2024
1 parent 0e864f3 commit 78dafed
Show file tree
Hide file tree
Showing 9 changed files with 676 additions and 0 deletions.
75 changes: 75 additions & 0 deletions content/en/docs/examples/security-headers.md
Original file line number Diff line number Diff line change
@@ -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
```
74 changes: 74 additions & 0 deletions content/es/docs/examples/security-headers.md
Original file line number Diff line number Diff line change
@@ -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
```
75 changes: 75 additions & 0 deletions content/fa/docs/examples/security-headers.md
Original file line number Diff line number Diff line change
@@ -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
```
76 changes: 76 additions & 0 deletions content/ja/docs/examples/security-headers.md
Original file line number Diff line number Diff line change
@@ -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
```
76 changes: 76 additions & 0 deletions content/ko-kr/docs/examples/security-headers.md
Original file line number Diff line number Diff line change
@@ -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
```

0 comments on commit 78dafed

Please sign in to comment.