feat: omc原始代码
This commit is contained in:
22
src/framework/middleware/security/csp.go
Normal file
22
src/framework/middleware/security/csp.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"nms_nbi/src/framework/config"
|
||||
"nms_nbi/src/framework/utils/generate"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// TODO
|
||||
// csp 这将帮助防止跨站脚本攻击(XSS)。
|
||||
// HTTP 响应头 Content-Security-Policy 允许站点管理者控制指定的页面加载哪些资源。
|
||||
func csp(c *gin.Context) {
|
||||
enable := false
|
||||
if v := config.Get("security.csp.enable"); v != nil {
|
||||
enable = v.(bool)
|
||||
}
|
||||
|
||||
if enable {
|
||||
c.Header("x-csp-nonce", generate.Code(8))
|
||||
}
|
||||
}
|
||||
37
src/framework/middleware/security/hsts.go
Normal file
37
src/framework/middleware/security/hsts.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"nms_nbi/src/framework/config"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// hsts 是一个安全功能 HTTP Strict Transport Security(通常简称为 HSTS )
|
||||
// 它告诉浏览器只能通过 HTTPS 访问当前资源,而不是 HTTP。
|
||||
func hsts(c *gin.Context) {
|
||||
enable := false
|
||||
if v := config.Get("security.hsts.enable"); v != nil {
|
||||
enable = v.(bool)
|
||||
}
|
||||
|
||||
maxAge := 365 * 24 * 3600
|
||||
if v := config.Get("security.hsts.maxAge"); v != nil {
|
||||
maxAge = v.(int)
|
||||
}
|
||||
|
||||
includeSubdomains := false
|
||||
if v := config.Get("security.hsts.includeSubdomains"); v != nil {
|
||||
includeSubdomains = v.(bool)
|
||||
}
|
||||
|
||||
str := fmt.Sprintf("max-age=%d", maxAge)
|
||||
if includeSubdomains {
|
||||
str += "; includeSubdomains"
|
||||
}
|
||||
|
||||
if enable {
|
||||
c.Header("strict-transport-security", str)
|
||||
}
|
||||
}
|
||||
20
src/framework/middleware/security/noopen.go
Normal file
20
src/framework/middleware/security/noopen.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"nms_nbi/src/framework/config"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// noopen 用于指定 IE 8 以上版本的用户不打开文件而直接保存文件。
|
||||
// 在下载对话框中不显式“打开”选项。
|
||||
func noopen(c *gin.Context) {
|
||||
enable := false
|
||||
if v := config.Get("security.noopen.enable"); v != nil {
|
||||
enable = v.(bool)
|
||||
}
|
||||
|
||||
if enable {
|
||||
c.Header("x-download-options", "noopen")
|
||||
}
|
||||
}
|
||||
26
src/framework/middleware/security/nosniff.go
Normal file
26
src/framework/middleware/security/nosniff.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"nms_nbi/src/framework/config"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// nosniff 用于防止 XSS 等跨站脚本攻击
|
||||
// 如果从 script 或 stylesheet 读入的文件的 MIME 类型与指定 MIME 类型不匹配,不允许读取该文件。
|
||||
func nosniff(c *gin.Context) {
|
||||
// 排除状态码范围
|
||||
status := c.Writer.Status()
|
||||
if status >= 300 && status <= 308 {
|
||||
return
|
||||
}
|
||||
|
||||
enable := false
|
||||
if v := config.Get("security.nosniff.enable"); v != nil {
|
||||
enable = v.(bool)
|
||||
}
|
||||
|
||||
if enable {
|
||||
c.Header("x-content-type-options", "nosniff")
|
||||
}
|
||||
}
|
||||
79
src/framework/middleware/security/referer.go
Normal file
79
src/framework/middleware/security/referer.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"nms_nbi/src/framework/config"
|
||||
"nms_nbi/src/framework/vo/result"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// referer 配置 referer 的 host 部分
|
||||
func referer(c *gin.Context) {
|
||||
enable := false
|
||||
if v := config.Get("security.csrf.enable"); v != nil {
|
||||
enable = v.(bool)
|
||||
}
|
||||
if !enable {
|
||||
return
|
||||
}
|
||||
|
||||
// csrf 校验类型
|
||||
okType := false
|
||||
if v := config.Get("security.csrf.type"); v != nil {
|
||||
vType := v.(string)
|
||||
if vType == "all" || vType == "any" || vType == "referer" {
|
||||
okType = true
|
||||
}
|
||||
}
|
||||
if !okType {
|
||||
return
|
||||
}
|
||||
|
||||
// 忽略请求方法
|
||||
method := c.Request.Method
|
||||
ignoreMethods := []string{"GET", "HEAD", "OPTIONS", "TRACE"}
|
||||
for _, ignore := range ignoreMethods {
|
||||
if ignore == method {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
referer := c.GetHeader("Referer")
|
||||
if referer == "" {
|
||||
// 无效 Referer 未知
|
||||
c.AbortWithStatusJSON(200, result.ErrMsg("Invalid referer unknown"))
|
||||
return
|
||||
}
|
||||
|
||||
// 获取host
|
||||
u, err := url.Parse(referer)
|
||||
if err != nil {
|
||||
// 无效 Referer 未知
|
||||
c.AbortWithStatusJSON(200, result.ErrMsg("Invalid referer unknown"))
|
||||
return
|
||||
}
|
||||
host := u.Host
|
||||
|
||||
// 允许的来源白名单
|
||||
refererWhiteList := make([]string, 0)
|
||||
if v := config.Get("security.csrf.refererWhiteList"); v != nil {
|
||||
for _, s := range v.([]any) {
|
||||
refererWhiteList = append(refererWhiteList, s.(string))
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历检查
|
||||
ok := false
|
||||
for _, domain := range refererWhiteList {
|
||||
if domain == host {
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
// 无效 Referer
|
||||
c.AbortWithStatusJSON(200, result.ErrMsg("Invalid referer "+host))
|
||||
return
|
||||
}
|
||||
}
|
||||
23
src/framework/middleware/security/security.go
Normal file
23
src/framework/middleware/security/security.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Security 安全
|
||||
func Security() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// 拦截,判断是否有效Referer
|
||||
referer(c)
|
||||
|
||||
// 无拦截,仅仅设置响应头
|
||||
xframe(c)
|
||||
csp(c)
|
||||
hsts(c)
|
||||
noopen(c)
|
||||
nosniff(c)
|
||||
xssProtection(c)
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
26
src/framework/middleware/security/xframe.go
Normal file
26
src/framework/middleware/security/xframe.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"nms_nbi/src/framework/config"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// xframe 用来配置 X-Frame-Options 响应头
|
||||
// 用来给浏览器指示允许一个页面可否在 frame, iframe, embed 或者 object 中展现的标记。
|
||||
// 站点可以通过确保网站没有被嵌入到别人的站点里面,从而避免 clickjacking 攻击。
|
||||
func xframe(c *gin.Context) {
|
||||
enable := false
|
||||
if v := config.Get("security.xframe.enable"); v != nil {
|
||||
enable = v.(bool)
|
||||
}
|
||||
|
||||
value := "sameorigin"
|
||||
if v := config.Get("security.xframe.value"); v != nil {
|
||||
value = v.(string)
|
||||
}
|
||||
|
||||
if enable {
|
||||
c.Header("x-frame-options", value)
|
||||
}
|
||||
}
|
||||
24
src/framework/middleware/security/xss_protection.go
Normal file
24
src/framework/middleware/security/xss_protection.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"nms_nbi/src/framework/config"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// xssProtection 用于启用浏览器的XSS过滤功能,以防止 XSS 跨站脚本攻击。
|
||||
func xssProtection(c *gin.Context) {
|
||||
enable := false
|
||||
if v := config.Get("security.xssProtection.enable"); v != nil {
|
||||
enable = v.(bool)
|
||||
}
|
||||
|
||||
value := "1; mode=block"
|
||||
if v := config.Get("security.xssProtection.value"); v != nil {
|
||||
value = v.(string)
|
||||
}
|
||||
|
||||
if enable {
|
||||
c.Header("x-xss-protection", value)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user