Secure Code Review skill for Codex
Security review of a diff, done right. This skill makes Codex review a diff or pull request through a security lens: it classifies what the change touches, traces untrusted input to dangerous sinks, and separates must-fix-before-merge issues from nits. Every comment carries a severity, the evidence from the diff, and a concrete fix rather than vague advice.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- secure-code-review Installs to ~/.agents/skills/secure-code-review/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install secure-code-review The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project secure-code-review Installs to .agents/skills/secure-code-review/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/secure-code-review.zipunzip -o secure-code-review.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) secure-code-review PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $secure-code-review, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Runs a security-focused review of a diff, pull request or module — threat-ranked, tracing untrusted input to dangerous sinks — and leaves precise comments with severity, evidence and a fix. Use when reviewing a PR for security, when a diff touches auth, input handling, crypto, file or network I/O, or when asked "is this change safe to merge?".
Use it when
- Reviewing a PR or diff specifically for security
- A change touches auth, queries, file/URL I/O, crypto or secrets
- Deciding whether a change is safe to merge
Use something else when
- You want full OWASP Top 10 coverage of a whole app, not one diff: use owasp-top-10-review
- You need a threat model of a feature before code exists: use threat-modeling
- The task is live testing of a deployed target: use web-app-pentest
How to check the result
Every High+ comment states the concrete abuse in one sentence and cites a diff line; reconcile manual findings with the project's SAST output instead of duplicating it.
The mistake it prevents
Reviewing hunks in isolation and missing that a new route skips the auth gate its sibling routes enforce.
A security review of a change answers one question per hunk: can untrusted input reach a dangerous operation here without a control in between? Review the diff in the context of the code it touches, not in isolation. Flag only what you can justify; every comment names the risk, the evidence, and the fix.
Scope the review
git fetch origin && git diff --stat origin/main...HEAD # what changed
git diff origin/main...HEAD # the change itself
Read AGENTS.md for stack and conventions. Then classify the diff — a 3-line config
change and a new auth flow get very different scrutiny:
| Diff touches | Review depth |
|---|---|
| Auth, sessions, tokens, access control | Highest — read the whole surrounding flow |
| Raw SQL/query building, templating, shell, deserialization | High — trace every input |
| File upload/download, path handling, URL fetch | High — SSRF/traversal |
| Crypto, secrets, env handling | High — primitives and storage |
| Dependency bumps / lockfile | Check changelog + advisories (hand off to dependency-scanning) |
| Pure UI, copy, formatting | Light — confirm no injected markup sink |
The one question, applied
For each changed hunk that handles data, trace: source → transformations → sink.
- Sources (untrusted): request params/body/headers/cookies, uploaded files, webhook payloads, queue messages, DB rows that originated from users, third-party API responses.
- Sinks (dangerous): SQL/NoSQL queries, OS commands,
eval/dynamic code, HTML/template output, file paths, outbound URLs, deserializers, redirects, log lines with secrets. - Controls (what must sit between): parameterization, output encoding, allowlist validation, authorization check, path canonicalization, size/type limits.
A finding is: a source reaching a sink with no adequate control on the path. If a control exists but is weak (blocklist instead of allowlist, validation that can be bypassed), say so specifically.
High-signal checks for a diff
- New route/handler: is it behind the same auth/authz as its siblings? New endpoints are a classic place where an access-control gate is forgotten.
- Changed query: did a parameterized query become string-built, or did a new column
come from user input?
git diffmakes this visible — look for added+/${}/ f-strings near query calls. - Object lookup by ID: is there an ownership/tenant filter? (IDOR)
- Redirect/
Locationfrom input: open-redirect; require an allowlist or relative path. - New dependency or CI action: pinned to a version/SHA, from a trusted source?
- Error handling: does a new
catchleak stack traces or internal detail to the client? - Secrets: any key, token or password added inline or in a committed
.env? Flag and say rotate — a committed secret is compromised even if removed later. - Logging: does a new log line write a token, password, full card number or PII?
- Regex on input: could it catastrophically backtrack (ReDoS)? Flag nested quantifiers.
Comment style
Each comment: severity tag, one-line risk, the evidence from the diff, the fix. Match the severity bands your team uses; default to Critical / High / Medium / Low / Nit. Keep the tone about the code. Example:
[High] IDOR — `invoices/:id` is read without an owner check.
At routes/invoices.ts:+58, `Invoice.findByPk(req.params.id)` returns any invoice to any
authenticated user. Scope it: `findOne({ where: { id, orgId: req.user.orgId } })`.
Separate “must fix before merge” (Critical/High) from “should fix” (Medium) and “nit”. Do not block a PR on style under a security label.
Verification
- For each High+ finding, state the concrete abuse in one sentence; if you cannot, downgrade to “needs verification” rather than asserting it.
- Run the project’s linters/SAST if present (
semgrep,npm audit, etc.) and reconcile their output with your manual findings — do not duplicate, do not blindly trust. - After fixes, re-diff and confirm the control is actually on the path, not just added nearby.
Output contract
## Security review — PR #<n>: <title>
Verdict: <block | approve-with-fixes | approve>
Scope: <files reviewed> (<n> of <m> changed files; rest are <reason>)
### Must fix before merge
- [High] <risk> — `file:line` — <evidence>. Fix: <fix>.
### Should fix
- [Medium] ...
### Nits / notes
- ...
Positive: <controls done right, so they are not removed later>
Hard rules
- Review what changed and its immediate context; do not rubber-stamp a large diff you did not read. Say which files you did not cover.
- Never approve a change that adds a committed secret — require rotation.
- Do not run exploit payloads against live systems from a review; this is static work.
- If the diff is too large to review safely, say so and ask to split it.
What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Secure Code Review"
short_description: "Security review of a diff, done right"
default_prompt: "$secure-code-review Do a security review of this PR before I merge it" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.