mcpField
S
sast-scanning

sast-scanning

github.com/bagelhole安全1.2k374 次安装23 周前更新
代码仓库

关于 sast-scanning

SAST Scanning 技能整理了通过静态分析检查源代码漏洞的方法和工具。适合将安全扫描纳入开发与 CI/CD 流程的团队,并涵盖多种语言及规则配置。

主要功能

  1. 01比较多种 SAST 工具
  2. 02配置自定义扫描规则
  3. 03接入 CI/CD 工作流
  4. 04按语言选择扫描工具
  5. 05设置质量门禁并处理误报

适用场景

  1. 01在提交或 PR 时扫描代码
  2. 02为代码库添加安全检查门禁
  3. 03排查误报并扩展规则覆盖

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill sast-scanning

安装后在 Claude Code 中输入/sast-scanning确认已加载。

附带文件references/sast-tools.md

详细介绍

SAST 扫描

通过静态分析识别源代码中的安全漏洞。

何时使用此技能

在以下情况下使用此技能:

  • 实施安全 SDLC 实践
  • 在 CI/CD 中添加安全门禁
  • 自动化代码安全审查
  • 在部署前发现漏洞
  • 满足合规要求

前提条件

  • 源代码访问权限
  • CI/CD 流水线
  • 已安装 SAST 工具

工具对比

工具许可证语言最适合
SemgrepOSS/商业版30+自定义规则、速度
CodeQL免费(GitHub)10+深度分析
SonarQubeOSS/商业版25+质量 + 安全
BanditOSSPythonPython 项目
BrakemanOSSRubyRails 应用

Semgrep

安装
# Install via pip
pip install semgrep

# Or via Homebrew
brew install semgrep
基本用法
# Run with default rules
semgrep --config auto .

# Run specific rulesets
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 .

# Output formats
semgrep --config auto --json -o results.json .
semgrep --config auto --sarif -o results.sarif .
自定义规则
# .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"

  - 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()
CI 配置
# .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 }}

CodeQL

设置
# .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 }}"
自定义查询
// 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

Docker 设置
# 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:
扫描器配置
# 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
CI 集成
# 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 }}

特定语言的工具

Python(Bandit)
# Install
pip install bandit

# Run scan
bandit -r src/ -f json -o bandit-report.json

# With configuration
bandit -r src/ -c bandit.yaml
# bandit.yaml
skips: ['B101', 'B601']
exclude_dirs: ['tests', 'venv']

assert_used:
  skips: ['*_test.py', '*_tests.py']
JavaScript(ESLint Security)
# Install
npm install eslint eslint-plugin-security --save-dev
// .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)
# Install
gem install brakeman

# Run scan
brakeman -o brakeman-report.json -f json

# CI configuration
brakeman --no-exit-on-warn --no-exit-on-error -o report.html

质量门禁

SonarQube 质量门禁
{
  "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"
    }
  ]
}
自定义门禁脚本
#!/bin/bash
# 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

常见问题

问题:误报过多

问题:对安全的代码模式发出警报 解决方案:调整规则、添加抑制项、使用基线

问题:扫描缓慢

问题:SAST 在 CI 中耗时过长 解决方案:增量扫描、并行执行、排除测试文件

问题:覆盖不足

问题:未检测到漏洞 解决方案:添加自定义规则、组合使用多个工具

最佳实践

  • 在每个 PR/提交上运行
  • 为现有代码建立基线
  • 根据严重程度和可利用性确定优先级
  • 为代码库维护自定义规则
  • 与 IDE 集成,以便尽早获得反馈
  • 随时间跟踪趋势
  • 记录误报抑制项
  • 结合 DAST 实现全面覆盖

相关技能

评论

支持 Markdown