评审代码变更的安全性
评审代码变更的安全性
Section titled “评审代码变更的安全性”Codex 中文站说明: 本页围绕“评审代码变更的安全性”重新补充了中文使用场景和验证重点。界面名称可能随 Codex 版本更新,请以当前客户端为准。
对一个由 Git 支撑的变更集做安全回归评审,而不是展开成全仓库审计。
当你需要证明某个由 Git 支撑的变更集是否引入安全回归时,使用安全变更评审。这个工作流会评审所有发生变更的源码类文件和直接支撑代码,但不会把任务扩展成通用仓库审计。
如果你想扫描完整仓库,而不是某个具体变更,请参见运行安全扫描。
运行手动评审
Section titled “运行手动评审”对于未提交改动,发送:
Use $codex-security:security-diff-scan to review my current uncommitted changes for security regressions.对于 commit 或 branch range,必要时明确两端:
Use $codex-security:security-diff-scan to review the changes from origin/main to HEAD for security regressions. Focus on authentication, authorization, input handling, filesystem access, network requests, and secrets.当 pull request 的 base 和 head revision 在本地 checkout 中可用时,也可以直接指定 pull request。
在设置中确认变更
Section titled “在设置中确认变更”- 确认 Scan type(扫描类型) 是
Changes。 - 确认已检出的 Codebase(代码库)、Current branch(当前分支) 和 Last commit(最新提交)。
- 在 Changes to review(待评审改动) 下选择:
Uncommitted changes:当前 Git 工作区中的未提交改动。- 最新 commit:单个 commit 的评审。
- base revision 和 head revision:分支或 pull request 的修订版本区间。
- 确认摘要描述的是你想评审的变更。
- 选择 Start scan(开始扫描)。
这个工作流不会检出另一个分支,也不会修改选中的 Git 工作区。如果请求的 revision 在本地不可用,请先执行 fetch,或提供一组本地可用的 base revision 和 head revision。
处理发现结果
Section titled “处理发现结果”评审结果后,可以修复并验证已接受的发现,或导出和跟踪发现。
在 CI/CD 中自动化评审
Section titled “在 CI/CD 中自动化评审”当 CI runner 能以非交互方式调用 Codex CLI 时,可以在 CI 中运行同一个 $codex-security:security-diff-scan skill。先安装 CLI 与 plugin,同时避免暴露扫描凭据:
npm install --global @openai/codexcodex plugin add codex-security@openai-curated然后,只在扫描期间把 CI secret store 中的 OpenAI API key 作为 CODEX_SECURITY_API_KEY 暴露:
CODEX_API_KEY="$CODEX_SECURITY_API_KEY" codex exec \--sandbox workspace-write \"Use \$codex-security:security-diff-scan to review changes from $BASE_REVISION to $HEAD_REVISION for security regressions. Do not modify the checkout."扫描会把输出写入 $TMPDIR/codex-security-scans/<repository>/<scan-id>/:
| 文件 | 内容 |
|---|---|
report.md |
完整扫描目录的主要可读入口。 |
findings/<slug>/ |
每项需报告发现对应一份详细漏洞报告;有可用材料时还会包含 PoC 文件。 |
hardening/ |
扫描存在需报告发现时,包含结构性加固方案集及配套提案或图示。 |
findings.json |
带稳定标识、严重程度、置信度、源码位置与修复建议的发现,可用于 PR 评论或下游工具。 |
scan-manifest.json |
封存的扫描回执,包含评审目标、修订版本和产物 hash。 |
coverage.json |
已评审与延后处理的范围、排除项和覆盖完整性。 |
完整结构由 findings.json schema定义。部分关键字段如下:
| 字段 | 类型 | 说明 |
|---|---|---|
documentType |
String | 标识文档类型为 codex-security.findings。 |
schemaVersion |
String | 标识 findings schema 版本。 |
scanId |
String | 标识生成这些发现的扫描。 |
findings |
Array | 包含零个或多个发现对象。 |
findings[].findingId |
String | 根据发现 fingerprint 派生的稳定发现标识。 |
findings[].occurrenceId |
String | 标识该发现出现在某次具体扫描中的实例。 |
findings[].ruleId |
String | 标识漏洞类别。 |
findings[].identity |
Object | 包含语义锚点和可选的同级实例标识。 |
findings[].fingerprints |
Object | 包含 fingerprint 算法与主要 fingerprint。 |
findings[].title |
String | 简短的发现标题。 |
findings[].summary |
String | 概述漏洞及其影响。 |
findings[].severity |
Object | 包含严重程度等级和可选评分详情。 |
findings[].confidence |
Object | 包含置信度等级和理由。 |
findings[].taxonomy |
Object | 包含漏洞类别与 CWE 标识。 |
findings[].locations |
Array | 列出受影响文件、行号和位置角色。 |
findings[].remediation |
String | 说明建议修复方式。 |
findings[].provenance |
Object | 标识发现来源。 |
例如,下面的命令会为每项发现输出一行制表符分隔的数据:
jq -r '.findings[] |[.findingId, .severity.level, .confidence.level, .locations[0].path, .locations[0].startLine, .title] |@tsv' findings.json下面的示例假设使用受信任的 Linux runner,并已安装 Node.js 与 npm、Git、Python 3、jq 以及相应平台的 CLI。npm 的全局 package prefix 必须可写。
GitHub Actions
Section titled “GitHub Actions”name: Codex Security review
on:pull_request:
jobs:security-review:if: github.event.pull_request.head.repo.full_name == github.repositoryruns-on: ubuntu-latestpermissions:contents: readpull-requests: writesteps:- uses: actions/checkout@v5with:ref: ${{ github.event.pull_request.head.sha }}fetch-depth: 0persist-credentials: false
- name: Install Codex Securityenv:CODEX_HOME: ${{ runner.temp }}/codex-homerun: |npm install --global @openai/codexcodex plugin add codex-security@openai-curated
- name: Review code changesenv:CODEX_SECURITY_API_KEY: ${{ secrets.CODEX_SECURITY_API_KEY }}CODEX_HOME: ${{ runner.temp }}/codex-homeTMPDIR: ${{ runner.temp }}/codex-securityBASE_SHA: ${{ github.event.pull_request.base.sha }}HEAD_REVISION: ${{ github.event.pull_request.head.sha }}run: |BASE_REVISION="$(git merge-base "$BASE_SHA" "$HEAD_REVISION")"CODEX_API_KEY="$CODEX_SECURITY_API_KEY" codex exec \--sandbox workspace-write \"Use \$codex-security:security-diff-scan to review changes from $BASE_REVISION to $HEAD_REVISION for security regressions. Do not modify the checkout."
- name: Comment with findingsif: always()env:GH_TOKEN: ${{ github.token }}PR_NUMBER: ${{ github.event.pull_request.number }}run: |findings="$(find "${{ runner.temp }}/codex-security/codex-security-scans" -name findings.json -print -quit 2>/dev/null || true)"test -n "$findings" || exit 0jq -r '"## Codex Security findings","",if (.findings | length) == 0 then "No findings reported."else .findings[] | "- **\(.severity.level | ascii_upcase)**: \(.title) (`\(.locations[0].path):\(.locations[0].startLine)`)\n \(.summary)"end' "$findings" | gh pr comment "$PR_NUMBER" --body-file -
- uses: actions/upload-artifact@v4if: always()with:name: codex-security-reviewpath: ${{ runner.temp }}/codex-security/codex-security-scansGitLab CI/CD
Section titled “GitLab CI/CD”创建 masked CODEX_SECURITY_API_KEY 和 GITLAB_TOKEN CI/CD variables。GitLab token 需要 API 访问权限,才能创建 merge-request note。
codex-security-review:rules:- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_PROJECT_ID == $CI_PROJECT_ID'variables:GIT_DEPTH: "0"script:- |codex_security_api_key="$CODEX_SECURITY_API_KEY"unset CODEX_SECURITY_API_KEY GITLAB_TOKENexport CODEX_HOME="/tmp/codex-home-$CI_JOB_ID"export TMPDIR="/tmp/codex-security-$CI_JOB_ID"export BASE_REVISION="$CI_MERGE_REQUEST_DIFF_BASE_SHA"export HEAD_REVISION="${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA:-$CI_COMMIT_SHA}"npm install --global @openai/codexcodex plugin add codex-security@openai-curatedCODEX_API_KEY="$codex_security_api_key" codex exec \--sandbox workspace-write \"Use \$codex-security:security-diff-scan to review changes from $BASE_REVISION to $HEAD_REVISION for security regressions. Do not modify the checkout."after_script:- |gitlab_token="$GITLAB_TOKEN"unset CODEX_SECURITY_API_KEY GITLAB_TOKENscan_root="/tmp/codex-security-$CI_JOB_ID/codex-security-scans"findings="$(find "$scan_root" -name findings.json -print -quit 2>/dev/null || true)"if [ -n "$findings" ]; thenjq -r '"## Codex Security findings","",if (.findings | length) == 0 then "No findings reported."else .findings[] | "- **\(.severity.level | ascii_upcase)**: \(.title) (`\(.locations[0].path):\(.locations[0].startLine)`)\n \(.summary)"end' "$findings" > codex-security-comment.mdcurl --fail --request POST \--header "PRIVATE-TOKEN: $gitlab_token" \--form "body=<codex-security-comment.md" \"$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes"fiif [ -d "$scan_root" ]; thentar -czf codex-security-artifacts.tar.gz -C "$scan_root" .fiartifacts:when: alwayspaths:- codex-security-artifacts.tar.gzAzure Pipelines
Section titled “Azure Pipelines”trigger: none
pool:vmImage: ubuntu-latest
steps:- checkout: selffetchDepth: 0
- bash: |set -euo pipefailexport CODEX_HOME="$AGENT_TEMPDIRECTORY/codex-home"npm install --global @openai/codexcodex plugin add codex-security@openai-curateddisplayName: Install Codex Security
- bash: |set -euo pipefailexport CODEX_HOME="$AGENT_TEMPDIRECTORY/codex-home"export TMPDIR="$AGENT_TEMPDIRECTORY/codex-security"export HEAD_REVISION="$SYSTEM_PULLREQUEST_SOURCECOMMITID"export BASE_REVISION="$(git merge-base HEAD^1 "$HEAD_REVISION")"CODEX_API_KEY="$CODEX_SECURITY_API_KEY" codex exec \--sandbox workspace-write \"Use \$codex-security:security-diff-scan to review changes from $BASE_REVISION to $HEAD_REVISION for security regressions. Do not modify the checkout."displayName: Review code changescondition: and(succeeded(), ne(variables['System.PullRequest.IsFork'], 'True'))env:CODEX_SECURITY_API_KEY: $(CODEX_SECURITY_API_KEY)
- publish: $(Agent.TempDirectory)/codex-security/codex-security-scansartifact: codex-security-reviewcondition: always()对于 Azure Repos,请配置 Build validation branch policy,使该 pipeline 在 pull request 上运行。
Jenkins
Section titled “Jenkins”pipeline {agent { label 'linux' }stages {stage('Codex Security review') {when {allOf {changeRequest()expression { !env.CHANGE_FORK?.trim() }}}steps {sh '''#!/usr/bin/env bashset -euo pipefailexport CODEX_HOME="/tmp/codex-home-$BUILD_TAG"export TMPDIR="/tmp/codex-security-$BUILD_TAG"mkdir -p "$TMPDIR"git fetch --no-tags origin "$CHANGE_TARGET"target="$(git rev-parse FETCH_HEAD)"git fetch --no-tags origin "$CHANGE_BRANCH"git rev-parse FETCH_HEAD > "$TMPDIR/head"git merge-base "$target" "$(cat "$TMPDIR/head")" > "$TMPDIR/base"npm install --global @openai/codexcodex plugin add codex-security@openai-curated'''withCredentials([string(credentialsId: 'codex-security-api-key', variable: 'CODEX_SECURITY_API_KEY')]) {sh '''#!/usr/bin/env bashset +xset -euo pipefailexport CODEX_HOME="/tmp/codex-home-$BUILD_TAG"export TMPDIR="/tmp/codex-security-$BUILD_TAG"export HEAD_REVISION="$(cat "$TMPDIR/head")"export BASE_REVISION="$(cat "$TMPDIR/base")"CODEX_API_KEY="$CODEX_SECURITY_API_KEY" codex exec \--sandbox workspace-write \"Use \$codex-security:security-diff-scan to review changes from $BASE_REVISION to $HEAD_REVISION for security regressions. Do not modify the checkout."'''}}post {always {sh '''#!/usr/bin/env bashset -euo pipefailscan_root="/tmp/codex-security-$BUILD_TAG/codex-security-scans"if [ -d "$scan_root" ]; thentar -czf codex-security-artifacts.tar.gz -C "$scan_root" .fi'''archiveArtifacts artifacts: 'codex-security-artifacts.tar.gz', allowEmptyArchive: true}}}}}这些示例会跳过来自 fork 的 pull request。只有受保护的 pipeline 定义,以及可以信任其接触扫描凭据的贡献者,才能运行带凭据的作业。请归档 codex-security-scans,把结构化发现、manifest、覆盖产物、report.md 及其链接的 findings/ 与 hardening/ 输出保存在一起。先以非阻断方式运行,评审覆盖范围和运行时间后,再把作业设为 required check。
API key 处理与沙箱控制请参见非交互模式。如果组织允许使用 Codex GitHub Action,它可以在运行时安装 CLI,但你仍需先安装 plugin,并让 action 的 codex-home 输入指向同一个 CODEX_HOME。
本站实践建议
Section titled “本站实践建议”应用“评审代码变更的安全性”中的安全设置时,应从最小权限开始,再根据实际任务逐步开放。涉及网络、密钥、生产环境或删除操作时,仍应保留人工确认。
Codex API 与国内使用
Section titled “Codex API 与国内使用”在实践“评审代码变更的安全性”相关功能时,如需为 Codex 配置 OpenAI-compatible API,可以前往 APIBest 获取 API Key。第三方服务的模型映射、价格、额度和数据处理方式以 APIBest 当前说明为准。