静态分析与质量门禁

让 Agent 将 SAST、数据流与规则引擎接入 PR:严重级别、基线与误报抑制流程清晰可审计。

SKILL 应列出所用引擎(Semgrep、CodeQL、SpotBugs 等)、扫描路径与语言版本,并约定「阻断」「仅评论」「仅报告」三类结果的处置。

对存量告警采用基线文件或按引入时间过滤,避免新代码与历史债务混在同一门禁下无法推进;新规则上线需附带修复示例或文档链接。

引擎与处置策略

同一 PR 上多种扫描器并存时,Agent 应能按规则 ID 归类、避免重复评论;与依赖扫描、Secret 扫描在安全看板统一优先级。

  • 高危(注入、硬编码密钥)默认阻断合并。
  • 中低危可配置为 advisory:写入 Checks 摘要或 PR 评论,但不阻塞。
  • 引擎版本与规则集在 CI 中钉扎;升级需附带变更说明与样本 diff。

ESLint 完整配置文件示例(.eslintrc.json):

// .eslintrc.json — TypeScript + React 项目推荐配置
{
  "env": { "browser": true, "es2022": true, "node": true },
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended-type-checked",
    "plugin:react/recommended",
    "plugin:react-hooks/recommended",
    "plugin:jsx-a11y/recommended"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "project": "./tsconfig.json",
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": ["@typescript-eslint", "react", "react-hooks"],
  "rules": {
    // 禁止项(error 级别 → 阻断 CI)
    "no-console": ["error", { "allow": ["warn", "error"] }],
    "@typescript-eslint/no-explicit-any": "error",
    "@typescript-eslint/no-floating-promises": "error",
    "no-eval": "error",

    // 警告项(warn 级别 → 评论但不阻断)
    "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
    "react/prop-types": "off",

    // React 18+ 不再需要 import React
    "react/react-in-jsx-scope": "off"
  },
  "ignorePatterns": ["dist/", "coverage/", "*.generated.ts"]
}

基线与误报抑制

基线只收录「已接受风险」或「计划内偿还」项,每条须可追溯到工单;抑制注释必须含工单号与过期复审日期。

  • 新代码门禁优先用「仅针对变更集」或 SARIF 中的 new 标记,与全量基线分离。
  • 误报走规则调整或路径级豁免,禁止无注释的全局关闭。
  • 真阳性修复后删除对应基线条目或抑制,避免僵尸条目。

SonarQube 质量门禁配置(Quality Gate)与自定义 ESLint 规则示例:

// SonarQube Quality Gate 阈值配置(sonar-project.properties)
sonar.projectKey=my-app
sonar.sources=src
sonar.tests=src
sonar.test.inclusions=**/*.test.ts,**/*.spec.ts
sonar.coverage.exclusions=**/generated/**,**/migrations/**

# 质量门禁阈值(在 SonarQube UI 或 sonarcloud.io 设置)
# 新代码质量门(推荐,只检查本次变更):
#   覆盖率 > 80%            → 阻断
#   重复度 < 3%             → 阻断
#   可靠性评级 ≥ A          → 阻断
#   安全性评级 ≥ A          → 阻断
#   可维护性评级 ≥ A        → 警告(不阻断)

// 自定义 ESLint 规则示例(禁止使用 console.log 但允许 console.error)
// rules/no-console-log.js
module.exports = {
  meta: {
    type: "suggestion",
    docs: { description: "禁止使用 console.log(使用 logger.info 替代)" },
    schema: [],
    messages: { noConsoleLog: "请使用 logger.info() 替代 console.log()" },
  },
  create(context) {
    return {
      CallExpression(node) {
        if (
          node.callee.type === "MemberExpression" &&
          node.callee.object.name === "console" &&
          node.callee.property.name === "log"
        ) {
          context.report({ node, messageId: "noConsoleLog" });
        }
      },
    };
  },
};

pre-commit 集成与 SARIF 上传

将 SARIF 上传到 GitHub Advanced Security、GitLab SAST 或自研聚合器时,Agent 应能根据 fingerprints / partialFingerprints 去重、关联 CWE,并在说明中区分真阳性需修与需规则调整的误报。

  • 制品:每个 job 产出独立 .sarif,合并时注意 tool.driver 与 run 元数据不互相覆盖。
  • 严重度映射:将引擎级别映射到平台统一枚举(如 error / warning / note),与合并门禁阈值一致。
  • 路径originalUriBaseIds 与 CI 工作目录对齐,避免 PR 上无法定位行号。
  • 门禁:按规则 ID、级别与是否为新引入结果组合策略;可选「仅 fail on new」配合基线文件。

pre-commit hook 集成静态分析(.pre-commit-config.yaml):

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-merge-conflict

  # ESLint(只检查暂存文件,通过 lint-staged 配合)
  - repo: local
    hooks:
      - id: eslint
        name: ESLint
        entry: npx eslint --max-warnings 0
        language: node
        types: [javascript, jsx, ts, tsx]
        pass_filenames: true

      # Semgrep(本地 SAST,推荐在 CI 中用全量扫描)
      - id: semgrep
        name: Semgrep
        entry: semgrep --config=p/typescript --error
        language: python
        types: [typescript]
        pass_filenames: true

# CI GitHub Actions 完整静态分析(阻断 vs 警告)
# - name: Run ESLint (阻断: error级别)
#   run: npx eslint . --max-warnings 0 --format json -o eslint-results.json
#   continue-on-error: false   # error 级别失败 → 阻断合并
#
# - name: Run Semgrep (警告: 仅评论)
#   run: semgrep --config=p/typescript --json > semgrep-results.json
#   continue-on-error: true    # 不阻断,仅上传 SARIF 作为评论
提示:GitHub 上常用 github/codeql-action/upload-sarif 或第三方 upload 动作;GitLab 使用流水线 artifacts:reports:sast。SKILL 应写明所用动作名与必需字段(sarif_filecategory 等)。

PR 合流主流程

固定顺序:扫描 → SARIF 归一化与上传 → 平台去重展示 → 按门禁判定 → 真阳性修复或误报走审计流程。

  [ CI:引擎跑扫描,写出 SARIF 2.1.x ]
                    │
                    ▼
         [ 归一化:路径前缀、severity 映射、tool 元数据 ]
                    │
                    ▼
         [ 上传:GH upload-sarif / GL artifacts:reports:sast ]
                    │
                    ▼
              [ 平台:指纹去重 + CWE / 规则 ID 展示 ]
                    │
           ┌────────┴────────┐
           ▼                 ▼
    [ 门禁:new + 级别阈值 ]   [ advisory:评论 / Check 摘要不阻断 ]
           │                 │
           └────────┬────────┘
                    ▼
         [ triage:真阳性修代码 / 误报改规则或基线 + PR 审计 ]
                    │
                    ▼
         [ 合流:规则版本归档 + 与 Secret / 依赖扫描同板展示 ]

门禁清单生成器

下方表单仅在本页浏览器内拼接 Markdown,不上传服务器;可用于 PR 描述、SKILL 附录或平台配置评审单。

填写后点击「生成」,再「复制」到剪贴板。

SKILL 片段

---
name: static-analysis-cn
description: 配置静态分析门禁、ESLint/SonarQube/SARIF 与处置策略
---
# 工具约定
- ESLint:error 级别阻断 CI,warn 级别仅评论
- SonarQube:新代码覆盖率 > 80%,可靠性/安全性 ≥ A
- Semgrep:高危规则阻断,中低危 advisory

# 阻断条件(阻止合并)
- ESLint error 级别规则触发
- SonarQube 质量门禁未通过(新代码)
- Semgrep 高危规则(注入、硬编码密钥)
- npm audit 高危 CVE

# 警告条件(评论但不阻断)
- ESLint warn 级别规则
- SonarQube 可维护性问题
- Semgrep 中低危规则

# pre-commit 集成
- 仅扫描暂存文件(lint-staged + pre-commit)
- 本地快速检查,CI 做全量扫描
- 钩子失败时提示修复命令

# 基线与误报
- 新代码用「仅针对变更集」门禁,不混入历史债务
- 抑制注释必须含工单号和复审日期
- 真阳性修复后删除对应基线条目

# SARIF 上传
- GitHub: github/codeql-action/upload-sarif
- GitLab: artifacts:reports:sast
- 路径对齐 originalUriBaseIds 与 CI 工作目录

返回技能库 更多技能入口