关于 security-scanning-security-sast
面向代码安全审查的 SAST 技能,覆盖多种语言、框架和常见漏洞模式,并提供扫描器选择与规则配置指导。适合在本地或 CI 中检查代码、分诊发现并提出修复建议。
主要功能
- 01覆盖多种编程语言
- 02集成多种静态分析工具
- 03检测常见代码漏洞
- 04提供框架安全检查指导
- 05编写 Semgrep 自定义规则
- 06指导 CI 扫描与结果分诊
适用场景
- 01审查代码中的安全问题
- 02部署前检查注入与机密泄露
- 03为组织策略编写自定义规则
- 04评估遗留代码并安排修复
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ rmyndharis/ antigravity-skills --skill security-scanning-security-sast安装后在 Claude Code 中输入/security-scanning-security-sast确认已加载。
详细介绍
SAST 安全插件
静态应用安全测试(SAST),可跨多种语言、框架和安全模式全面检测代码漏洞。
功能
- 多语言 SAST:Python、JavaScript/TypeScript、Java、Ruby、PHP、Go、Rust
- 工具集成:Bandit、Semgrep、ESLint Security、SonarQube、CodeQL、PMD、SpotBugs、Brakeman、gosec、cargo-clippy
- 漏洞模式:SQL 注入、XSS、硬编码密钥、路径遍历、IDOR、CSRF、不安全反序列化
- 框架分析:Django、Flask、React、Express、Spring Boot、Rails、Laravel
- 自定义规则编写:开发 Semgrep 模式,制定组织专属的安全策略
适用场景
适用于代码审查安全分析、注入漏洞、硬编码密钥、框架专属模式、自定义安全策略强制执行、部署前验证、遗留代码评估和合规性检查(OWASP、PCI-DSS、SOC2)。
专用工具:使用 security-secrets.md 进行高级凭据扫描,使用 security-owasp.md 进行 Top 10 映射,使用 security-api.md 检查 REST/GraphQL 端点。
不适用场景
- 仅需运行时测试或渗透测试
- 无法访问源代码或构建输出
- 环境禁止使用第三方扫描工具
说明
- 确定要扫描的语言、框架和范围。
- 选择 SAST 工具,并为代码库配置规则。
- 使用可复现的设置,在 CI 或本地运行扫描。
- 分类处理发现的问题,按严重程度排序,并提出修复方案。
安全
- 未经批准,不要将专有代码上传到外部服务。
- 启用自动修复或阻止发布前,必须经过审查。
SAST 工具选择
Python:Bandit
# Installation & scan
pip install bandit
bandit -r . -f json -o bandit-report.json
bandit -r . -ll -ii -f json # High/Critical only
配置:.bandit
exclude_dirs: ['/tests/', '/venv/', '/.tox/', '/build/']
tests: [B201, B301, B302, B303, B304, B305, B307, B308, B312, B323, B324, B501, B502, B506, B602, B608]
skips: [B101]
JavaScript/TypeScript:ESLint Security
npm install --save-dev eslint @eslint/plugin-security eslint-plugin-no-secrets
eslint . --ext .js,.jsx,.ts,.tsx --format json > eslint-security.json
配置:.eslintrc-security.json
{
"plugins": ["@eslint/plugin-security", "eslint-plugin-no-secrets"],
"extends": ["plugin:security/recommended"],
"rules": {
"security/detect-object-injection": "error",
"security/detect-non-literal-fs-filename": "error",
"security/detect-eval-with-expression": "error",
"security/detect-pseudo-random-prng": "error",
"no-secrets/no-secrets": "error"
}
}
多语言:Semgrep
pip install semgrep
semgrep --config=auto --json --output=semgrep-report.json
semgrep --config=p/security-audit --json
semgrep --config=p/owasp-top-ten --json
semgrep ci --config=auto # CI mode
自定义规则:.semgrep.yml
rules:
- id: sql-injection-format-string
pattern: cursor.execute("... %s ..." % $VAR)
message: SQL injection via string formatting
severity: ERROR
languages: [python]
metadata:
cwe: "CWE-89"
owasp: "A03:2021-Injection"
- id: dangerous-innerHTML
pattern: $ELEM.innerHTML = $VAR
message: XSS via innerHTML assignment
severity: ERROR
languages: [javascript, typescript]
metadata:
cwe: "CWE-79"
- id: hardcoded-aws-credentials
patterns:
- pattern: $KEY = "AKIA..."
- metavariable-regex:
metavariable: $KEY
regex: "(aws_access_key_id|AWS_ACCESS_KEY_ID)"
message: Hardcoded AWS credentials detected
severity: ERROR
languages: [python, javascript, java]
- id: path-traversal-open
patterns:
- pattern: open($PATH, ...)
- pattern-not: open(os.path.join(SAFE_DIR, ...), ...)
- metavariable-pattern:
metavariable: $PATH
patterns:
- pattern: $REQ.get(...)
message: Path traversal via user input
severity: ERROR
languages: [python]
- id: command-injection
patterns:
- pattern-either:
- pattern: os.system($CMD)
- pattern: subprocess.call($CMD, shell=True)
- metavariable-pattern:
metavariable: $CMD
patterns:
- pattern-either:
- pattern: $X + $Y
- pattern: f"...{$VAR}..."
message: Command injection via shell=True
severity: ERROR
languages: [python]
其他语言工具
Java:mvn spotbugs:check
Ruby:brakeman -o report.json -f json
Go:gosec -fmt=json -out=gosec.json ./...
Rust:cargo clippy -- -W clippy::unwrap_used
漏洞模式
SQL 注入
有风险:在 SQL 查询中使用字符串格式化或拼接处理用户输入
安全:
# Parameterized queries
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
User.objects.filter(id=user_id) # ORM
跨站脚本攻击(XSS)
有风险:直接使用未经净化的用户输入操作 HTML(innerHTML、outerHTML、document.write)
安全:
// Use textContent for plain text
element.textContent = userInput;
// React auto-escapes
<div>{userInput}</div>
// Sanitize when HTML required
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);
硬编码密钥
有风险:在源代码中硬编码 API 密钥、密码或令牌
安全:
import os
API_KEY = os.environ.get('API_KEY')
PASSWORD = os.getenv('DB_PASSWORD')
路径遍历
有风险:使用未经净化的用户输入打开文件
安全:
import os
ALLOWED_DIR = '/var/www/uploads'
file_name = request.args.get('file')
file_path = os.path.join(ALLOWED_DIR, file_name)
file_path = os.path.realpath(file_path)
if not file_path.startswith(os.path.realpath(ALLOWED_DIR)):
raise ValueError("Invalid file path")
with open(file_path, 'r') as f:
content = f.read()
不安全反序列化
有风险:使用不可信数据调用 pickle.loads()、yaml.load()
安全:
import json
data = json.loads(user_input) # SECURE
import yaml
config = yaml.safe_load(user_input) # SECURE
命令注入
有风险:使用 shell=True 和用户输入调用 os.system() 或 subprocess
安全:
subprocess.run(['ping', '-c', '4', user_input]) # Array args
import shlex
safe_input = shlex.quote(user_input) # Input validation
不安全随机数
有风险:在安全关键操作中使用 random 模块
安全:
import secrets
token = secrets.token_hex(16)
session_id = secrets.token_urlsafe(32)
框架安全
Django
有风险:@csrf_exempt、DEBUG=True、弱 SECRET_KEY、缺少安全中间件
安全:
# settings.py
DEBUG = False
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
X_FRAME_OPTIONS = 'DENY'
Flask
有风险:debug=True、弱 secret_key、CORS 通配符
安全:
import os
from flask_talisman import Talisman
app.secret_key = os.environ.get('FLASK_SECRET_KEY')
Talisman(app, force_https=True)
CORS(app, origins=['https://example.com'])
Express.js
有风险:缺少 helmet、CORS 通配符、没有速率限制
安全:
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
app.use(helmet());
app.use(cors({ origin: 'https://example.com' }));
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
多语言扫描器实现
import json
import subprocess
from pathlib import Path
from typing import Dict, List, Any
from dataclasses import dataclass
from datetime import datetime
@dataclass
class SASTFinding:
tool: str
severity: str
category: str
title: str
description: str
file_path: str
line_number: int
cwe: str
owasp: str
confidence: str
class MultiLanguageSASTScanner:
def __init__(self, project_path: str):
self.project_path = Path(project_path)
self.findings: List[SASTFinding] = []
def detect_languages(self) -> List[str]:
"""Auto-detect languages"""
languages = []
indicators = {
'python': ['*.py', 'requirements.txt'],
'javascript': ['*.js', 'package.json'],
'typescript': ['*.ts', 'tsconfig.json'],
'java': ['*.java', 'pom.xml'],
'ruby': ['*.rb', 'Gemfile'],
'go': ['*.go', 'go.mod'],
'rust': ['*.rs', 'Cargo.toml'],
}
for lang, patterns in indicators.items():
for pattern in patterns:
if list(self.project_path.glob(f'**/{pattern}')):
languages.append(lang)
break
return languages
def run_comprehensive_sast(self) -> Dict[str, Any]:
"""Execute all applicable SAST tools"""
languages = self.detect_languages()
scan_results = {
'timestamp': datetime.now().isoformat(),
'languages': languages,
'tools_executed': [],
'findings': []
}
self.run_semgrep_scan()
scan_results['tools_executed'].append('semgrep')
if 'python' in languages:
self.run_bandit_scan()
scan_results['tools_executed'].append('bandit')
if 'javascript' in languages or 'typescript' in languages:
self.run_eslint_security_scan()
scan_results['tools_executed'].append('eslint-security')
scan_results['findings'] = [vars(f) for f in self.findings]
scan_results['summary'] = self.generate_summary()
return scan_results
def run_semgrep_scan(self):
"""Run Semgrep"""
for ruleset in ['auto', 'p/security-audit', 'p/owasp-top-ten']:
try:
result = subprocess.run([
'semgrep', '--config', ruleset, '--json', '--quiet',
str(self.project_path)
], capture_output=True, text=True, timeout=300)
if result.stdout:
data = json.loads(result.stdout)
for f in data.get('results', []):
self.findings.append(SASTFinding(
tool='semgrep',
severity=f.get('extra', {}).get('severity', 'MEDIUM').upper(),
category='sast',
title=f.get('check_id', ''),
description=f.get('extra', {}).get('message', ''),
file_path=f.get('path', ''),
line_number=f.get('start', {}).get('line', 0),
cwe=f.get('extra', {}).get('metadata', {}).get('cwe', ''),
owasp=f.get('extra', {}).get('metadata', {}).get('owasp', ''),
confidence=f.get('extra', {}).get('metadata', {}).get('confidence', 'MEDIUM')
))
except Exception as e:
print(f"Semgrep {ruleset} failed: {e}")
def generate_summary(self) -> Dict[str, Any]:
"""Generate statistics"""
severity_counts = {'CRITICAL': 0, 'HIGH': 0, 'MEDIUM': 0, 'LOW': 0}
for f in self.findings:
severity_counts[f.severity] = severity_counts.get(f.severity, 0) + 1
return {
'total_findings': len(self.findings),
'severity_breakdown': severity_counts,
'risk_score': self.calculate_risk_score(severity_counts)
}
def calculate_risk_score(self, severity_counts: Dict[str, int]) -> int:
"""Risk score 0-100"""
weights = {'CRITICAL': 10, 'HIGH': 7, 'MEDIUM': 4, 'LOW': 1}
total = sum(weights[s] * c for s, c in severity_counts.items())
return min(100, int((total / 50) * 100))
CI/CD 集成
GitHub Actions
name: SAST Scan
on:
pull_request:
branches: [main]
jobs:
sast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install tools
run: |
pip install bandit semgrep
npm install -g eslint @eslint/plugin-security
- name: Run scans
run: |
bandit -r . -f json -o bandit.json || true
semgrep --config=auto --json --output=semgrep.json || true
- name: Upload reports
uses: actions/upload-artifact@v3
with:
name: sast-reports
path: |
bandit.json
semgrep.json
GitLab CI
sast:
stage: test
image: python:3.11
script:
- pip install bandit semgrep
- bandit -r . -f json -o bandit.json || true
- semgrep --config=auto --json --output=semgrep.json || true
artifacts:
reports:
sast: bandit.json
最佳实践
- 尽早并频繁运行 - 使用提交前钩子和 CI/CD
- 组合使用多种工具 - 不同工具可以发现不同的漏洞
- 调整误报 - 配置排除项和阈值
- 确定发现项的优先级 - 优先处理 CRITICAL/HIGH 级问题
- 感知框架的扫描 - 使用特定的规则集
- 自定义规则 - 针对组织的模式
- 开发者培训 - 安全编码实践
- 增量修复 - 逐步修复
- 基线管理 - 跟踪已知问题
- 定期更新 - 保持工具处于最新状态
相关工具
- security-secrets.md - 高级凭据检测
- security-owasp.md - OWASP Top 10 评估
- security-api.md - API 安全测试
- security-scan.md - 全面安全扫描