AgentSkillsCN

vulnerability-remediation-patterns

针对常见漏洞,提供行之有效的防御性修复方案。在发现漏洞后,应采取哪些措施?包括注入攻击的修复、身份认证的强化、权限控制的落实、数据泄露的防范、加密实践的最佳实践,以及修复效果的验证。这一技能不仅补充了 Gabe 的红队知识,更提供了蓝队视角下的应对策略。

SKILL.md
--- frontmatter
name: vulnerability-remediation-patterns
description: >
  Defensive remediation patterns for common vulnerabilities. What to DO after finding
  a vuln: injection fixes, auth hardening, authorization enforcement, data exposure
  prevention, crypto best practices, and fix verification. Complements Gabe's red team
  knowledge with the blue team response.
metadata:
  author: grizzly-gabe
  version: "1.0"
  created: "2026-01-31"

Vulnerability Remediation Patterns

Injection Remediation

SQL Injection

  • Parameterized queries ALWAYS. No exceptions. No string concatenation for SQL.
  • ORM usage preferred -- but verify the ORM parameterizes under the hood (raw queries in ORMs are still vulnerable).
  • Stored procedures: use parameters, not dynamic SQL inside the procedure.
  • If building dynamic column/table names: strict allowlist validation, never user input directly.

Command Injection

  • Avoid shell execution entirely. Rewrite with language-native libraries (file ops, HTTP clients, etc.).
  • If shell is unavoidable: subprocess with array args (['cmd', 'arg1', 'arg2']), NEVER shell=True.
  • Allowlist commands and arguments. Reject anything not on the list.
  • Never pass user input to eval(), exec(), os.system(), or backtick execution.

XSS (Cross-Site Scripting)

  • Output encoding by context -- these are ALL different:
    • HTML body: HTML entity encode (< becomes &lt;)
    • HTML attribute: attribute encode, always quote attribute values
    • JavaScript context: JavaScript encode (hex escape)
    • URL parameter: URL encode
    • CSS value: CSS hex encode
  • CSP headers as defense in depth: default-src 'self', avoid unsafe-inline/unsafe-eval.
  • DOM manipulation: use textContent, NEVER innerHTML with user data.
  • Frameworks with auto-escaping (React, Angular) help but do not prevent dangerouslySetInnerHTML or [innerHTML] bypasses.

Template Injection (SSTI)

  • Never pass user input as the template source. User input goes into template variables, not the template itself.
  • Use logic-less templates (Mustache, Handlebars) where possible.
  • Sandbox template engines. Restrict available functions/objects in template context.

Path Traversal

  • Canonicalize the path first (os.path.realpath, Path.resolve()), THEN verify it starts with the allowed prefix.
  • Never trust user-supplied filenames. Generate filenames server-side, store original name as metadata.
  • Reject paths containing .., null bytes, or encoded variants.

Authentication Fixes

Password Storage

  • bcrypt or argon2id with appropriate work factor. Target 250ms+ hash time.
  • NEVER MD5, SHA-1, or SHA-256 for passwords (fast hashes enable brute force).
  • Use the library's built-in salt generation -- do not roll your own.

Session Management

  • Session IDs: cryptographically random, minimum 128 bits of entropy.
  • Cookie flags: HttpOnly (no JS access), Secure (HTTPS only), SameSite=Lax or Strict.
  • Server-side session expiry. Do not rely only on cookie expiry.
  • Regenerate session ID on login (prevents session fixation).

Token Handling

  • Short-lived access tokens (15 min or less) + refresh token rotation.
  • Store the hash of refresh tokens, not plaintext.
  • Invalidate all tokens on password change.
  • JWTs: validate signature, issuer, audience, and expiry. Reject alg: none.

MFA Implementation

  • TOTP preferred over SMS (SIM swap risk).
  • Backup codes: hash them like passwords. Single-use. Show only once.
  • Rate limit verification attempts (5 attempts, then lockout with backoff).
  • Do not reveal whether MFA is enabled during login flow (information leakage).

Password Reset

  • Constant-time email lookup -- same response time whether account exists or not (prevents enumeration).
  • Time-limited tokens (15-30 min). Single-use.
  • Hash the stored token (if DB is compromised, tokens are useless).
  • Invalidate all existing reset tokens when a new one is issued.

Authorization Fixes

BOLA (Broken Object Level Authorization)

  • Verify ownership at the data layer, not just the route/middleware.
  • Every query that fetches by ID must also filter by the authenticated user's scope.
  • Pattern: SELECT * FROM orders WHERE id = ? AND user_id = ? -- never just WHERE id = ?.

Privilege Escalation

  • Role checks at the function/action level, not just the UI.
  • Server-side enforcement is mandatory. Hiding a button is not access control.
  • Verify role on every request. Do not trust a role claim from the client.
  • Principle of least privilege: default deny, explicitly grant.

Mass Assignment

  • Explicit allowlists for assignable fields. Never pass raw request body to model update.
  • Example: user.update(request.body) is vulnerable. Use user.update(pick(request.body, ['name', 'email'])).
  • Separate DTOs for create vs update if different fields are assignable.

CORS

  • Explicit origin allowlist. Never Access-Control-Allow-Origin: * with credentials.
  • Validate the Origin header server-side against the allowlist.
  • Do not reflect the request origin back as the allowed origin without checking.
  • Restrict allowed methods and headers to what is actually needed.

Data Exposure Fixes

Error Handling

  • Generic messages to users: "Something went wrong. Please try again."
  • Detailed errors server-side only (structured logging with request ID for correlation).
  • Never expose: stack traces, SQL errors, internal file paths, dependency versions.
  • Custom error pages for 4xx/5xx. Framework defaults often leak info.

API Response Shaping

  • Explicit serialization: return only the fields the client needs.
  • Never dump model/ORM objects directly to JSON response.
  • Different serializers for different roles (admin sees more fields than regular user).
  • Paginate list endpoints. Never return unbounded result sets.

Logging Hygiene

  • Scrub before logging: PII, tokens, passwords, credit card numbers.
  • Structured logging with sensitivity tags so automated scrubbing can catch what you miss.
  • Log access events (who accessed what, when) for audit trail.
  • Do not log full request bodies -- they may contain secrets.

Security Headers

  • Strict-Transport-Security: max-age=31536000; includeSubDomains (HSTS)
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY (or SAMEORIGIN if you need iframes)
  • Content-Security-Policy: lock down script/style/image sources
  • Remove Server, X-Powered-By, and other version-disclosing headers.

Cryptography Fixes

Core Rules

  • Use standard libraries (libsodium, OpenSSL, Web Crypto API). Never roll your own.
  • AES-256-GCM for symmetric encryption (authenticated encryption -- integrity + confidentiality).
  • RSA-OAEP (2048+ bit) or ECDH (P-256+) for key exchange.
  • TLS 1.2+ only. Disable TLS 1.0, 1.1, SSLv3.

Key Management

  • Build in key rotation from day one. Hardcoded keys are a ticking time bomb.
  • Secrets in environment variables or a vault (HashiCorp Vault, AWS Secrets Manager).
  • Never commit secrets to version control. Use .gitignore and pre-commit hooks to prevent it.
  • Rotate keys immediately if any suspected compromise.

Common Mistakes

  • Using ECB mode (patterns visible in ciphertext). Use GCM or CBC with HMAC.
  • Reusing IVs/nonces. Every encryption operation needs a unique IV.
  • Comparing hashes with == instead of constant-time comparison (timing attacks).
  • Storing encryption keys next to the encrypted data.

Fix Verification Patterns

How to confirm a fix actually works:

Write the Exploit Test

  • Create a test that reproduces the original vulnerability. It should fail before the fix and pass after.
  • Example: a test that sends ' OR 1=1 -- to the search endpoint and verifies it returns 0 results, not all results.

Test the Bypass

  • Can the fix be circumvented with encoding changes? (%27 instead of ', double encoding, Unicode normalization)
  • Can it be bypassed with case changes, null bytes, or alternate representations?
  • Try the fix with the attacker mindset: "How would I get around this?"

Test Adjacent Functionality

  • Did the fix break legitimate use cases? (Overly aggressive validation rejecting valid input)
  • Test with international characters, long strings, and edge-case valid inputs.

Check for Variants

  • If you found SQLi in /search, check /filter, /export, /report -- same pattern, different endpoint.
  • Grep the codebase for the vulnerable pattern: grep -r "query.*+.*request" or equivalent.
  • Fix the pattern, not just the instance.

Regression Protection

  • Add the exploit test to CI. It must run on every build.
  • If the test suite does not cover this attack vector, the fix WILL regress.

Remediation Anti-Patterns

Patterns that feel like fixes but are not:

  • Blocklist over allowlist: blocking known-bad input (DROP, <script>) instead of allowlisting known-good. Always bypassable with encoding, casing, or novel payloads.
  • Client-side only validation: the server must validate independently. Client validation is UX, not security.
  • Security through obscurity: hiding the admin endpoint at /x7f3admin does not fix missing auth. Assume the attacker knows the URL.
  • Partial fix: fixing the reported instance but not the pattern. If one endpoint was vulnerable, grep for the same pattern everywhere.
  • Over-patching: adding so many validation layers that legitimate usage breaks. Fix precisely -- one correct check at the right boundary.
  • Fix and forget: no regression test means the vulnerability returns in the next refactor. If there is no test, the fix is incomplete.