关于 implementing-semgrep-for-custom-sast-rules
面向应用安全和开发团队的 Semgrep 自定义 SAST 规则实施指南,涵盖 YAML 规则编写、测试和 CI/CD 集成,适用于多种编程语言。
主要功能
- 01编写 YAML 自定义规则
- 02使用模式与污点分析
- 03测试规则及修复建议
- 04集成 GitHub Actions 和 GitLab CI
适用场景
- 01检测组织特定的安全问题
- 02在 CI 中阻止高严重性发现
- 03执行编码规范检查
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill implementing-semgrep-for-custom-sast-rules安装后在 Claude Code 中输入/implementing-semgrep-for-custom-sast-rules确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdstandards.mdscripts/agent.py详细介绍
为自定义 SAST 规则实现 Semgrep
概述
Semgrep 是一款开源静态分析工具,使用模式匹配来发现缺陷、执行代码规范并检测安全漏洞。自定义规则使用 YAML 编写,采用 Semgrep 的模式语法,因此无需编译器知识即可上手。它支持 30 多种语言,包括 Python、JavaScript、Go、Java 和 C。
何时使用
- 在环境中部署或配置为自定义 SAST 规则实现 Semgrep 的能力时
- 在建立符合合规要求的安全控制措施时
- 在为该领域构建或改进安全架构时
- 在开展需要此实现的安全评估时
先决条件
- Python 3.8+ 或 Docker
- 已安装 Semgrep CLI
- 使用受支持语言的目标代码库
安装
# Install via pip
pip install semgrep
# Install via Homebrew
brew install semgrep
# Run via Docker
docker run -v "${PWD}:/src" returntocorp/semgrep semgrep --config auto /src
# Verify
semgrep --version
运行 Semgrep
# Auto-detect rules for your code
semgrep --config auto .
# Use Semgrep registry rules
semgrep --config r/python.lang.security
# Use custom rule file
semgrep --config my-rules.yaml .
# Use multiple configs
semgrep --config auto --config ./custom-rules/ .
# JSON output
semgrep --config auto --json . > results.json
# SARIF output for GitHub
semgrep --config auto --sarif . > results.sarif
# Filter by severity
semgrep --config auto --severity ERROR .
编写自定义规则
基本模式匹配
# rules/sql-injection.yaml
rules:
- id: sql-injection-string-format
languages: [python]
severity: ERROR
message: |
Potential SQL injection via string formatting.
Use parameterized queries instead.
pattern: |
cursor.execute(f"..." % ...)
metadata:
cwe: ["CWE-89"]
owasp: ["A03:2021"]
category: security
fix: |
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
模式运算符
rules:
- id: hardcoded-secret-in-code
languages: [python, javascript, typescript]
severity: ERROR
message: Hardcoded secret detected in source code
patterns:
- pattern-either:
- pattern: $VAR = "..."
- pattern: $VAR = '...'
- metavariable-regex:
metavariable: $VAR
regex: (?i)(password|secret|api_key|token|aws_secret)
- pattern-not: $VAR = ""
- pattern-not: $VAR = "changeme"
- pattern-not: $VAR = "PLACEHOLDER"
metadata:
cwe: ["CWE-798"]
category: security
污点分析
rules:
- id: xss-taint-tracking
languages: [python]
severity: ERROR
message: User input flows to HTML response without sanitization
mode: taint
pattern-sources:
- pattern: request.args.get(...)
- pattern: request.form.get(...)
- pattern: request.form[...]
pattern-sinks:
- pattern: return render_template_string(...)
- pattern: Markup(...)
pattern-sanitizers:
- pattern: bleach.clean(...)
- pattern: escape(...)
metadata:
cwe: ["CWE-79"]
owasp: ["A03:2021"]
多语言规则
rules:
- id: insecure-random
languages: [python, javascript, go, java]
severity: WARNING
message: |
Using insecure random number generator. Use cryptographically
secure alternatives for security-sensitive operations.
pattern-either:
# Python
- pattern: random.random()
- pattern: random.randint(...)
# JavaScript
- pattern: Math.random()
# Go
- pattern: math/rand.Intn(...)
# Java
- pattern: new java.util.Random()
metadata:
cwe: ["CWE-330"]
执行代码规范
rules:
- id: require-error-handling
languages: [go]
severity: WARNING
message: Error return value not checked
pattern: |
$VAR, _ := $FUNC(...)
fix: |
$VAR, err := $FUNC(...)
if err != nil {
return fmt.Errorf("$FUNC failed: %w", err)
}
- id: no-console-log-in-production
languages: [javascript, typescript]
severity: WARNING
message: Remove console.log before merging to production
pattern: console.log(...)
paths:
exclude:
- "tests/*"
- "*.test.*"
JWT 安全规则
rules:
- id: jwt-none-algorithm
languages: [python]
severity: ERROR
message: JWT decoded without algorithm verification - allows token forgery
patterns:
- pattern: jwt.decode($TOKEN, ..., algorithms=["none"], ...)
metadata:
cwe: ["CWE-347"]
- id: jwt-no-verification
languages: [python]
severity: ERROR
message: JWT decoded with verification disabled
patterns:
- pattern: jwt.decode($TOKEN, ..., options={"verify_signature": False}, ...)
metadata:
cwe: ["CWE-345"]
规则测试
# rules/test-sql-injection.yaml
rules:
- id: sql-injection-format-string
languages: [python]
severity: ERROR
message: SQL injection via format string
pattern: |
cursor.execute(f"...{$VAR}...")
# Test annotation in test file:
# test-sql-injection.py
def bad_query(user_id):
# ruleid: sql-injection-format-string
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
def good_query(user_id):
# ok: sql-injection-format-string
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
# Run rule tests
semgrep --test rules/
# Test specific rule
semgrep --config rules/sql-injection.yaml --test
CI/CD 集成
GitHub Actions
name: Semgrep SAST
on: [pull_request]
jobs:
semgrep:
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
run: |
semgrep --config auto \
--config ./custom-rules/ \
--sarif --output results.sarif \
--severity ERROR \
.
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
GitLab CI
semgrep:
stage: test
image: returntocorp/semgrep
script:
- semgrep --config auto --config ./custom-rules/ --json --output semgrep.json .
artifacts:
reports:
sast: semgrep.json
配置文件
# .semgrep.yaml
rules:
- id: my-org-rules
# ... rules here
# .semgrepignore
tests/
node_modules/
vendor/
*.min.js
最佳实践
- 从自动配置开始,然后为组织特定模式添加自定义规则
- 测试规则,使用
# ruleid:和# ok:注解 - 对数据流漏洞(XSS、SQLi、SSRF)使用污点模式
- 包含元数据(CWE、OWASP)以便对漏洞进行分类
- 尽可能使用
fix键提供修复建议 - 排除测试文件以减少误报
- 在共享仓库中对规则进行版本控制
- 在 CI 中将 ERROR 严重级别发现作为阻塞检查运行
评论
支持 Markdown