sast-scanning
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSAST Scanning
SAST扫描
Identify security vulnerabilities in source code through static analysis.
通过静态分析识别源代码中的安全漏洞。
When to Use This Skill
适用场景
Use this skill when:
- Implementing secure SDLC practices
- Adding security gates to CI/CD
- Automating code security reviews
- Finding vulnerabilities before deployment
- Meeting compliance requirements
在以下场景中使用本技能:
- 实施安全SDLC实践
- 在CI/CD中添加安全门
- 自动化代码安全审查
- 在部署前发现漏洞
- 满足合规要求
Prerequisites
前置条件
- Source code access
- CI/CD pipeline
- SAST tool installation
- 源代码访问权限
- CI/CD流水线
- SAST工具已安装
Tool Comparison
工具对比
| Tool | License | Languages | Best For |
|---|---|---|---|
| Semgrep | OSS/Commercial | 30+ | Custom rules, speed |
| CodeQL | Free (GitHub) | 10+ | Deep analysis |
| SonarQube | OSS/Commercial | 25+ | Quality + Security |
| Bandit | OSS | Python | Python projects |
| Brakeman | OSS | Ruby | Rails apps |
| 工具 | 许可证 | 支持语言 | 适用场景 |
|---|---|---|---|
| Semgrep | 开源/商业版 | 30+种 | 自定义规则、扫描速度快 |
| CodeQL | 免费(GitHub) | 10+种 | 深度代码分析 |
| SonarQube | 开源/商业版 | 25+种 | 代码质量+安全检测 |
| Bandit | 开源 | Python | Python项目 |
| Brakeman | 开源 | Ruby | Rails应用 |
Semgrep
Semgrep
Installation
安装
bash
undefinedbash
undefinedInstall via pip
通过pip安装
pip install semgrep
pip install semgrep
Or via Homebrew
或通过Homebrew安装
brew install semgrep
undefinedbrew install semgrep
undefinedBasic Usage
基础用法
bash
undefinedbash
undefinedRun with default rules
使用默认规则扫描
semgrep --config auto .
semgrep --config auto .
Run specific rulesets
使用特定规则集扫描
semgrep --config p/security-audit .
semgrep --config p/owasp-top-ten .
semgrep --config p/ci .
semgrep --config p/security-audit .
semgrep --config p/owasp-top-ten .
semgrep --config p/ci .
Scan specific languages
扫描特定语言
semgrep --config p/python .
semgrep --config p/javascript .
semgrep --config p/python .
semgrep --config p/javascript .
Output formats
输出格式
semgrep --config auto --json -o results.json .
semgrep --config auto --sarif -o results.sarif .
undefinedsemgrep --config auto --json -o results.json .
semgrep --config auto --sarif -o results.sarif .
undefinedCustom Rules
自定义规则
yaml
undefinedyaml
undefined.semgrep/custom-rules.yaml
.semgrep/custom-rules.yaml
rules:
-
id: hardcoded-password patterns:
- pattern-either:
- pattern: password = "..."
- pattern: PASSWORD = "..."
- pattern: passwd = "..." message: Hardcoded password detected severity: ERROR languages: [python, javascript, java] metadata: cwe: "CWE-798" owasp: "A3:2017"
- pattern-either:
-
id: sql-injection patterns:
- pattern: | $QUERY = "..." + $USER_INPUT + "..." $DB.execute($QUERY) message: Potential SQL injection severity: ERROR languages: [python] metadata: cwe: "CWE-89"
-
id: insecure-random pattern: random.random() message: Use secrets module for security-sensitive randomness severity: WARNING languages: [python] fix: secrets.token_hex()
undefinedrules:
-
id: hardcoded-password patterns:
- pattern-either:
- pattern: password = "..."
- pattern: PASSWORD = "..."
- pattern: passwd = "..." message: Hardcoded password detected severity: ERROR languages: [python, javascript, java] metadata: cwe: "CWE-798" owasp: "A3:2017"
- pattern-either:
-
id: sql-injection patterns:
- pattern: | $QUERY = "..." + $USER_INPUT + "..." $DB.execute($QUERY) message: Potential SQL injection severity: ERROR languages: [python] metadata: cwe: "CWE-89"
-
id: insecure-random pattern: random.random() message: Use secrets module for security-sensitive randomness severity: WARNING languages: [python] fix: secrets.token_hex()
undefinedCI Configuration
CI配置
yaml
undefinedyaml
undefined.github/workflows/semgrep.yml
.github/workflows/semgrep.yml
name: Semgrep
on:
push:
branches: [main]
pull_request:
jobs:
semgrep:
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
run: semgrep ci
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}undefinedname: Semgrep
on:
push:
branches: [main]
pull_request:
jobs:
semgrep:
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
run: semgrep ci
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}undefinedCodeQL
CodeQL
Setup
配置
yaml
undefinedyaml
undefined.github/workflows/codeql.yml
.github/workflows/codeql.yml
name: CodeQL Analysis
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 0'
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
strategy:
matrix:
language: ['javascript', 'python']
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: +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 }}"undefinedname: CodeQL Analysis
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 0'
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
strategy:
matrix:
language: ['javascript', 'python']
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: +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 }}"undefinedCustom Queries
自定义查询
ql
// queries/sql-injection.ql
/**
* @name SQL Injection
* @description User input in SQL query
* @kind path-problem
* @problem.severity error
* @security-severity 9.0
* @precision high
* @id py/sql-injection
* @tags security
*/
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.security.dataflow.SqlInjectionQuery
from SqlInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "SQL injection from $@.", source.getNode(), "user input"ql
// queries/sql-injection.ql
/**
* @name SQL Injection
* @description User input in SQL query
* @kind path-problem
* @problem.severity error
* @security-severity 9.0
* @precision high
* @id py/sql-injection
* @tags security
*/
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.security.dataflow.SqlInjectionQuery
from SqlInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "SQL injection from $@.", source.getNode(), "user input"SonarQube
SonarQube
Docker Setup
Docker部署
yaml
undefinedyaml
undefineddocker-compose.yml
docker-compose.yml
version: '3.8'
services:
sonarqube:
image: sonarqube:lts-community
ports:
- "9000:9000"
environment:
- SONAR_JDBC_URL=jdbc:postgresql://db:5432/sonar
- SONAR_JDBC_USERNAME=sonar
- SONAR_JDBC_PASSWORD=sonar
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_logs:/opt/sonarqube/logs
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_USER=sonar
- POSTGRES_PASSWORD=sonar
- POSTGRES_DB=sonar
volumes:
- postgresql_data:/var/lib/postgresql/data
volumes:
sonarqube_data:
sonarqube_logs:
postgresql_data:
undefinedversion: '3.8'
services:
sonarqube:
image: sonarqube:lts-community
ports:
- "9000:9000"
environment:
- SONAR_JDBC_URL=jdbc:postgresql://db:5432/sonar
- SONAR_JDBC_USERNAME=sonar
- SONAR_JDBC_PASSWORD=sonar
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_logs:/opt/sonarqube/logs
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_USER=sonar
- POSTGRES_PASSWORD=sonar
- POSTGRES_DB=sonar
volumes:
- postgresql_data:/var/lib/postgresql/data
volumes:
sonarqube_data:
sonarqube_logs:
postgresql_data:
undefinedScanner Configuration
扫描器配置
properties
undefinedproperties
undefinedsonar-project.properties
sonar-project.properties
sonar.projectKey=myproject
sonar.projectName=My Project
sonar.projectVersion=1.0
sonar.sources=src
sonar.tests=tests
sonar.exclusions=/node_modules/,/vendor/
sonar.language=py
sonar.python.coverage.reportPaths=coverage.xml
sonar.qualitygate.wait=true
undefinedsonar.projectKey=myproject
sonar.projectName=My Project
sonar.projectVersion=1.0
sonar.sources=src
sonar.tests=tests
sonar.exclusions=/node_modules/,/vendor/
sonar.language=py
sonar.python.coverage.reportPaths=coverage.xml
sonar.qualitygate.wait=true
undefinedCI Integration
CI集成
yaml
undefinedyaml
undefinedGitHub Actions
GitHub Actions
-
name: SonarQube Scan uses: sonarsource/sonarqube-scan-action@master env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
-
name: Quality Gate uses: sonarsource/sonarqube-quality-gate-action@master timeout-minutes: 5 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
undefined-
name: SonarQube Scan uses: sonarsource/sonarqube-scan-action@master env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
-
name: Quality Gate uses: sonarsource/sonarqube-quality-gate-action@master timeout-minutes: 5 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
undefinedLanguage-Specific Tools
语言专属工具
Python (Bandit)
Python(Bandit)
bash
undefinedbash
undefinedInstall
安装
pip install bandit
pip install bandit
Run scan
执行扫描
bandit -r src/ -f json -o bandit-report.json
bandit -r src/ -f json -o bandit-report.json
With configuration
使用配置文件
bandit -r src/ -c bandit.yaml
```yamlbandit -r src/ -c bandit.yaml
```yamlbandit.yaml
bandit.yaml
skips: ['B101', 'B601']
exclude_dirs: ['tests', 'venv']
assert_used:
skips: ['_test.py', '_tests.py']
undefinedskips: ['B101', 'B601']
exclude_dirs: ['tests', 'venv']
assert_used:
skips: ['_test.py', '_tests.py']
undefinedJavaScript (ESLint Security)
JavaScript(ESLint Security)
bash
undefinedbash
undefinedInstall
安装
npm install eslint eslint-plugin-security --save-dev
```javascript
// .eslintrc.js
module.exports = {
plugins: ['security'],
extends: ['plugin:security/recommended'],
rules: {
'security/detect-object-injection': 'error',
'security/detect-non-literal-regexp': 'warn',
'security/detect-unsafe-regex': 'error',
'security/detect-buffer-noassert': 'error',
'security/detect-eval-with-expression': 'error',
'security/detect-no-csrf-before-method-override': 'error',
'security/detect-possible-timing-attacks': 'warn'
}
};npm install eslint eslint-plugin-security --save-dev
```javascript
// .eslintrc.js
module.exports = {
plugins: ['security'],
extends: ['plugin:security/recommended'],
rules: {
'security/detect-object-injection': 'error',
'security/detect-non-literal-regexp': 'warn',
'security/detect-unsafe-regex': 'error',
'security/detect-buffer-noassert': 'error',
'security/detect-eval-with-expression': 'error',
'security/detect-no-csrf-before-method-override': 'error',
'security/detect-possible-timing-attacks': 'warn'
}
};Ruby (Brakeman)
Ruby(Brakeman)
bash
undefinedbash
undefinedInstall
安装
gem install brakeman
gem install brakeman
Run scan
执行扫描
brakeman -o brakeman-report.json -f json
brakeman -o brakeman-report.json -f json
CI configuration
CI配置
brakeman --no-exit-on-warn --no-exit-on-error -o report.html
undefinedbrakeman --no-exit-on-warn --no-exit-on-error -o report.html
undefinedQuality Gates
安全质量门
SonarQube Quality Gate
SonarQube安全质量门
json
{
"name": "Security Gate",
"conditions": [
{
"metric": "new_security_rating",
"op": "GT",
"error": "1"
},
{
"metric": "new_vulnerabilities",
"op": "GT",
"error": "0"
},
{
"metric": "new_security_hotspots_reviewed",
"op": "LT",
"error": "100"
}
]
}json
{
"name": "Security Gate",
"conditions": [
{
"metric": "new_security_rating",
"op": "GT",
"error": "1"
},
{
"metric": "new_vulnerabilities",
"op": "GT",
"error": "0"
},
{
"metric": "new_security_hotspots_reviewed",
"op": "LT",
"error": "100"
}
]
}Custom Gate Script
自定义安全门脚本
bash
#!/bin/bashbash
#!/bin/bashsecurity-gate.sh
security-gate.sh
CRITICAL=$(cat results.json | jq '[.results[] | select(.severity == "critical")] | length')
HIGH=$(cat results.json | jq '[.results[] | select(.severity == "high")] | length')
echo "Critical: $CRITICAL, High: $HIGH"
if [ "$CRITICAL" -gt 0 ]; then
echo "FAILED: Critical vulnerabilities found"
exit 1
fi
if [ "$HIGH" -gt 5 ]; then
echo "FAILED: Too many high severity vulnerabilities"
exit 1
fi
echo "PASSED: Security gate"
exit 0
undefinedCRITICAL=$(cat results.json | jq '[.results[] | select(.severity == "critical")] | length')
HIGH=$(cat results.json | jq '[.results[] | select(.severity == "high")] | length')
echo "Critical: $CRITICAL, High: $HIGH"
if [ "$CRITICAL" -gt 0 ]; then
echo "FAILED: Critical vulnerabilities found"
exit 1
fi
if [ "$HIGH" -gt 5 ]; then
echo "FAILED: Too many high severity vulnerabilities"
exit 1
fi
echo "PASSED: Security gate"
exit 0
undefinedCommon Issues
常见问题
Issue: Too Many False Positives
问题:误报过多
Problem: Alerts on safe code patterns
Solution: Tune rules, add suppressions, use baseline
现象: 对安全代码模式发出警报
解决方案: 调整规则、添加抑制规则、使用基线扫描
Issue: Slow Scans
问题:扫描速度慢
Problem: SAST taking too long in CI
Solution: Incremental scanning, parallel execution, exclude test files
现象: CI中SAST扫描耗时过长
解决方案: 增量扫描、并行执行、排除测试文件
Issue: Missing Coverage
问题:覆盖不全
Problem: Vulnerabilities not detected
Solution: Add custom rules, combine multiple tools
现象: 漏洞未被检测到
解决方案: 添加自定义规则、组合多种工具
Best Practices
最佳实践
- Run on every PR/commit
- Establish baseline for existing code
- Prioritize by severity and exploitability
- Maintain custom rules for your codebase
- Integrate with IDE for early feedback
- Track trends over time
- Document false positive suppressions
- Combine with DAST for comprehensive coverage
- 对每个PR/提交执行扫描
- 为现有代码建立安全基线
- 按漏洞严重程度和可利用性排序优先级
- 针对代码库维护自定义规则
- 与IDE集成实现早期反馈
- 跟踪安全趋势变化
- 记录误报抑制规则
- 结合DAST实现全面安全覆盖
Related Skills
相关技能
- dast-scanning - Dynamic testing
- dependency-scanning - Dependency vulnerabilities
- github-actions - CI integration
- dast-scanning - 动态测试
- dependency-scanning - 依赖漏洞检测
- github-actions - CI集成