Go Injection Vulnerability Patterns (CWE-78/89/77/94/88)
当审计 Go 代码中涉及命令执行、SQL 查询、模板渲染、外部进程调用时加载此 Skill。
Detection Strategy
Sources(攻击入口):
- HTTP 请求参数(query params, form values, JSON body)
- gRPC 请求字段
- Git 仓库内容(commit message, branch name, file content)
- MCP tool 输入参数
- 用户提交的配置值(Helm values, Kustomize patches)
- AI/LLM 生成的 SQL 查询
Sinks(危险操作):
exec.Command("sh", "-c", userInput)-- OS 命令注入exec.Command("bash", "-c", userInput)-- 同上exec.Command(binary, "--flag=" + userInput)-- 参数注入 (CWE-88)exec.CommandContext(ctx, "git", "--upload-pack=evil", ...)-- Git argument injectiondb.Query("SELECT * FROM t WHERE id=" + userInput)-- SQL 注入db.Exec(fmt.Sprintf("INSERT INTO t VALUES ('%s')", userInput))-- SQL 注入template.New("").Parse(userInput)(text/template) -- 模板注入template.HTML(userInput)-- XSS(绕过html/template自动转义)
Sanitization(安全屏障):
exec.Command(binary, arg1, arg2)-- 不经过 shell,每个参数独立传递db.Query(sql, args...)/db.Exec(sql, args...)-- 参数化查询html/template(非text/template)-- 自动 HTML 转义shellescape/shlex包 -- shell 参数转义- 输入白名单验证(正则匹配允许的字符)
检测路径:
# OS 命令执行
grep -rn "exec.Command\|exec.CommandContext\|os.StartProcess" --include="*.go"
# Shell 调用
grep -rn '"sh".*"-c"\|"bash".*"-c"\|"cmd".*"/c"' --include="*.go"
# SQL 拼接
grep -rn 'fmt.Sprintf.*SELECT\|fmt.Sprintf.*INSERT\|fmt.Sprintf.*UPDATE\|fmt.Sprintf.*DELETE' --include="*.go"
grep -rn 'Sprintf.*WHERE\|"+.*WHERE\|`.*%s.*FROM' --include="*.go"
# 模板注入
grep -rn "text/template\|template.New\|template.Must" --include="*.go"
# 参数化查询(安全模式)
grep -rn "db.Query.*,\|db.Exec.*,\|db.QueryRow.*," --include="*.go"
# Argument injection — Git
grep -rn '"git".*"--upload-pack\|"git".*"--exec-path\|"git".*"--config"' --include="*.go"
- 定位命令执行/SQL 查询/模板渲染的 Sink 函数
- 回溯参数来源,确认是否包含用户输入
- 验证是否有安全屏障:
exec.Command是否通过 shell(sh -c)执行?直接传参不经过 shell 通常安全- SQL 是否使用参数化查询(
?占位符)?fmt.Sprintf拼接 SQL 是危险信号 - 模板是否使用
html/template(安全)而非text/template(不安全)? - Git 命令是否允许用户控制
--upload-pack、--config等可执行的参数?
- 若无安全屏障或屏障可被绕过 -> 标记为候选漏洞
Detection Checklist
-
exec.CommandShell 调用审计 (CWE-78):是否使用exec.Command("sh", "-c", input)或exec.Command("bash", "-c", input)执行用户输入?Go 中exec.Command默认不经过 shell,但显式调用 shell 时存在注入风险。 - Git Argument Injection 审计 (CWE-88):
exec.Command("git", userArgs...)是否允许用户注入--upload-pack、--exec-path、--config=core.sshCommand=evil等可执行参数?Gogs 的 SSH argument injection 是经典案例。 - SQL 字符串拼接审计 (CWE-89):是否使用
fmt.Sprintf或字符串连接构造 SQL?应使用db.Query(sql, args...)的参数化形式。特别注意ORDER BY、LIMIT等不能用参数化的子句。 - AI/LLM 生成 SQL 审计 (CWE-89):AI 数据库查询工具(如 WeKnora)生成的 SQL 是否经过安全过滤?LLM 输出不可信,必须有 SQL 白名单或 AST 解析验证。
-
text/template用于 HTML 审计 (CWE-94):是否误用text/template生成 HTML 输出?应使用html/template以获得自动转义。检查 import 路径。 - Helm/Kustomize 模板注入审计 (CWE-94):用户提交的 Helm values 是否被直接注入模板?
{{语法是否能执行任意 Go 模板函数?Flux helm-controller 曾因此导致 RCE。 - MCP Stdio 命令注入审计 (CWE-78):MCP server 的 stdio transport 配置中的
command字段是否经过验证?WeKnora 的 MCP stdio test 功能曾允许注入任意命令。 -
os.StartProcess参数审计 (CWE-78):低层级的os.StartProcess调用是否正确隔离了参数?参数数组中是否有用户控制的元素?
False Positive Exclusion Guide
以下模式不是此类漏洞:
exec.Command("git", "--version")-- 无用户输入的硬编码命令exec.Command(binary, fixedArgs...)-- 参数完全硬编码,无用户输入db.Query("SELECT * FROM t WHERE id = ?", userID)-- 参数化查询是安全的html/template渲染用户输入 -- 自动转义会处理 XSS(除非使用template.HTML()类型转换)fmt.Sprintf用于日志而非 SQL -- 拼接字符串用于 log 而非数据库查询
以下模式需要深入检查:
exec.Command("git", userProvidedRepoURL)-- URL 中可能包含--upload-pack参数db.Exec("CREATE TABLE " + tableName)-- DDL 语句中标识符不能用?参数化text/template用于非 HTML 输出 -- 如生成 YAML/JSON,可能导致结构注入strings.Replace(input, "'", "''", -1)-- 手工 SQL 转义极易遗漏边缘情况
Real-World Cases
详见 references/cases.md(7 个真实案例,需要时加载)。
Source: yhy0/ghsa-skill-builder — distributed by TomeVault.