Semgrep 使用方式与典型场景
四、使用方式与典型场景
示例一:自定义规则,抓命令拼接。下面这条规则针对 Java,找「把变量拼进 Runtime.exec」的写法,并排除常量字符串:
rules:
- id: ok-custom-runtime-exec-concat
languages: [java]
severity: ERROR
message: >-
检测到 Runtime.exec 接收拼接字符串($CMD$),
若拼接内容来自外部输入可导致命令注入。建议改为
白名单校验 + 参数数组形式调用,或改用不经过 shell 的 API。
metadata:
cwe: "CWE-78: OS Command Injection"
owasp: "A03:2021 Injection"
confidence: MEDIUM
category: security
patterns:
- pattern: Runtime.getRuntime().exec($CMD$)
- metavariable-regex:
metavariable: $CMD$
regex: .*\+.*
- pattern-not: Runtime.getRuntime().exec("...")
示例二:用污点模式降低误报。同样是命令注入,但只报「参数确实来自请求」的情况:
rules:
- id: ok-custom-taint-exec
languages: [java]
severity: ERROR
message: 用户输入经 $SINK$ 流入命令执行,构成命令注入路径
metadata:
cwe: "CWE-78"
confidence: HIGH
mode: taint
pattern-sources:
- pattern: (HttpServletRequest $REQ).getParameter(...)
- pattern: (HttpServletRequest $REQ).getHeader(...)
pattern-sinks:
- pattern: Runtime.getRuntime().exec(...)
- pattern: new ProcessBuilder(...).start()
pattern-sanitizers:
- pattern: WhitelistUtil.check(...)
- pattern: Integer.parseInt(...)
示例三:跑起来并接进流水线。
# 本地:只扫自己的改动,且只报 ERROR 及以上
semgrep scan --config ./rules --baseline-commit origin/main --severity ERROR --error .
# 规则单测
semgrep --test --config ./rules
# GitLab CI 片段
semgrep:
image: returntocorp/semgrep
script:
- semgrep scan --config ./rules --sarif -o semgrep.sarif --error .
artifacts:
reports:
sast: semgrep.sarif
when: always
适合与不适合的场景:Semgrep 适合「团队想自己写规则、且要跨多种语言」的场景,适合把安全检查塞进提交前与流水线的增量门禁,也适合快速摸底一个陌生代码库的高危写法。不太适合需要极深跨函数数据流分析(那种要建全量调用图与别名分析的场景更适合 CodeQL),也不适合把它当作唯一的安全手段——静态分析只能覆盖代码层面的模式问题,运行时逻辑缺陷、配置错误、依赖漏洞要靠别的工具。另外要注意不要把 Semgrep 当格式化/风格检查器用,风格问题交给 linter,混在一起会让安全告警被噪音淹没。

