--- name: foxguard description: Apply foxguard's secure-coding patterns when writing or fixing security-sensitive code. Use proactively when handling user input, shelling out, building SQL, doing file I/O, fetching URLs, generating randomness, or touching crypto. Use when this capability is needed. metadata: author: 0sec-labs --- Use this guidance when writing or fixing code that touches any of these surfaces. Match the language patterns to what foxguard's rules look for so the auto-scan stays clean. ## Command execution - Never pass concatenated strings to a shell. Use argument lists. - Python: `subprocess.run(["git", "log", branch], check=True)` — never `subprocess.run(f"git log {branch}", shell=True)`. - Node: `execFile("git", ["log", branch])` — never `exec(`git log ${branch}`)`. - Go: `exec.Command("git", "log", branch)` — never `exec.Command("sh", "-c", "git log "+branch)`. - If a shell is genuinely required, validate the input against a strict allowlist regex first. ## SQL - Use parameterized queries everywhere. `cursor.execute("SELECT * FROM u WHERE id = ?", (uid,))` — not f-strings or `%`. - ORMs are fine; raw `query.format(...)` / `+` concat is not. ## Path traversal - Resolve and bound paths: `Path(root).resolve() / Path(name).name` — strip directory components from untrusted names. - Reject inputs that contain `..`, absolute paths, or null bytes before joining. ## SSRF - For outbound HTTP from user-supplied URLs: parse the URL, resolve the host, and reject private/loopback/link-local ranges (`10.0.0.0/8`, `127.0.0.0/8`, `169.254.0.0/16`, `172.16.0.0/12`, `192.168.0.0/16`, `::1`, `fc00::/7`, `fe80::/10`) and metadata endpoints (`169.254.169.254`). - Prefer an allowlist over a denylist when the destinations are known. ## Secrets - Read from env / secrets manager, never from string literals. `os.getenv("API_TOKEN")` — not `API_TOKEN = "sk-..."`. - Even in tests, prefer fixtures from env or a vault. High-entropy strings in code will be flagged. - Never log secrets. Redact before logging. ## Randomness - Security-sensitive: `secrets.token_urlsafe`, `crypto.randomBytes`, `OsRng`, `crypto/rand`. Never `random.random()`, `Math.random()`, `rand()`, `math/rand`. - Non-security (jitter, sampling): the fast PRNGs are fine. ## Crypto - New code: AES-GCM or ChaCha20-Poly1305 for symmetric; Ed25519 for signatures; X25519 for key agreement (until PQ rollout). Never DES, 3DES, RC4, MD5, SHA-1. - Asymmetric crypto in long-lived security paths: prefer hybrid suites (X25519+ML-KEM) where the toolchain supports it. Use `/foxguard:pq-audit` to find legacy usage. - Password hashing: argon2id or bcrypt. Never plain SHA-2 or unsalted hashes. ## Deserialization - Never `pickle.load`, `yaml.load` (use `safe_load`), `Marshal.load`, or `unserialize` on untrusted input. - For JSON, deserialize into a typed schema (pydantic, zod, serde) — don't trust the shape. When you finish a fix, the PostToolUse hook will re-scan the file and confirm it's clean. If a finding persists, read the rule's description carefully — the remediation is usually one of the patterns above. --- > Source: [0sec-labs/foxguard](https://github.com/0sec-labs/foxguard) — distributed by [TomeVault](https://tomevault.io).