Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions backend-security/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "backend-security",
"displayName": "Backend Security",
"version": "0.2.0",
"description": "Defensive backend security for Claude Code: full-codebase audits, dependency and config scanning, secure-coding guidance while you write, and a phased zero-to-hardened roadmap. Stack-aware with a Node/TS deep-dive; anchored to OWASP Top 10 2021, ASVS 4.0, and CWE.",
"author": {
"name": "Ghostfreak-cypher",
"url": "https://github.com/Ghostfreak-cypher"
},
"homepage": "https://github.com/Ghostfreak-cypher/backend-security-skill",
"repository": "https://github.com/Ghostfreak-cypher/backend-security-skill",
"license": "MIT",
"keywords": [
"security",
"appsec",
"owasp",
"asvs",
"audit",
"backend",
"api",
"vulnerability",
"code-review",
"hardening"
]
}
117 changes: 117 additions & 0 deletions backend-security/skills/backend-security/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
name: backend-security
description: Backend security audit, dependency/config scanning, and secure-coding guidance. Use when the user asks for a security audit or review of a backend, API, or server codebase, asks "is this secure" or "find vulnerabilities", wants dependencies, Dockerfiles, or CI configs scanned for security issues, or when writing or modifying backend authentication, authorization, API endpoints, database queries, file uploads, or secrets handling.
---

# Backend Security

You are performing defensive security work: finding and fixing vulnerabilities in code the user owns. Be precise, evidence-driven, and allergic to false positives — a report padded with speculative findings destroys trust.

## Pick a mode from how you were invoked

- **Audit** — "audit this backend", "find vulnerabilities", "security review the codebase" → run the full workflow below.
- **Scan** — "scan dependencies", "check the Docker/CI config" → run only Step 4.
- **Guide** — you are writing or modifying backend code (endpoints, auth, queries, uploads) → do not produce a report; build the code securely by following the relevant reference files, and briefly note the security decisions you made (e.g. "parameterized the query; added ownership check on the lookup").
- **Harden** — "secure this backend from scratch", "make this production-ready", "take this to enterprise grade" → read `references/roadmap.md` and run the phased zero→hardened engagement. Report phase-by-phase status against its ASVS exit criteria instead of the flat findings table. Use this when the goal is *building up* a baseline, not just *finding* what's broken.

Before anything else, read **Scope & limits** at the bottom of this file so you set honest expectations — this skill is one strong pillar of security, not a substitute for a professional audit, pentest, or compliance program.

## Step 1: Detect the stack

Check for manifests at the repo root (and in service subdirectories for monorepos):

| Manifest | Stack | Extra reference to read |
|---|---|---|
| `package.json` | Node.js / TypeScript | `references/nodejs.md` (always read for Node) |
| `requirements.txt`, `pyproject.toml`, `Pipfile` | Python | — |
| `go.mod` | Go | — |
| `pom.xml`, `build.gradle` | Java / Kotlin | — |
| `composer.json` | PHP | — |
| `Gemfile` | Ruby | — |
| `*.csproj` | .NET | — |

The general reference files apply to every stack; translate the grep patterns and idioms to the detected language. If multiple stacks exist (e.g. Node API + Python worker), cover each.

## Step 2: Map the attack surface (Audit mode)

Do not review file-by-file. Review **data flow: untrusted input → dangerous sink**. First build a map of:

1. **Entry points** — routes, controllers, GraphQL resolvers, webhook handlers, message consumers, cron jobs that read external data.
2. **The auth boundary** — which middleware/decorator enforces authentication, and which routes bypass it (intentionally or not).
3. **Sinks** — DB queries, shell/process execution, file reads/writes, outbound HTTP, template rendering, deserialization.
4. **Trust decisions** — every place the code reads a user id, role, tenant, or price/amount: does it come from the session/token (trusted) or from the request body/params (attacker-controlled)?

## Step 3: Domain review (Audit mode)

Read each reference file and hunt for its checks against the map from Step 2. Each file opens with **Coverage anchors** mapping its checks to OWASP Top 10 2021, ASVS 4.0, and CWE — cite these in findings so coverage is auditable:

1. `references/injection.md` — injection classes, SSRF, traversal, deserialization, uploads, open redirect
2. `references/auth.md` — authentication, password policy, sessions, JWT, access control, IDOR
3. `references/infra.md` — secrets, config, CORS, headers, rate limiting, TLS, data-at-rest, Docker, CI
4. `references/nodejs.md` — only when the stack is Node.js/TypeScript
5. `references/roadmap.md` — only in **Harden** mode (phased build-up, not a findings pass)

## Step 4: Dependency & config scan

Read `references/deps.md` and follow it: run the ecosystem's audit tool, check lockfile hygiene, and review Dockerfile/CI/env handling.

## Step 5: Verify before reporting

For every candidate finding:
- **Trace it**: confirm attacker-controlled data actually reaches the sink. Name the path (e.g. `req.query.path` → `resolveFile()` → `fs.readFile`).
- **Check reachability**: is the endpoint exposed? Behind auth? Dead code?
- **Check existing mitigations**: framework auto-escaping, ORM parameterization, validation middleware upstream. If mitigated, drop it or downgrade to hardening advice.
- If you cannot confirm exploitability but the pattern is dangerous, report it honestly as "needs verification" — never present speculation as fact.

## Severity rubric

- **Critical** — exploitable pre-auth with severe impact: SQL injection on a public endpoint, auth bypass, RCE, live production credentials committed to the repo.
- **High** — exploitable by an authenticated user or under realistic conditions: IDOR, weak/hardcoded JWT secret, stored XSS, SSRF to internal services.
- **Medium** — requires chaining or unusual conditions, or a meaningful hardening gap: missing rate limit on login, CORS reflecting Origin with credentials, verbose stack traces to clients.
- **Low** — defense-in-depth: missing security headers, missing cookie flags on non-sensitive cookies, outdated dep with no known reachable vuln.

## Report format (Audit and Scan modes)

```markdown
# Security Review — <repo/service name> (<date>)

**Scope:** <what was reviewed> · **Not reviewed:** <what was out of scope and why>

| # | Severity | Finding | Location |
|---|----------|---------|----------|

## Findings

### [SEC-1] <Title> — <Severity>
- **Location:** `path/file.ts:42`
- **Evidence:** <the vulnerable code and the input→sink path>
- **Impact:** <what an attacker gains, concretely>
- **Fix:** <ready-to-apply code>

## Hardening recommendations
<Low-severity / defense-in-depth items, briefly>
```

Finding nothing in a domain is a valid result — say "reviewed, no issues found", never invent findings to fill severity levels.

## Rules

- **Never apply fixes without approval.** Propose fix code in the report; edit files only after the user says to. Never commit.
- Every finding gets a `file:line` reference and real evidence from the code.
- Prefer fixing code over adding dependencies; suggest new security libraries only when hand-rolling would be worse (e.g. crypto, rate limiting).
- State clearly what you did **not** review (infrastructure you can't see, runtime config, third-party services).
- If the codebase is large, tell the user your prioritization (auth + payment + upload paths first) rather than silently sampling.

## Scope & limits

State these plainly to the user — overclaiming is the fastest way to give false confidence. This skill covers **one pillar** of security: the application code and repo-visible configuration.

**What it does well:** systematic source-level review of the vulnerability classes in the reference files, data-flow reasoning to cut false positives, live dependency scanning (delegated to `npm audit` / `pip-audit` / `osv-scanner` / `govulncheck`, so CVE data is always current), and a phased path to a strong ASVS L1–L2 application baseline.

**What it is not, and cannot replace:**
- **Not a SAST/DAST tool.** It is LLM-guided review: thorough but not exhaustive or provable. It does no runtime testing, fuzzing, or exploitation. On large codebases it prioritizes rather than covering every line — say so.
- **Not infrastructure or operations security.** It sees only what's in the repo — not your cloud IAM, network segmentation, WAF, secrets manager, or running config. It cannot set up monitoring, alerting, or 24/7 incident response.
- **Not a compliance or certification exercise.** It does not produce SOC 2 / ISO 27001 / PCI evidence, and it is **not a substitute for a professional penetration test or human security audit** before you stake real user data or money on it.
- **Static knowledge ages.** Library-specific advice reflects the author's knowledge cutoff; treat version-specific notes as prompts to verify against current advisories, not gospel.

The honest bottom line: this skill makes a backend meaningfully more secure and can build a solid baseline from zero — but "all checks pass" means *the application-layer baseline is strong*, not *this system is enterprise-certified secure*. Recommend a professional pentest and infra/ops review before high-stakes launch.
62 changes: 62 additions & 0 deletions backend-security/skills/backend-security/references/auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Authentication & Access Control

**Coverage anchors** — OWASP Top 10 2021: A01 Broken Access Control, A07 Identification & Authentication Failures, A04 Insecure Design. ASVS 4.0: V2 (Authentication), V3 (Session Management), V4 (Access Control). CWE: 287, 862, 863, 639, 384, 613, 307, 522, 620.

Two questions dominate this domain: **who are you** (authn) and **what may you touch** (authz). Broken object-level authorization (IDOR) is the single most common real-world backend vulnerability — check it on every route that takes an ID.

## Password storage

- **Require:** bcrypt (cost ≥ 10), argon2id, or scrypt. Flag: MD5, SHA-1, unsalted/plain SHA-256, plaintext, reversible encryption, home-rolled hashing.
- Hash comparison must be the library's verify function, not `==` on hashes.
- Hunt: `md5(`, `sha1(`, `createHash('sha256').update(password`, `hashlib.md5`, columns named `password` populated without a hash call.

## Password policy

- **Minimum length** enforced server-side (≥8, prefer ≥12). Flag validation that accepts trivially short passwords — e.g. a regex like `/^.{1,20}$/` sets only a *maximum* and permits a 1-character password.
- Reject known-breached / top-common passwords (e.g. a HaveIBeenPwned range check or a common-password list). Don't impose arbitrary composition rules that push users toward predictable patterns (`Password1!`).
- No low upper bound that forces truncation; bcrypt's 72-byte limit should be handled, not worked around by capping user length short.
- Hunt: signup/reset validators (`PASS_RE`, `password.length`, joi/zod `.min()`/`.max()` on password) — confirm a real minimum exists and is applied on **both** registration and password-change/reset paths.

## JWT

- **`decode` vs `verify`:** `jwt.decode()` (Node `jsonwebtoken`, PyJWT with `verify=False`/no key) does NOT check the signature. Any token trusted after mere decoding is a full auth bypass. Hunt: `jwt.decode(` and confirm a separate `verify` guards the trust decision.
- **Algorithm confusion:** verification must pin an algorithm allowlist (`algorithms: ['RS256']`). Accepting `none`, or verifying RS256 tokens with the public key as an HMAC secret (HS256 confusion), is a bypass.
- **Secret strength:** HMAC secrets must be long random values from env/secret store — flag short/dictionary strings, secrets committed to the repo, the same secret across environments.
- **Claims:** enforce `exp` (and reasonable lifetime), validate `iss`/`aud` in multi-service setups. Don't put authorization data the user can pick (role from a request) into the token.
- **Revocation:** long-lived tokens with no revocation path (logout, password change, ban) — flag as High for sensitive apps. Refresh tokens: stored hashed, rotated on use, revocable.

## Sessions & cookies

- Session cookies: `HttpOnly`, `Secure`, `SameSite=Lax` or `Strict`. Session ID regenerated on login (fixation) and invalidated server-side on logout.
- Absolute + idle expiry for sensitive apps. Session data server-side; if using signed cookie sessions, nothing sensitive inside and strong signing key.
- CSRF: if auth is cookie-based, state-changing routes need CSRF protection (token or strict SameSite + custom-header check). Pure Bearer-token APIs are exempt.

## Login flow

- **Rate limiting / lockout** on login, password reset, OTP verification — per-account and per-IP. Missing = Medium minimum.
- **User enumeration:** identical errors and similar timing for "no such user" vs "wrong password"; registration and reset flows shouldn't reveal whether an email exists.
- **Timing-safe comparison** for tokens, API keys, OTPs: `crypto.timingSafeEqual`, `hmac.compare_digest` — flag `==`/`===` on secret values.

## Password reset

- Token: ≥128 bits from a CSPRNG (not `Math.random`, not a timestamp/user-id hash), stored hashed, single-use, short expiry (≤1h).
- Sessions invalidated on password change. Reset link host not built from the request's `Host` header (host-header injection → token theft).

## Access control (authorization)

- **Every route:** identify the authn middleware chain; list routes that skip it and confirm each is intentionally public. Watch for routers mounted before auth middleware and "temporary" debug endpoints.
- **IDOR / object-level:** every fetch/update/delete by ID from the request must scope to the caller: `findOne({ id, userId: session.userId })` or an explicit ownership/tenant check after fetch. Hunt: `findById(req.params`, `get_object_or_404(Model, pk=` with no owner filter. Sequential integer IDs make it trivially exploitable — but UUIDs are NOT authorization.
- **Function-level:** admin routes need a server-side role check, not just hidden UI. Role must come from the session/DB, never from the request body or a client-editable JWT claim.
- **Privilege escalation via mass assignment:** can a profile-update endpoint set `role`/`isAdmin`? (see injection.md).
- **Multi-tenancy:** tenant ID from the authenticated context, never from a request parameter; ideally enforced centrally (scoped query helpers, RLS) rather than per-query discipline.

## OAuth / SSO

- `redirect_uri` validated by exact match against a registration (not prefix/substring). `state` parameter required and verified (CSRF). PKCE for public clients.
- Account linking by email: only trust `email_verified`; otherwise pre-registration account takeover.
- ID token: verify signature, `aud`, `iss`, `nonce`.

## API keys & machine auth

- Stored hashed server-side (they're passwords). Timing-safe comparison. Scoped and revocable, prefixed (`sk_live_`) so leaks are greppable.
- Internal service-to-service endpoints: confirm they're not reachable from the public edge with no auth ("the gateway handles it" — verify).
51 changes: 51 additions & 0 deletions backend-security/skills/backend-security/references/deps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Dependency & Supply-Chain Scan

**Coverage anchors** — OWASP Top 10 2021: A06 Vulnerable & Outdated Components, A08 Software & Data Integrity Failures. ASVS 4.0: V14.2 (Dependency management). CWE: 1104, 1035, 937.

## 1. Run the ecosystem's audit tool

Use what the repo's lockfile implies. Run read-only audits; never auto-run `... audit fix` without approval.

| Ecosystem | Command | Notes |
|---|---|---|
| npm | `npm audit` | `--omit=dev` to focus on runtime deps; JSON via `--json` |
| pnpm | `pnpm audit` | |
| yarn | `yarn npm audit` (berry) / `yarn audit` (v1) | |
| Python | `pip-audit` | falls back: `pip install pip-audit`; or `osv-scanner` |
| Go | `govulncheck ./...` | call-graph aware — its results are reachability-filtered already |
| Java | `mvn org.owasp:dependency-check-maven:check` or Gradle equivalent | slow; osv-scanner is a faster first pass |
| Ruby | `bundle audit` (bundler-audit) | |
| PHP | `composer audit` | |
| .NET | `dotnet list package --vulnerable --include-transitive` | |
| Any / monorepo | `osv-scanner -r .` | good universal fallback if installed |

If a tool isn't installed, say so and offer the install command — don't silently skip the step.

## 2. Triage the results (don't just paste the output)

For each reported vulnerability, assess and report:
- **Reachability:** is the vulnerable function actually used? A prototype-pollution advisory in a build-time-only dep is Low; the same in the request path is High.
- **Direct vs transitive:** direct → upgrade the dep; transitive → upgrade the parent, or use `overrides` (npm) / `resolutions` (yarn) / constraints as a stopgap and note it's a stopgap.
- **Runtime vs dev dependency:** dev-only advisories rarely matter in production (but do matter in CI supply-chain terms).
- Group by the fix action ("upgrade express to 4.19.2 clears 3 advisories") rather than listing CVEs one by one.

## 3. Lockfile & manifest hygiene

- Lockfile committed and in sync with the manifest (unlocked deps = non-reproducible, drift-prone builds).
- No dependencies from raw URLs, `git+http://`, or personal forks without a pinned commit.
- Version ranges on security-critical libs (auth, crypto, session, ORM): wide ranges (`*`, `>=`) are a flag.
- Deprecated/unmaintained security-critical packages (e.g. abandoned auth middleware) — recommend maintained replacements.

## 4. Supply-chain checks

- **Install scripts (npm):** `postinstall` hooks are the main attack vector — for unfamiliar deps, check what their scripts do; recommend `--ignore-scripts` for CI installs where feasible.
- **Typosquatting:** hand-typed package names close to popular ones; very new packages with few downloads pulled into production code.
- **CI actions/plugins:** third-party GitHub Actions pinned to a SHA, not a movable tag, on repos holding secrets.
- **Base images:** pinned tags or digests, not `latest`; if trivy/`docker scout` is available, offer an image scan — don't install scanners unprompted.

## 5. Config files that ride along

While in scan mode, also check (details in infra.md):
- `Dockerfile` / `docker-compose.yml` — root user, baked secrets, `.dockerignore`
- CI workflow files — secret exposure, fork-triggered workflows, unpinned actions
- `.env*` — gitignored, never committed historically (`git log --all --oneline -- .env`), no `.env.production` with real values in the repo
Loading