La interfaz está localizada; las descripciones y documentos de las Skills se traducen automáticamente con IA a su idioma. El código, los comandos, rutas y términos técnicos se mantienen en el original, y prevalece el documento del autor.
Explorar Skills
Productividad · SKILL.md

harden

harden

Security audit: threat model, OWASP Top 10 (and LLM Top 10), abuse cases, dependency and secret scan, with ranked findings and concrete fixes. Read-only.

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentación de la Skill

GitHub

name: harden description: >- Security audit: threat model, OWASP Top 10 (and LLM Top 10), abuse cases, dependency and secret scan, with ranked findings and concrete fixes. Read-only. disable-model-invocation: true context: fork

harden — dedicated security review

Look at the system the way an attacker would, then report what a defender must fix. This is the focused security pass; inspect covers general quality with a security axis, but a real hardening review deserves its own depth.

Read references/disciplines/security.md — the shared security reference (STRIDE, OWASP Top 10 + LLM Top 10, secrets, abuse cases). Read CONVENTIONS.md for the workspace (§1), the ledger (§2), judgment (§4.1), the resume sweep (§5), git isolation (§11), multi-agent rules (§8), grounding (§14), and freshness (§17 — check current CVEs/advisories against today's date), and workspace integrity (§20).

Journal every run (§2.1). The first write of the run, once the task folder is resolved (§20.1), is a START entry in the task's log.md; then set this phase in_progress in state.json. Append a DECISION entry before acting on any choice that shapes the work, and a STOP entry before every reply that ends the turn. Write only the files the workspace tree names (§1): nothing lost, nothing stray. Before asking a question or deciding, check the user's judgment (§4.1) for a confirmed rule that covers it, and journal who decided.

Step 1 — Scope & threat model

The iron rule: no finding without a reachable path from an attacker to an asset. A checklist item that fails in the abstract is not a finding until you can name who reaches it and what they get. Build the model before auditing, in this order:

  1. Assets — what is actually worth stealing or breaking here? Credentials, personal data, money movement, the ability to act as another user, availability. Rank them; the audit's attention follows this list, not the checklist's order.
  2. Entry points — every place untrusted input enters: routes and handlers, webhooks, queue consumers, file/image uploads, third-party callbacks, admin surfaces, CLI flags, environment and config. The API is the surface, not the UI — enumerate endpoints from the router, never from the screens.
  3. Actors and their starting privilege — anonymous · self-registered user · another tenant's user · low-privilege staff · compromised dependency · someone with a stolen session. For each finding later, you will name which of these can reach it.
  4. Trust boundaries — draw the lines where data crosses from one privilege level to another. Every boundary is a place validation and authorization must exist; missing checks cluster there.
  5. STRIDE per boundary — spoofing · tampering · repudiation · information disclosure · denial of service · elevation of privilege. Walk the six against each boundary and keep what is concrete for this system.

Load security.md for the checklist that the audit works through.

Step 2 — Audit (read-only)

Work the checklist against the code and config:

  • Access control — authz on every route/action, deny-by-default, no IDOR.
  • Injection & input — parameterized queries, boundary validation.
  • Crypto & secrets — TLS, encryption at rest, strong hashing; no secrets in code/logs (scan the diff).
  • Auth & sessions — rate-limited login, safe session/JWT handling.
  • Dependencies/supply chain — known-vulnerable packages (web-check current advisories, §17).
  • SSRF, deserialization, misconfig, debug endpoints.
  • LLM features — prompt injection, unsafe tool permissions, data leakage.

In multi-agent mode, dispatch parallel auditors by category and merge; the orchestrator owns writes (§8). Single-agent: work the checklist inline with fresh eyes.

These thoughts mean stop — you are about to dismiss a real finding:

The thoughtThe reality
"It's internal-only, not exposed"Internal networks get breached: model a network-internal attacker too. But rank by who can reach it, verified, not by the worst case imagined.
"You'd have to be logged in to hit it"Check whether anyone can register (the signup route or its config, cited). Authenticated ≠ trusted either way.
"Another tenant couldn't reach this"That is the claim to test, not assume — it is the definition of IDOR.
"No one would think to try that"Attackers do this full-time and share notes.
"It's validated on the client"Client validation is UX. The server is the boundary.
"That endpoint is old, nobody uses it"Unused, reachable, and unmaintained is the ideal target.
"The framework probably handles it"Probably is not a control. Read the config and confirm.

Dismissing a finding is a decision with the same weight as raising one — it needs the same evidence.

Step 3 — Report

Write security-review.md in the task folder (bootstrap per §1), ranked by severity:

# Security review — <target> · <date>
### Coverage — entry points reviewed (file:line), and for each checklist item the read or
                search that cleared it (absence claims show their searches, §5.2)
### Critical  — exploitable now: <boundary violated> → <impact> → <fix>
### High      — exploitable given a verified precondition / sensitive-data exposure
### Medium    — defense-in-depth gaps
### Info      — hardening suggestions

Every finding carries its evidence: a source-to-sink trace (where untrusted input enters, file:line, through each step, to the dangerous operation, file:line) and its reachability, verified (the route, the auth guard or its absence, the signup config, cited). That is enough to rank it: harden reads and does not attack, so a traced, reachable hole is ranked by the table above even though nothing was fired. A path with a step you could not trace is labelled a hypothesis, and says which step is missing; unverified reachability takes the lower rank, labelled unconfirmed. A committed secret is ranked by what it grants, never "reproduced" by using it: when the grants cannot be confirmed without using it, rank by what its name and location indicate (a key in prod.env grants production access), labelled unconfirmed, and let the user confirm.

Calibrate severity by reachability × impact, not by how alarming the category sounds. When the two columns point at different rows (reachable by anyone, but the impact reads like the High row), take the more severe row and say which column set it:

RankWho can reach itWhat they get
Criticalanonymous, or any self-registered userauth bypass · RCE · another tenant's data · money movement · mass data exposure
Highauthenticated, or a precondition shown to holda single user's sensitive data · privilege escalation within a tenant · destructive action
Mediumneeds an unlikely chain, or is a missing layer behind a working controldefense-in-depth gap · information leak that aids a bigger attack
Infonot reachable todayhardening that prevents a future mistake

A category does not set the rank — a hardcoded key in a repo nobody can read is not Critical, and a missing authorization check on one route is not Info.

A finding is valid only with a violated boundary + demonstrated impact + a concrete fix, and each one names which actor reaches it (Step 1) — no speculative "could be risky". Never invent a CVE or a vulnerability — verify and cite, or label it a hypothesis to confirm (§14). No secret is ever written into the report: name the file and line, never the value, and if a live credential is found say so plainly and treat rotation as part of the fix — a leaked secret that was committed is already public to anyone with repo history.

Step 3b — Variant analysis (report the class, not the instance)

Every confirmed finding triggers a hunt: search the whole codebase for the same pattern (same sink, same missing check, same unsafe construct) before closing. One SQL-injection finding usually means several; fixing the instance while its siblings ship is a false sense of security. Report the class with all its locations.

Step 4 — Close the loop

Write security-review.md to disk and confirm it is non-empty (§20.2) before touching the ledger — then record a harden entry in state.json.phases — approved: true on a clean pass that has a Coverage section (no coverage, no pass: a clean result is a set of absence claims, and each needs its search), or waived: true only on the user's explicit acceptance of open findings (§2) — so a resumed run re-proves the security gate instead of trusting it. Critical/High must be fixed (or defensibly, explicitly accepted by the user) before ship. List the findings and let the user choose, per finding: fix now, accept (with its risk recorded in decisions.md), or a follow-up. For a Critical or High, a follow-up still ships the hole, so it is acceptance: say so, and record it only on the user's explicit yes as waived: true, with the risk in decisions.md. A plain follow-up is for Medium and Info. Variant analysis can surface a whole class of siblings; fixing all of them grows the task, so that is the user's call (§4.1, §4.2). Chosen fixes go through construct → verify, and a finding is resolved only on evidence (§5.1), not because the code changed: verify writes and runs a reproduction (a request or failing test) that worked before the fix and fails after it. A leaked secret is resolved by the user confirming it was rotated, and its removal from history is a separate decision.

Composition

  • Consumes: the code/diff/config, security.md, project memory, current advisories (web).
  • Produces: security-review.md; fixes routed to construct/verify.
  • Receives from: engineer (auto-scheduled when a change touches auth, PII, payments, secrets, or a new public surface — a rule, not luck) or a direct user request.
  • Hands off to: construct (fixes), release (blocks ship on unresolved Critical). Distinct from inspect (general code review) and assess (whole-app feature health).

Self-review (author's notes)

  • Mis-routed? engineer routes here when a change touches auth, secrets, payments, or untrusted input; wrong for general quality review (inspect) or app health (assess). Pick this over inspect when the threat model, not the diff, is the question.
  • Single-agent safe? Yes — the checklist runs inline; parallel auditors are optional.
  • Leaks specifics? No — checklist is framework-neutral; findings cite real boundaries.
  • Grounded? CVEs/advisories web-checked with today's date; nothing invented (§14, §17).
Skills guardadas