OWASP Top 10 Review skill for Codex

Find real OWASP bugs at file:line. With this skill Codex maps your app's attack surface, walks every OWASP Top 10 category against the real handlers, and reports each finding with the untrusted source, the sink, the missing control and a fix that compiles. It prioritizes access-control and injection bugs, where most real issues live, instead of listing generic advice.

  • Security
  • $owasp-top-10-review
  • 118 lines
  • 2 files
  • ~1,500 tokens
  • MIT
  • Updated
  • Editor's pick

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- owasp-top-10-review

Installs to ~/.agents/skills/owasp-top-10-review/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $owasp-top-10-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

Reviews a web application's source for the OWASP Top 10 (2021, with 2025 category shifts) — broken access control, injection, cryptographic failures, SSRF, insecure design and the rest — and reports findings with file:line evidence and a concrete fix. Use when asked to "check this app for OWASP issues", harden an endpoint, review auth or access-control code, or before a release that handles user data.

Use it when

  • Reviewing an app or endpoint for web security issues
  • Hardening auth, access control or data-handling code
  • A pre-release security pass on code that handles user data

Use something else when

  • You want a security-focused review of an arbitrary diff rather than full OWASP coverage: use secure-code-review
  • You need live exploitation against an authorized target: use web-app-pentest
  • The concern is only outdated dependencies with CVEs: use dependency-scanning

How to check the result

Each finding names a file:line, the untrusted input and the sink; re-grep the same pattern across sibling handlers to confirm the fix was applied everywhere.

The mistake it prevents

Reporting grep hits from tests, comments or framework-escaped sinks as findings without tracing the data flow from an untrusted source.

~/.agents/skills/owasp-top-10-review/SKILL.md

--- name: owasp-top-10-review description: Reviews a web application's source for the OWASP Top 10 (2021, with 2025 category shifts) — broken access control, injection, cryptographic failures,… license: MIT ---

A good review names the exact category, points at the vulnerable line, proves why it is exploitable in this code (not in general), and gives a fix that compiles. “Add input validation” is not a finding; “the userId from req.params is used in the query without an ownership check at routes/orders.js:42” is.

Before you start

  • Read AGENTS.md and the project README for the stack, framework and auth model.
  • Map the attack surface first: list every route/handler, every place untrusted input enters (query, body, headers, cookies, path, file uploads, webhooks, message queues), and every trust boundary (auth middleware, tenant isolation, admin-only paths).
  • Identify the authn/authz mechanism (session, JWT, OAuth) and the data store. Most of the real findings cluster around access control and injection.

This skill is a code review, not a live test. It needs no network and no running app.

Category checklist

Walk each category against the mapped surface. Record every hit with file:line.

#Category (2021)Look for
A01Broken Access ControlObject IDs from the request used without an ownership/tenant check; missing role checks on admin routes; client-trusted isAdmin; path traversal in file access; CORS * with credentials
A02Cryptographic FailuresSecrets/PII sent or stored in plaintext; MD5/SHA1 for passwords; hardcoded keys; Math.random() for tokens; missing TLS; disabled cert verification
A03InjectionString-built SQL/NoSQL/LDAP/OS commands; eval/exec on input; unescaped HTML (XSS); template injection; ORM raw() with interpolation
A04Insecure DesignNo rate limit on auth/reset; missing anti-automation; trust in client-side checks only; business-logic flaws (negative quantities, price from client)
A05Security MisconfigurationDebug on in prod; default creds; verbose stack traces to users; permissive CORS; missing security headers; open cloud buckets
A06Vulnerable ComponentsOutdated deps with known CVEs; unpinned versions (hand off to dependency-scanning)
A07Identification & Auth FailuresWeak password policy; no lockout/MFA; session fixation; JWT alg:none or unverified signature; tokens in URLs
A08Software & Data IntegrityUnsigned/untrusted updates; insecure deserialization (pickle, Java readObject, PHP unserialize); CI pulling unpinned actions
A09Logging & Monitoring FailuresNo audit log on auth/privilege change; secrets/PII in logs; no alerting path
A10SSRFUser-controlled URLs fetched server-side without allowlist/validation (hand off to full SSRF defenses)

How to find the high-value bugs fast

Access control (A01) is where most real findings are. For every handler that reads a resource by ID, ask: who owns this row, and where is that enforced? Grep the pattern:

# Params/body used to look up records — check each for an ownership/tenant filter
grep -rnE "findById|findOne|WHERE id|params\.(id|userId)|\.get\(['\"]id" --include=*.js --include=*.ts src
# Admin or role gates — confirm they cannot be bypassed by another route
grep -rniE "isAdmin|role|authorize|requireAuth|@PreAuthorize" src

Injection (A03). Any query assembled with +, template literals, f-strings or .format() around input is a finding unless the driver parameterizes it.

grep -rnE "(query|execute)\(.*(\+|\$\{|%s.*%|f['\"]).*" src   # candidate string-built queries
grep -rnE "eval\(|exec\(|child_process|os\.system|subprocess" src

Secrets & crypto (A02). Scan for hardcoded material and weak primitives:

grep -rniE "api[_-]?key|secret|password|private[_-]?key|BEGIN RSA" src .env*
grep -rniE "md5|sha1|createHash\(['\"]md5|DES|ECB|Math\.random" src

For each hit, open the file and confirm the data flow from an untrusted source to the sink before you report it. A grep hit inside a test fixture or a comment is not a finding.

Confirming exploitability

Promote a candidate to a finding only when you can state the untrusted source, the sink, and the missing control. For an access-control bug, write the one-line exploit in words: “User A requests GET /orders/<B's id> and receives B’s order because no userId filter is applied.” If you cannot articulate that, mark it “needs verification” instead of asserting it.

Severity

Rate by impact × exploitability, aligned to CVSS bands:

  • Critical — unauthenticated RCE, auth bypass, mass data exposure, SQLi on a prod path.
  • High — authenticated privilege escalation, IDOR exposing other tenants’ data, stored XSS.
  • Medium — reflected XSS needing user interaction, CSRF on a state change, missing rate limit on auth.
  • Low — missing security header, verbose errors, info leak with no direct impact.

Output contract

## OWASP Top 10 review — <app/scope> (<date>)
Scope: <paths/modules reviewed>. Not covered: <what you did not read>.

### Findings
#### [Critical] A01 Broken Access Control — IDOR on order lookup
- Location: `routes/orders.js:42`
- Untrusted input: `req.params.id` (any authenticated user)
- Sink: `Order.findById(req.params.id)` returned without owner check
- Impact: any user reads any order (PII, totals)
- Fix:
  ```js
  const order = await Order.findOne({ _id: req.params.id, userId: req.user.id });
  if (!order) return res.sendStatus(404);
  • Status: confirmed by code path

Summary

<counts by severity>. Top 3 to fix first: <list>.


## Hard rules

- Report only what the code shows. Do not assert exploitability you have not traced.
- Never run exploit payloads against a live or shared system from here — this is static
  review. Live testing belongs to an authorized engagement (see web-app-pentest).
- Keep secrets you find out of the report body; reference the location and say "rotate".
- Re-grep after fixes land: the same pattern often repeats across sibling handlers.

What the zip contains

SKILL.md plus the interface file below. Nothing runs on install.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "OWASP Top 10 Review"
  short_description: "Find real OWASP bugs at file:line"
  default_prompt: "$owasp-top-10-review Review this Express app against the OWASP Top 10 before we ship"

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.

esc