agentleFS
SkillMedevSkillMedev/security-compliance-hardening/skills/secure-code-review/SKILL.md

secure-code-review

Skill0 starsChanged 40 days agoMITView on GitHub

Reviews code for the security flaw classes that cause the most breaches - broken authorization and IDOR, injection, SSRF, mass assignment, and unsafe deserialization - and returns a short, focused findings list with concrete fixes. Use when someone asks "review this code for security issues", "is this endpoint safe", "check this PR for vulnerabilities", or is shipping auth logic, new API endpoints, file handling, or anything that touches untrusted input. Do NOT use for general code quality, style, or maintainability review - use code-review-checklist instead; for prioritizing findings a scanner already produced, use vulnerability-triage; for design-stage analysis before code exists, use threat-model-stride.

16 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use threat-modeling, competitive-analysis and 1 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • msewellSkill

    threat-modeling

    Produces structured threat models for software systems using STRIDE on data flow diagrams. Generates DFDs with trust boundaries, identifies threats per element, scores risks, and defines concrete mitigations. Outputs a complete threat model Markdown document through phased, interactive delivery. Use when threat modeling a system, analyzing security threats, identifying attack surfaces, performing STRIDE analysis, assessing security risks in architecture, creating a threat model document, or when the user mentions threat model, attack surface, trust boundaries, STRIDE, or security risk analysis.

    Also in 3 projects that use this

  • AnthropicSkill

    competitive-analysis

    Framework for building competitive landscape decks — market positioning, competitor deep-dives, comparative analysis, strategic synthesis. Use when the user asks for a competitive landscape, competitor analysis, peer comparison, market positioning assessment, strategic review, or investment memo deck. Also triggers on "who are the competitors to X", "benchmark X against peers", "build a market map", or any request to systematically evaluate competitive dynamics across an industry.

    Also in 3 projects that use this

  • AnthropicSkill

    incident-response

    Run an incident response workflow — triage, communicate, and write postmortem. Trigger with "we have an incident", "production is down", an alert that needs severity assessment, a status update mid-incident, or when writing a blameless postmortem after resolution.

    Also in 3 projects that use this

The file

We split this skill into the rules it gives an agent

12 rules. 0 are common, 12 are distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 15 edited versions we read keep these.

  • 12

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    If entry points are unclear, trace them from the router or handler registry before reviewing anything, and label inferred entry points as …

    line 24
  2. Distinctive:

    Verify privileged actions enforce role checks at the function level, not only at the route level - middleware-only checks are bypassed by …

    line 36
  3. Distinctive:

    Check that authorization logic is centralized.

    line 37
  4. Distinctive:

    Do not pad the report with style or theoretical findings - every low-value item lowers the odds the real ones get fixed.

    line 96
  5. Distinctive:

    Do not accept middleware-only or route-only permission checks as proof of authorization.

    line 97
  6. Distinctive:

    Do not pass string-built ORDER BY or identifier interpolation as safe "because it's not a value" - it is still injectable.

    line 98
  7. Distinctive:

    Do not accept a blocklist sanitizer for HTML or an "encode everything as HTML" approach.

    line 99
  8. Distinctive:

    Do not confirm authentication and stop.

    line 100
  9. Distinctive:

    Do not review only the diff when the change touches auth - read the callers, because authorization bugs live at call sites.

    line 101
  10. Distinctive:

    Every finding has a realistic attack scenario an engineer can reproduce, not a rule citation.

    line 105
  11. Distinctive:

    Every finding names the exact fix.

    line 106
  12. Distinctive:

    All six categories (authz, SQL, shell, HTML/path, SSRF, mass assignment/deserialization) were covered or explicitly marked out of scope.

    line 108

“Common” is measured: kept by at least 6 in 10 of the 15 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Secure Code Review

Secure code review is not a checklist audit - it is a focused search for the flaw categories that actually cause breaches. A 40-finding report gets skimmed and ignored; a 5-finding report where every item is exploitable gets fixed. The costly mistake this skill prevents is spending review time evenly across the diff while the one missing ownership check ships to production.

Operating procedure

Work the steps in order: scope first, then the highest-breach-rate categories, then filtering, so scrutiny lands where risk lives.

Step 1: Gather inputs

  • The code under review: diff, PR, or file set.
  • Entry points: which routes, handlers, jobs, or consumers accept untrusted input (request params, headers, cookies, body, queue messages, webhooks).
  • Stack facts: framework, ORM or query layer, template engine, auth model (session, JWT, API key).
  • Deployment context: internet-facing or internal, and whether the service runs in a cloud environment with an instance metadata endpoint.
  • What changed and why, in one sentence - reviews without intent context miss logic flaws.

If entry points are unclear, trace them from the router or handler registry before reviewing anything, and label inferred entry points as guesses.

Step 2: Budget scrutiny by risk

Spend time proportional to risk: auth logic and untrusted-input handling get the deepest read; rendering, styling, and config get a skim. Any function reachable from untrusted input is in scope; pure internal refactors of trusted data are not.

Step 3: Authorization - the highest-value check

Broken authorization (OWASP A01) is the most common high-severity finding. For every action that reads or mutates a resource:

  • Confirm the code checks that the authenticated user owns or has permission for the specific resource ID - not merely that the user is logged in.
  • Hunt IDOR: resource IDs from request parameters used without ownership verification.
  • Verify privileged actions enforce role checks at the function level, not only at the route level - middleware-only checks are bypassed by internal calls.
  • Check that authorization logic is centralized; duplicated per-endpoint checks drift and create gaps.

Bad - authenticated but not authorized:

@app.get("/invoices/<invoice_id>")
def get_invoice(invoice_id):
    user = require_login()                    # proves identity only
    return db.invoices.find(id=invoice_id)   # any logged-in user reads any invoice

Good - ownership enforced in the query, uniform response:

@app.get("/invoices/<invoice_id>")
def get_invoice(invoice_id):
    user = require_login()
    invoice = db.invoices.find(id=invoice_id, owner_id=user.id)
    if invoice is None:
        abort(404)   # same response for missing and forbidden - no existence oracle
    return invoice

Step 4: Injection surfaces

For any code that constructs queries, commands, or markup from user input:

  • SQL: parameterized queries or a safe ORM API throughout - no string concatenation into query bodies, even for identifiers or ORDER BY clauses (map user sort keys through an allowlist).
  • Shell: flag any exec/spawn call that includes user input. The correct fix is to avoid shell execution; if unavoidable, use argument arrays, never string interpolation.
  • HTML/templates: output encoding for the correct context (HTML body, attribute, JavaScript, URL). Rich-text user content must pass through a sanitization library with an allowlist, never a blocklist.
  • Path traversal: normalize any user-supplied filename or path and confirm it resolves inside the expected root directory before use.

Step 5: Server-side request forgery

Any outbound HTTP request with a URL derived from user input is an SSRF candidate:

  • Confirm the target is validated against an allowlist of permitted hosts and schemes before the request fires.
  • Cloud-hosted services: verify requests to instance metadata endpoints (169.254.169.254, fd00:ec2::254) are blocked.
  • Redirects: confirm the HTTP client does not follow redirects automatically, or that each redirect destination is re-validated against the allowlist.

Step 6: Mass assignment and deserialization

  • Mass assignment: model or ORM binding must use an explicit allowlist of permitted fields, not a deny-list. Any field controlling permissions, ownership, or internal state must be excluded from user-supplied binding.
  • Deserialization: flag any deserialization of user-supplied data via native object serialization (Java ObjectInputStream, Python pickle, PHP unserialize, Ruby Marshal) - almost always unsafe with untrusted input. Prefer JSON or protobuf with explicit schema validation.

Step 7: Filter - raise vs skip

Raise: anything letting an attacker access data or perform actions beyond their authorization, execute code, or exfiltrate secrets. Skip: style issues, missing logging (unless the gap breaks audit requirements), and theoretical issues with no realistic attack path in the current deployment. Target roughly seven findings or fewer, ordered by severity; a longer list means the filter was not applied.

Step 8: Write the findings

Each finding: file and line, flaw class, one-sentence attack scenario ("an authenticated user can read any tenant's invoices by iterating IDs"), severity (Critical for unauthenticated data access or code execution; High for authenticated cross-user access; Medium for issues needing chaining or non-default config), and the concrete fix - the specific code change, not "sanitize input".

Deliverable

Produce a findings report containing: the reviewed scope and entry points, at most about seven findings each with file:line, flaw class, one-sentence attack scenario, severity, and a specific fix, plus an explicit "checked, clean" list of the categories reviewed with nothing to raise.

Do NOT

  • Do not pad the report with style or theoretical findings - every low-value item lowers the odds the real ones get fixed.
  • Do not accept middleware-only or route-only permission checks as proof of authorization; internal call paths bypass them.
  • Do not pass string-built ORDER BY or identifier interpolation as safe "because it's not a value" - it is still injectable.
  • Do not accept a blocklist sanitizer for HTML or an "encode everything as HTML" approach; encoding must match the output context.
  • Do not confirm authentication and stop; nearly every IDOR sits behind a valid login.
  • Do not review only the diff when the change touches auth - read the callers, because authorization bugs live at call sites.

Quality bar

  • Every finding has a realistic attack scenario an engineer can reproduce, not a rule citation.
  • Every finding names the exact fix; none say "validate input" without saying how and where.
  • Authorization was checked object-by-object for every resource access in scope.
  • All six categories (authz, SQL, shell, HTML/path, SSRF, mass assignment/deserialization) were covered or explicitly marked out of scope.
  • The report is short enough to be read whole - about seven findings or fewer.

Escalation

Route general readability and maintainability review to code-review-checklist, prioritization of scanner output to vulnerability-triage, design-stage questions to threat-model-stride, and any hardcoded credential found mid-review to secrets-hygiene immediately - a live secret in code outranks every other finding.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.