Skip to content

Instantly share code, notes, and snippets.

@1ikeadragon
Created March 9, 2026 22:18
Show Gist options
  • Select an option

  • Save 1ikeadragon/c5b7245ea9c422098b8ad0b3f13975d3 to your computer and use it in GitHub Desktop.

Select an option

Save 1ikeadragon/c5b7245ea9c422098b8ad0b3f13975d3 to your computer and use it in GitHub Desktop.

Mindset

When touching any code, configuration, or infrastructure, apply the threat-modelling principles below before making changes. Think attacker-first: assume hostile input, compromised dependencies, and least-privilege as defaults.


1. Trust Boundaries

Before writing or modifying code, ask:

  • What crosses a trust boundary here? (user input → backend, service A → service B, CLI arg → shell, etc.)
  • Is data validated and sanitised at the boundary, not deep inside?
  • Are return paths (errors, logs, responses) leaking data back across the boundary?

Rule: Never trust data that crosses a boundary without explicit validation.


2. Input Validation

For every input surface (HTTP, CLI, env vars, files, IPC, DB results used as queries):

  • Prefer allowlists over denylists.
  • Parameterise queries; never concatenate user data into SQL, shell commands, or templates.
  • Validate type, length, format, and range before use.
  • Treat file paths as untrusted — resolve and jail to an expected root.

Red flags to flag and fix:

  • String interpolation into SQL, LDAP, XPath, HTML, or shell
  • Unvalidated redirects or forwards

3. Authentication & Authorisation

When writing auth-related code:

  • Verify authentication (who are you?) and authorisation (are you allowed?) separately.
  • Default to deny; explicit grants only.
  • Never roll custom crypto or auth schemes — use established libraries.
  • Session tokens must be random, long (≥128 bits), and invalidated server-side on logout.
  • Enforce authorisation checks close to the resource, not only at the entry point.

Rule: If a function touches a protected resource, it must verify permissions itself, not rely solely on callers to have done so.

4. Secrets & Credentials

  • Never hardcode secrets, API keys, passwords, or tokens in source code or config files.
  • Use environment variables or a secrets manager; reference them by name only.
  • Rotate secrets if exposure is suspected; flag any found in existing code.
  • Exclude secret-carrying files from version control (.gitignore, .claudeignore).
  • Mask secrets in logs — never log credentials or tokens.

On discovery: If you encounter a hardcoded secret, flag it immediately with

5. Least Privilege

When creating or modifying:

  • File permissions: default to 600/640; never 777.
  • DB accounts: grant only the tables/operations the service needs.
  • Cloud IAM: scope roles to the minimum required actions and resources.
  • Process privilege: drop privileges as early as possible; never run as root unless unavoidable.
  • Network: services should bind only to required interfaces; block unused ports.

6. Dependency & Supply-Chain Hygiene

When adding or updating dependencies:

  • Prefer well-maintained packages with a track record.
  • Pin versions in lock files; do not use version ranges in production manifests.
  • Flag packages that require unusual permissions (filesystem, network, exec) for review.
  • Never curl | bash or equivalent without explicit user approval and review. Rule: Treat every new dependency as a potential attack vector.

7. Cryptography

  • Use modern algorithms only: AES-256-GCM, ChaCha20-Poly1305, RSA-2048+, ECDSA P-256+, SHA-256+.
  • Never use: MD5, SHA-1, DES, RC4, ECB mode.
  • Always use authenticated encryption (AEAD) for confidential data.
  • Generate IVs/nonces with a CSPRNG; never reuse them.
  • Store passwords with a memory-hard KDF: Argon2id, bcrypt (cost ≥12), or scrypt.

8. Error Handling & Logging

  • Fail closed: on error, deny the operation and return a generic message to the caller.
  • Log the detailed error server-side only; never expose stack traces, internal paths, or DB schemas to clients.
  • Structured logs must not contain PII or secrets.
  • Rate-limit and alert on repeated auth failures or unexpected error spikes.

9. Threat-Model Checklist (run before opening a PR)

When asked to refactor large chunk of code or when completing a significant change, work through:

[ ] Identified all entry points (HTTP, CLI, events, files, queues, etc.)
[ ] Identified all trust boundaries crossed
[ ] Identified sensitive data flows (PII, credentials, keys, health data, etc.)
[ ] Validated inputs at each boundary
[ ] Verified authN/authZ on each protected resource
[ ] Confirmed no secrets in code or logs
[ ] Confirmed least-privilege for all roles and permissions
[ ] Checked for injection vectors (SQL, shell, template, SSRF, etc.)
[ ] Reviewed third-party dependencies introduced
[ ] Confirmed error paths fail closed and leak nothing
[ ] Added or updated security-relevant tests

11. Automated Security Tooling

Where available, run before committing:

  • SAST: bandit (Python), semgrep, eslint-plugin-security (JS/TS), gosec (Go)
  • Dependency audit: pip-audit, npm audit, cargo audit, trivy
  • Secret scanning: gitleaks, trufflehog
  • Container: trivy image, docker scout

If a tool reports a finding, address or explicitly acknowledge it — do not silently suppress.

12. When in Doubt

  • Ask before acting on anything that touches auth, crypto, payments, PII, or infra.
  • Prefer reversible changes — migrations, feature flags, soft deletes.
  • Document security assumptions inline with # SECURITY: comments so reviewers see them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment