评审代码变更的安全性
审查代码变更中的安全问题
以手动方式或在 CI/CD 中审查拉取请求和本地变更,查找安全回归问题。
运行安全变更审查,以查找 Git 支持的单个变更集中的回归问题。 Codex 会审查每个发生变更的源代码类文件及其直接相关的支持代码。 它不会将审查范围扩大为完整的仓库审计。
如果你希望扫描整个仓库而不是特定变更,请参阅运行 安全扫描。
运行手动审查
在桌面应用中,打开 Security,选择 Scans,然后选择 + Scan。 选择仓库,然后选择 Changes。审查未提交的变更、 单个提交,或基准修订和头部修订。变更扫描不支持 Deep scan。
你也可以在对话中要求 Codex 审查未提交的变更:
Use $codex-security:security-diff-scan to review my current uncommitted changes for security regressions.对于提交或分支范围,请在需要时指定两端:
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.如果本地检出中存在拉取请求的基准修订和头部修订, 你也可以直接指定该拉取请求。
在设置过程中确认变更
- 选择 Changes。
- 确认已检出的仓库、当前分支和最新提交。
- 在 Changes to review 下选择:
Uncommitted changes,用于审查当前工作树。- 最新提交,用于审查单个提交。
- 基准修订和头部修订,用于审查分支或拉取请求范围。
- 确认摘要描述的是你打算审查的变更。
- 选择 Start scan。
此工作流不会检出其他分支,也不会更改所选的工作树。 如果请求的修订在本地不可用,请在审查前将其提取到本地, 或提供本地可用的基准修订和头部修订。
处理发现
审查结果后,请修复并验证已接受的 发现,或导出并跟踪 发现。
在 CI/CD 中自动执行审查
当运行器可以在无需交互的情况下调用 Codex CLI 时,请从 CI 运行同一个 $codex-security:security-diff-scan 技能。
首先安装 CLI 和插件,并避免暴露扫描凭据:
npm install --global @openai/codex在 CLI 中安装 Codex Security 插件:
codex plugin add codex-security@openai-curated安装命令使用公共 Codex CLI 插件市场。在 CI 中依赖 特定插件版本或功能之前,请查看插件更新日志。
然后,仅在扫描期间将 CI 机密存储中的 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>/ |
请求时生成的详细漏洞报告和支持性概念验证文件。 |
hardening/ |
请求时生成的结构性加固指南和支持性提案。 |
findings.json |
包含稳定标识符、严重程度、置信度、源代码位置和修复措施的发现。可将其提供给已获批准的内部安全工作流或下游工具。 |
scan-manifest.json |
密封的扫描收据,包含已审查的目标、修订和工件哈希。 |
coverage.json |
已审查和推迟审查的部分、排除项以及覆盖完整度。 |
findings.json 架构
定义了完整结构。该架构包含以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
documentType |
字符串 | 将文档标识为 codex-security.findings。 |
schemaVersion |
字符串 | 标识发现架构的版本。 |
scanId |
字符串 | 标识生成这些发现的扫描。 |
findings |
数组 | 包含零个或多个发现对象。 |
findings[].findingId |
字符串 | 从发现指纹派生的稳定发现标识符。 |
findings[].occurrenceId |
字符串 | 标识特定扫描中此次出现的发现。 |
findings[].ruleId |
字符串 | 标识漏洞系列。 |
findings[].identity |
对象 | 包含语义锚点和可选的同级实例标识符。 |
findings[].fingerprints |
对象 | 包含指纹算法和主指纹。 |
findings[].title |
字符串 | 提供简短的发现标题。 |
findings[].summary |
字符串 | 概述漏洞及其影响。 |
findings[].severity |
对象 | 包含严重程度级别和可选的评分详情。 |
findings[].confidence |
对象 | 包含置信度级别和理由。 |
findings[].taxonomy |
对象 | 包含漏洞类别和 CWE 标识符。 |
findings[].locations |
数组 | 列出受影响的文件、行号和位置角色。 |
findings[].remediation |
字符串 | 描述建议的修复措施。 |
findings[].provenance |
对象 | 标识发现的来源。 |
例如,以下命令会为每项发现输出一行以制表符分隔的数据:
jq -r '
.findings[] |
[.findingId, .severity.level, .confidence.level, .locations[0].path, .locations[0].startLine, .title] |
@tsv
' findings.json这些示例假定使用受信任的 Linux 运行器,其中装有 Node.js 和 npm、Git、Python
3、jq 以及提供商的命令行工具。npm 全局软件包前缀
必须可写。
请选择与你的 CI 提供商对应的示例。扫描结果可能包含敏感的漏洞详情。请将工件设为私有,并且只有在审查受众、内容和所需批准后才能发布发现。
name: Codex Security review
on:
pull_request:
jobs:
security-review:
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
persist-credentials: false
- name: Install Codex Security
env:
CODEX_HOME: ${{ runner.temp }}/codex-home
run: |
npm install --global @openai/codex
codex plugin add codex-security@openai-curated
- name: Review code changes
env:
CODEX_SECURITY_API_KEY: ${{ secrets.CODEX_SECURITY_API_KEY }}
CODEX_HOME: ${{ runner.temp }}/codex-home
TMPDIR: ${{ runner.temp }}/codex-security
BASE_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."
- uses: actions/upload-artifact@v4
if: always()
with:
name: codex-security-review
path: ${{ runner.temp }}/codex-security/codex-security-scans 创建一个已屏蔽的 CODEX_SECURITY_API_KEY CI/CD 变量,并在共享发现前私下审查扫描
工件。
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
export 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/codex
codex plugin add codex-security@openai-curated
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."
after_script:
- |
unset CODEX_SECURITY_API_KEY
scan_root="/tmp/codex-security-$CI_JOB_ID/codex-security-scans"
if [ -d "$scan_root" ]; then
tar -czf codex-security-artifacts.tar.gz -C "$scan_root" .
fi
artifacts:
when: always
paths:
- codex-security-artifacts.tar.gz trigger: none
pool:
vmImage: ubuntu-latest
steps:
- checkout: self
fetchDepth: 0
- bash: |
set -euo pipefail
export CODEX_HOME="$AGENT_TEMPDIRECTORY/codex-home"
npm install --global @openai/codex
codex plugin add codex-security@openai-curated
displayName: Install Codex Security
- bash: |
set -euo pipefail
export 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 changes
condition: and(succeeded(), ne(variables['System.PullRequest.IsFork'], 'True'))
env:
CODEX_SECURITY_API_KEY: $(CODEX_SECURITY_API_KEY)
- publish: $(Agent.TempDirectory)/codex-security/codex-security-scans
artifact: codex-security-review
condition: always()对于 Azure Repos,请配置 Build validation 分支策略,以便在 拉取请求上运行流水线。
pipeline {
agent { label 'linux' }
stages {
stage('Codex Security review') {
when {
allOf {
changeRequest()
expression { !env.CHANGE_FORK?.trim() }
}
}
steps {
sh '''#!/usr/bin/env bash
set -euo pipefail
export 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/codex
codex plugin add codex-security@openai-curated
'''
withCredentials([string(credentialsId: 'codex-security-api-key', variable: 'CODEX_SECURITY_API_KEY')]) {
sh '''#!/usr/bin/env bash
set +x
set -euo pipefail
export 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 bash
set -euo pipefail
scan_root="/tmp/codex-security-$BUILD_TAG/codex-security-scans"
if [ -d "$scan_root" ]; then
tar -czf codex-security-artifacts.tar.gz -C "$scan_root" .
fi
'''
archiveArtifacts artifacts: 'codex-security-artifacts.tar.gz', allowEmptyArchive: true
}
}
}
}
} 这些示例会跳过来自复刻仓库的拉取请求。只有使用受保护的
流水线定义,并且贡献者可信、可以接触扫描
凭据时,才运行需要凭据的作业。归档 codex-security-scans,将结构化发现、
清单、覆盖范围和 report.md 保存在一起,并同时保留所有按要求生成的
findings/ 或 hardening/ 输出。先从建议性结果开始,并在将该作业
设为必需检查前审查覆盖范围和运行时间。
有关 API key 处理和沙箱控制的信息,请参阅非交互
模式。如果你的组织允许使用 Codex
GitHub Action,它可以在运行时安装 CLI,但你
仍须先安装插件,并将该 Action 的 codex-home 输入指向
同一个 CODEX_HOME。