Integrates CodeQL and Semgrep SAST tools into GitHub Actions for automatic code scanning on PRs/pushes, SARIF upload to GitHub Advanced Security, rule tuning, and quality gates blocking merges on high-severity vulnerabilities.
npx claudepluginhub killvxk/cybersecurity-skills-zhThis skill uses the workspace's default tool permissions.
- 开发团队需要在每个 pull request 上进行自动代码级漏洞检测时
Integrates CodeQL and Semgrep SAST tools into GitHub Actions pipelines for automated code scanning on pull requests and pushes, SARIF upload to GitHub Advanced Security, and quality gates blocking high-severity vulnerabilities.
Integrates CodeQL and Semgrep SAST into GitHub Actions for automated code scanning on PRs/pushes, SARIF upload to GitHub Advanced Security, rule tuning, and merge-blocking quality gates.
Guides setup, configuration, and custom rule creation for SAST tools like Semgrep, SonarQube, and CodeQL to scan codebases across languages in CI/CD pipelines.
Share bugs, ideas, or general feedback.
不适用于运行时漏洞检测(使用 DAST)、扫描第三方依赖项(使用 Snyk 等 SCA 工具)或基础设施即代码扫描(使用 Checkov 或 tfsec)。
创建在 pull request 和每周计划中运行的 CodeQL 工作流,以捕获现有代码中的漏洞。
# .github/workflows/codeql-analysis.yml
name: "CodeQL Analysis"
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: '30 2 * * 1' # 每周一 2:30
jobs:
analyze:
name: Analyze (${{ matrix.language }})
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: ['javascript', 'python']
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-extended,security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{ matrix.language }}"
Semgrep 以更快的扫描速度和对自定义模式规则的支持来补充 CodeQL。配置它将 SARIF 结果上传到相同的 GitHub 安全标签。
# .github/workflows/semgrep.yml
name: "Semgrep SAST Scan"
on:
pull_request:
branches: [main, develop]
push:
branches: [main]
jobs:
semgrep:
name: Semgrep Scan
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
container:
image: semgrep/semgrep:latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run Semgrep
run: |
semgrep ci \
--config auto \
--config p/owasp-top-ten \
--config p/cwe-top-25 \
--sarif --output semgrep-results.sarif \
--severity ERROR \
--error
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: semgrep-results.sarif
category: semgrep
编写特定于组织的规则,以捕获代码库中独特的模式,例如已弃用的内部 API 或不安全的配置模式。
# .semgrep/custom-rules.yml
rules:
- id: hardcoded-database-url
patterns:
- pattern: |
$DB_URL = "...$PROTO://...:...$PASS@..."
message: |
Hardcoded database connection string with credentials detected.
Use environment variables or a secrets manager instead.
languages: [python, javascript, typescript]
severity: ERROR
metadata:
cwe: "CWE-798: Use of Hard-coded Credentials"
owasp: "A07:2021 - Identification and Authentication Failures"
- id: unsafe-deserialization
patterns:
- pattern-either:
- pattern: pickle.loads(...)
- pattern: yaml.load(..., Loader=yaml.Loader)
- pattern: yaml.load(..., Loader=yaml.FullLoader)
message: |
Unsafe deserialization detected. Use safe alternatives to prevent
remote code execution vulnerabilities.
languages: [python]
severity: ERROR
metadata:
cwe: "CWE-502: Deserialization of Untrusted Data"
- id: missing-csrf-protection
patterns:
- pattern: |
@app.route("...", methods=["POST"])
def $FUNC(...):
...
- pattern-not-inside: |
@csrf.exempt
...
message: "POST endpoint may lack CSRF protection."
languages: [python]
severity: WARNING
配置分支保护规则,要求 SAST 检查在合并前通过,防止易受攻击的代码进入生产分支。
# 使用 GitHub CLI 设置分支保护,要求 SAST 检查
gh api repos/{owner}/{repo}/branches/main/protection \
--method PUT \
--field required_status_checks='{"strict":true,"contexts":["Analyze (javascript)","Analyze (python)","Semgrep Scan"]}' \
--field enforce_admins=true \
--field required_pull_request_reviews='{"required_approving_review_count":1}'
通过 CodeQL 查询过滤器和 Semgrep nosemgrep 注解管理误报,以维护开发者对扫描结果的信任。
# codeql-config.yml - 自定义 CodeQL 配置
name: "Custom CodeQL Config"
queries:
- uses: security-extended
- uses: security-and-quality
- excludes:
id: js/unused-local-variable
paths-ignore:
- '**/test/**'
- '**/tests/**'
- '**/vendor/**'
- '**/node_modules/**'
- '**/*.test.js'
- '**/*.spec.py'
# 示例:在 Semgrep 中抑制已知误报
import subprocess
def run_safe_command(cmd_list):
# nosemgrep: python.lang.security.audit.dangerous-subprocess-use
result = subprocess.run(cmd_list, capture_output=True, text=True, shell=False)
return result.stdout
使用 GitHub 安全概览仪表板,并为跨仓库的安全告警配置通知。
# 通过 GitHub API 查询 SARIF 结果用于报告
gh api repos/{owner}/{repo}/code-scanning/alerts \
--jq '.[] | select(.state=="open") | {rule: .rule.id, severity: .rule.security_severity_level, file: .most_recent_instance.location.path, line: .most_recent_instance.location.start_line}'
# 按严重性统计未处理告警
gh api repos/{owner}/{repo}/code-scanning/alerts \
--jq '[.[] | select(.state=="open")] | group_by(.rule.security_severity_level) | map({severity: .[0].rule.security_severity_level, count: length})'
| 术语 | 定义 |
|---|---|
| SAST | 静态应用安全测试 — 在不执行代码的情况下分析源代码以查找安全漏洞 |
| SARIF | 静态分析结果交换格式 — 用于表达静态分析工具结果的标准化 JSON 格式 |
| CodeQL | GitHub 的语义代码分析引擎,将代码视为数据并查询漏洞模式 |
| Semgrep | 使用模式匹配跨多种语言查找漏洞和安全问题的轻量级静态分析工具 |
| Security Extended | 包含除默认集之外额外安全查询的 CodeQL 查询套件,用于更深入分析 |
| 质量门禁 | 自动检查点,除非满足安全标准,否则阻止代码通过管道 |
| 误报 | 错误地将安全代码识别为易受攻击的扫描发现,需要抑制或调整 |
背景:平台团队管理包含 Python 微服务、TypeScript 前端和 Go 基础设施工具的 monorepo。安全审查每季度手动进行一次,遗漏了审查间隔的漏洞。
方法:
--config auto 的 Semgrep 以自动检测语言并应用相关规则集注意事项:将 CodeQL 设置为在每个 PR 上分析所有语言会显著增加 CI 时间。使用路径过滤器仅触发相关语言扫描。Semgrep 的 --config auto 可能启用与 CodeQL 发现冲突的规则,创建重复告警。
背景:启用 SAST 后,开发者忽略发现,因为 40% 是误报,破坏了安全程序。
方法:
.semgrepignore 模式注意事项:过度抑制规则以减少噪音可能造成盲点。始终根据 OWASP Top 10 和 CWE Top 25 验证抑制,确保关键漏洞类别仍被覆盖。
SAST 管道扫描报告
==========================
仓库:org/web-application
分支:feature/user-auth-refactor
扫描日期:2026-02-23
提交:a1b2c3d4
CodeQL 结果:
语言 运行查询数 发现数 严重 高危 中危
javascript 312 4 1 2 1
python 287 2 0 1 1
Semgrep 结果:
规则集 匹配规则数 发现数 错误 警告
auto 1,847 3 1 2
owasp-top-ten 186 2 1 1
custom-rules 12 1 0 1
质量门禁:失败
阻塞发现:2 个严重/高危问题
- [严重] CWE-89:src/api/users.py:47 中的 SQL 注入
- [高危] CWE-79:src/components/Search.tsx:123 中的跨站脚本
必需操作:允许合并之前修复阻塞发现。