Skip to content

安全模式

安全模式提供危险模式检测功能,防止 JSON 注入攻击、原型污染和其他安全威胁。

DangerousPattern 结构体

DangerousPattern 表示一个安全风险模式。它是一个结构体类型。

go
type DangerousPattern struct {
    Pattern string       // 要在输入中检测的子字符串
    Name    string       // 模式的描述性名称
    Level   PatternLevel // 确定如何处理该模式的严重级别
}

字段说明

字段类型说明
Patternstring要在输入中检测的子字符串
Namestring模式的描述性名称
LevelPatternLevel确定如何处理该模式的严重级别

PatternLevel 类型

PatternLevel 表示危险模式的严重级别。

go
type PatternLevel int

常量

go
const (
    // PatternLevelCritical 始终阻止操作
    // 用于立即构成安全风险的模式(如原型污染)
    PatternLevelCritical PatternLevel = iota

    // PatternLevelWarning 在严格模式下阻止,在宽松模式下记录警告
    // 用于可能表明恶意意图但有合法用途的模式
    PatternLevelWarning

    // PatternLevelInfo 仅记录,从不阻止
    // 用于审计/跟踪目的,不中断操作
    PatternLevelInfo
)

String 方法

go
func (pl PatternLevel) String() string

返回 PatternLevel 的字符串表示。


内置危险模式

默认模式

内部 API

内置模式列表由内部函数管理,不再作为公开 API 导出。可通过 Config 的 AdditionalDangerousPatterns 字段管理自定义模式。

以下是内置危险模式列表,全部为 Critical 级别:

模式名称类别
__proto__prototype pollution原型污染
constructor[constructor access构造器访问
prototype.prototype manipulation原型操作
<scriptscript tag injectionHTML 注入
<iframeiframe injectionHTML 注入
<objectobject injectionHTML 注入
<embedembed injectionHTML 注入
<svgsvg injectionHTML 注入
javascript:javascript protocol协议注入
vbscript:vbscript protocol协议注入
eval(dynamic code execution代码执行
setTimeout(timer manipulation代码执行
setInterval(interval manipulation代码执行
require(code injection代码执行
new function(dynamic function creation代码执行
document.cookiecookie accessDOM 访问
window.locationredirect manipulationDOM 访问
innerhtmlDOM manipulationDOM 访问
onerror, onload, onclick, onmouseover, onfocusevent handler injection事件处理器
fromcharcode(character encoding bypass编码绕过
atob(base64 decoding编码绕过
expression(CSS expression injectionCSS 注入
__defineGetter__getter definition原型污染
__defineSetter__setter definition原型污染

关键模式

内部 API

GetCriticalPatterns 已转为内部函数,不再作为公开 API 导出。关键模式(__proto__constructor[prototype.)始终强制检查,无法禁用。

以下关键模式始终完全扫描,无论 JSON 大小如何:

模式说明
__proto__prototype pollution
constructor[constructor access
prototype.prototype manipulation

模式注册方法

危险模式通过 Config 结构体进行配置,而不是全局注册函数。

Config.AddDangerousPattern

签名:func (c *Config) AddDangerousPattern(pattern DangerousPattern)

添加自定义危险模式到配置中。

go
cfg := json.DefaultConfig()
cfg.AddDangerousPattern(json.DangerousPattern{
    Pattern: "malicious_keyword",
    Name:    "自定义危险模式",
    Level:   json.PatternLevelCritical,
})

processor, err := json.New(cfg)
if err != nil {
    panic(err)
}
defer processor.Close()

Config.AdditionalDangerousPatterns

也可以直接设置 Config.AdditionalDangerousPatterns 字段:

go
cfg := json.DefaultConfig()
cfg.AdditionalDangerousPatterns = []json.DangerousPattern{
    {Pattern: "eval(", Name: "eval-call", Level: json.PatternLevelCritical},
    {Pattern: "exec(", Name: "exec-call", Level: json.PatternLevelWarning},
}

Config 配置方法

AddDangerousPattern

向配置中添加安全模式。

go
func (c *Config) AddDangerousPattern(pattern DangerousPattern)
go
cfg := json.DefaultConfig()
cfg.AddDangerousPattern(json.DangerousPattern{
    Pattern: "custom_dangerous_string",
    Name:    "自定义危险字符串",
    Level:   json.PatternLevelWarning,
})

配置字段

go
type Config struct {
    // ... 其他字段 ...

    // AdditionalDangerousPatterns 添加除默认模式外的安全模式
    AdditionalDangerousPatterns []DangerousPattern

    // DisableDefaultPatterns 禁用内置默认安全模式(关键模式除外)
    // 设为 true 则仅使用 AdditionalDangerousPatterns
    // 注意:关键模式(__proto__、constructor[、prototype.)始终强制执行,无法禁用
    DisableDefaultPatterns bool
}

全局模式注册

除了通过 Config 配置实例级模式外,还可以通过包级函数管理全局模式注册表。全局注册表中的模式在所有 Processor 实例中生效。

RegisterDangerousPattern

签名:func RegisterDangerousPattern(pattern DangerousPattern)

向全局注册表添加自定义危险模式。注册的模式在所有 Processor 实例中生效。

go
json.RegisterDangerousPattern(json.DangerousPattern{
    Pattern: "malicious_keyword",
    Name:    "自定义危险模式",
    Level:   json.PatternLevelCritical,
})

UnregisterDangerousPattern

签名:func UnregisterDangerousPattern(pattern string)

从全局注册表中移除指定模式。

go
json.UnregisterDangerousPattern("malicious_keyword")

ListDangerousPatterns

签名:func ListDangerousPatterns() []DangerousPattern

返回全局注册表中所有自定义模式。

go
patterns := json.ListDangerousPatterns()
for _, p := range patterns {
    fmt.Printf("模式: %s, 名称: %s, 级别: %s\n", p.Pattern, p.Name, p.Level)
}

全局模式 vs Config 模式

  • 全局模式RegisterDangerousPattern):所有 Processor 实例共享,适合应用级安全策略
  • Config 模式Config.AddDangerousPattern):仅影响使用该 Config 的 Processor,适合实例级定制

完整示例

自定义安全策略

go
package main

import (
    "fmt"
    "github.com/cybergodev/json"
)

func main() {
    // 方式一:通过配置字段
    cfg := json.DefaultConfig()
    cfg.AdditionalDangerousPatterns = []json.DangerousPattern{
        {Pattern: "company_secret", Name: "公司敏感信息", Level: json.PatternLevelCritical},
    }

    // 方式二:通过配置方法
    cfg.AddDangerousPattern(json.DangerousPattern{
        Pattern: "internal_api",
        Name:    "内部 API 引用",
        Level:   json.PatternLevelWarning,
    })

    p, err := json.New(cfg)
    if err != nil {
        panic(err)
    }
    defer p.Close()

    // 测试危险模式检测
    _, err = p.Get(`{"data": "company_secret_info"}`, "data")
    if err != nil {
        fmt.Println("检测到危险模式:", err)
    }

    // 查看已注册的模式
    fmt.Printf("自定义模式数量:%d\n", len(cfg.AdditionalDangerousPatterns))
}

禁用默认模式

go
cfg := json.DefaultConfig()

// 禁用内置默认模式(关键模式除外),仅使用自定义模式
// 注意:关键模式(__proto__、constructor[、prototype.)始终强制执行
cfg.DisableDefaultPatterns = true

// 添加自定义模式
cfg.AddDangerousPattern(json.DangerousPattern{
    Pattern: "xss_payload",
    Name:    "XSS 攻击载荷",
    Level:   json.PatternLevelCritical,
})

p, err := json.New(cfg)
if err != nil {
    panic(err)
}
defer p.Close()

按级别处理模式

go
// 注册不同级别的模式
cfg := json.DefaultConfig()
cfg.AddDangerousPattern(json.DangerousPattern{
    Pattern: "suspicious_but_allowed",
    Name:    "可疑但允许",
    Level:   json.PatternLevelInfo, // 仅记录,不阻止
})

// 查看已注册的自定义模式
for _, p := range cfg.AdditionalDangerousPatterns {
    fmt.Printf("模式: %s, 名称: %s, 级别: %s\n", p.Pattern, p.Name, p.Level)
}

安全扫描策略

小 JSON(< 4KB)

始终进行完整的安全扫描,逐一检查全部危险模式。

较大 JSON(≥ 4KB)

采用多层级优化扫描,保证 100% 覆盖(无采样盲区):

  • 关键模式(__proto__constructor[prototype.)始终完全扫描
  • 先做指示字符检查:若无任何危险字符则快速跳过
  • 检测可疑字符密度:密度过高时回退全量扫描,防止攻击者把恶意内容藏在密集区
  • 其余模式使用 32KB 滚动窗口扫描(窗口带重叠),确保跨边界模式不遗漏

相关