skills/security-and-hardening/SKILL.md
Use when handling user input, authentication, data storage, or external integrations. Use when building any feature that accepts untrusted data, manages user sessions, or interacts with third-party services.
npx skillsauth add paulund/skills security-and-hardeningInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Threat model first — before writing security controls, spend 5 minutes thinking like an attacker:
Apply always-do controls — no exceptions:
httpOnly, secure, sameSite cookies for sessionsnpm audit (or equivalent) before every releaseAuthorisation on every endpoint — authentication ≠ authorisation. Check that the authenticated user owns the resource being acted upon.
Secrets management — .env.example committed (no real values), .env gitignored. If a secret is ever committed: rotate it immediately, then purge from history.
Rate limit authentication endpoints — minimum 10 attempts per 15-minute window. Stricter for sensitive actions.
SSRF prevention — when the server fetches a URL influenced by user input: allowlist scheme + host, resolve DNS and reject private/reserved IPs, forbid redirects.
LLM/AI features — if the app calls a language model:
eval, SQL, shell, innerHTML, or file paths| Rationalization | Reality | |---|---| | "This is an internal tool, security doesn't matter" | Internal tools get compromised. Attackers target the weakest link. | | "We'll add security later" | Security retrofitting is 10× harder than building it in from the start. | | "The framework handles security" | Frameworks provide tools, not guarantees. You still need to use them correctly. | | "It's just a prototype" | Prototypes become production. Security habits from day one. | | "Threat modelling is overkill here" | Five minutes of "how would I attack this?" prevents design flaws no control can patch later. | | "It's just LLM output, it's only text" | That text can be a SQL statement, a script tag, or a shell command. Treat it like any untrusted input. |
eval without validationAfter implementing security-relevant code:
npm audit shows no critical or high vulnerabilitieslocalStorage.eval() or innerHTML with user-provided data..env files or API keys.| Topic | Reference | Load When | |-------|-----------|----------| | Security Checklist | references/security-checklist.md | Implementing auth, input validation, security headers, CORS, or any LLM-facing feature |
development
Use when implementing any logic, fixing any bug, or changing any behaviour. Use when you need to prove code works, when a bug report arrives, or when modifying existing functionality. Do NOT use for config changes, data migrations, or dependency updates.
development
Use when starting a new feature, when requirements are unclear, when asked to write code without a clear spec, or before any non-trivial implementation. Do NOT use for trivial bug fixes or one-line changes.
development
Use when you want authoritative, source-cited code free from outdated patterns. Use when building with any framework or library where correctness matters. Detects the stack from dependency files, fetches official documentation, implements following documented patterns, and cites sources for every framework-specific decision.
development
Use when preparing to ship a feature, release, or deployment. Use before merging to main, creating a release, or deploying to production. Do NOT use for CI-only changes or internal refactors that don't reach production.