Secure Web App Coding
Turns OWASP Top 10:2025, ASVS 5.0, the Cheat Sheet Series, and selected WSTG material into practical web-app security guidance.
Default (inline): write secure code quietly; flag only the highest-impact issue you see nearby.
Audit: on "review", "audit", "harden", "is this secure?", or incident follow-up — read assets/audit-checklist.md and produce prioritized findings.
Modes, invoked as $secure-webapp <mode>:
$secure-webapp audit: full prioritized review; readassets/audit-checklist.md.$secure-webapp quick-check: highest-risk pass only — authorization, auth/session, secrets, injection/XSS, uploads, SSRF, tokens. No full checklist report.$secure-webapp harden: apply secure changes directly where edits are authorized; small patches that preserve the architecture; verify, and flag anything needing product approval.$secure-webapp remediate: iterative audit→fix loop; readassets/remediate-checklist.mdin full first.$secure-webapp design-review: pre-implementation threat model — assumptions, trust boundaries, abuse cases, must-have controls, unresolved questions.$secure-webapp report: write a formal report todocs/security-audit-report-YYYY-MM-DD.md; readassets/report-template.mdin full first and follow every step. Requires a prior audit this session. Write to the file, never into the chat.$secure-webapp update: self-update this install by runningnpx --yes github:hov172/secure-webapp-skill --global. It version-checks and only reinstalls when a newer release exists. Flags:--claude/--codex/--gemini,--check,--force.$secure-webapp maintain: update the skill package itself, from a clone of the source repository — seescripts/README.md.
Load only the references the task needs. Never bulk-load them all.
Routing
| Task involves | Load |
|---|---|
| Untrusted strings interpreted as HTML/DOM/SQL/shell/NoSQL/LDAP/regex/CSV | references/input-handling.md |
| Login, signup, passwords, MFA, reset, brute force, sessions, cookies, logout | references/auth-and-sessions.md |
| Permissions, roles, ownership checks, IDOR, tenant isolation | references/authorization.md |
| JWTs, API/refresh tokens, signing and verification, OAuth/OIDC, PKCE, state | references/tokens-and-oauth.md |
| REST/GraphQL/WebSocket endpoints, rate limits, mass assignment, response shape, uploads/downloads, path traversal, pre-signed URLs | references/apis-and-files.md |
| Secure/HttpOnly/SameSite, CSP, CORS, CSRF, headers, iframes, postMessage | references/frontend-and-headers.md |
Env vars, .env, keys, secrets manager, debug mode, defaults | references/secrets-and-config.md |
| Encryption, password hashing, algorithms, key management, PII | references/data-and-crypto.md |
| Dependencies, lockfiles, SBOM, CI/CD, GitHub Actions, signed artifacts | references/supply-chain.md |
| User-controlled external URLs, SSRF, race conditions, deserialization, prototype pollution | references/secure-coding.md |
| Logging, error responses, stack traces, audit trails, fail-closed, rollback | references/logging-and-errors.md |
| New feature design, threat modeling, multi-tenancy, secure-by-design decisions | references/insecure-design.md |
| LLM/AI features, prompt construction, RAG, agent tool calls, MCP servers, model output rendered or executed | references/ai-and-llm.md |
Always-On Watchlist
Flag these in passing when seen in web code, with one concrete fix:
- Missing server-side auth/ownership checks on resource routes. Prefer query-level scoping such as
WHERE owner_id = :current_user. - Hardcoded secrets, credentials, JWT secrets, API keys, or committed
.envfiles. - String-built SQL/NoSQL/shell queries. Use parameterized queries, safe builders, or argv APIs.
- Plaintext or fast-hashed passwords. Use argon2id, scrypt, or bcrypt; PBKDF2 only where required.
- JWT verification with unpinned algorithms, missing
exp/iss/audchecks, or secrets in code. dangerouslySetInnerHTML,v-html, orinnerHTMLwith user content. Render as text or sanitize.- Credentialed CORS with wildcard or echoed origins. Use a strict allowlist.
- Missing rate limits on login, signup, reset, MFA/OTP, or expensive endpoints.
- Verbose production errors, stack traces, SQL/ORM details, or debug mode exposed to clients.
- Open redirects from unvalidated
next,returnTo, or URL parameters. - SSRF from user-supplied URLs without allowlists and private-IP blocking after DNS and redirects.
- Logs containing passwords, tokens, session IDs, secrets, or unnecessary PII.
- Client-only security controls: hidden fields, disabled buttons, client role claims, frontend-only validation.
- File uploads without size, type, path, storage, or generated-name controls.
- Fail-open exception paths around auth, authorization, rate limits, feature flags, or transactions.
- Non-atomic balance, quota, payment, inventory, coupon, or one-time-token state changes.
- Model/LLM output reaching a sink unchecked —
innerHTML, shell, SQL, file paths,fetchURLs, or a downstream agent. Treat it as untrusted input. - Agent tool calls authorized against the service account rather than the end user, or generic
run_shell/execute_sql/http_requesttools that turn prompt injection into RCE, SQLi, or SSRF. - Untrusted text concatenated into a system prompt; secrets or other users' data in the model context.
- Mutable dependency or CI-action references where pinning and lockfiles are expected — a moved tag runs attacker code in that job with that job's secrets. Rate High when the job holds deploy credentials, signing keys, or publish rights; same for long-lived cloud credentials where OIDC exists. Audit every workspace in a monorepo, and flag an
--audit-levelweaker thanhigh.
Behavior
- Write secure code by default, without long explanations. Name security-relevant choices briefly when useful.
- Match rigor to the app's stakes; do not force enterprise controls into throwaway prototypes.
- Never generate intentionally insecure code. Offer the safe equivalent and state the constraint in one sentence.
- For new trust-boundary features, check: untrusted input, authorization, failure mode, stored data, abuse path.
- When auditing, inspect real code, ask only essential scoping questions, and report severity + location + evidence + fix, prioritized.
- Do not cite OWASP requirement numbers unless asked.
- Do not claim to perform penetration testing; this is code and design review.
Scope
Mainstream web stacks — Next.js, Express, Django, Flask, FastAPI, Rails, Spring, Laravel, Go, and similar. For niche areas the references do not cover, say so and point at the relevant OWASP source rather than guessing.
Agent-agnostic: works in Claude Code, Codex, Gemini CLI, and anything else that loads skills or reads AGENTS.md/GEMINI.md. Where this file names a tool, use your environment's equivalent.