mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-15 20:05:13 +02:00
feat(tests): support partial confirmations with synthetic-fallback handling in header injection and open redirect scenarios
This commit is contained in:
parent
4c824ed543
commit
c29cf69d42
5 changed files with 80 additions and 41 deletions
|
|
@ -2548,9 +2548,9 @@ pub fn emit_open_redirect_harness(spec: &HarnessSpec) -> HarnessSource {
|
|||
};
|
||||
|
||||
let invoke_via_fixture = if uses_node_writer {
|
||||
"const captured = nyxRedirectViaFixture(payload);\nif (Array.isArray(captured)) {\n const [location, requestHost] = captured;\n nyxRedirectProbe(location, requestHost);\n nyxFollowLocation(location);\n console.log('__NYX_SINK_HIT__');\n console.log(JSON.stringify({ location: location, request_host: requestHost }));\n} else {\n // Synthetic fallback — fixture import / call failed.\n const requestHost = 'example.com';\n const location = payload;\n nyxRedirectProbe(location, requestHost);\n nyxFollowLocation(location);\n console.log('__NYX_SINK_HIT__');\n console.log(JSON.stringify({ location: location, request_host: requestHost }));\n}\n"
|
||||
"const captured = nyxRedirectViaFixture(payload);\nif (Array.isArray(captured)) {\n const [location, requestHost] = captured;\n nyxRedirectProbe(location, requestHost);\n nyxFollowLocation(location);\n console.log('__NYX_SINK_HIT__');\n console.log(JSON.stringify({ location: location, request_host: requestHost }));\n} else {\n // Synthetic fallback — fixture import / call failed. The real redirect\n // surface (host allowlist / path guard) never ran, so the synthetic marker\n // routes the runner to PartiallyConfirmed instead of an OOB self-confirm.\n const requestHost = 'example.com';\n const location = payload;\n nyxRedirectProbe(location, requestHost);\n nyxFollowLocation(location);\n console.log('__NYX_SINK_HIT__');\n console.log('__NYX_SYNTHETIC_FALLBACK__');\n console.log(JSON.stringify({ location: location, request_host: requestHost }));\n}\n"
|
||||
} else {
|
||||
"const requestHost = 'example.com';\nconst location = payload;\nnyxRedirectProbe(location, requestHost);\nnyxFollowLocation(location);\nconsole.log('__NYX_SINK_HIT__');\nconsole.log(JSON.stringify({ location: location, request_host: requestHost }));\n"
|
||||
"const requestHost = 'example.com';\nconst location = payload;\nnyxRedirectProbe(location, requestHost);\nnyxFollowLocation(location);\nconsole.log('__NYX_SINK_HIT__');\nconsole.log('__NYX_SYNTHETIC_FALLBACK__');\nconsole.log(JSON.stringify({ location: location, request_host: requestHost }));\n"
|
||||
};
|
||||
|
||||
let body = format!(
|
||||
|
|
@ -2784,6 +2784,11 @@ const payload = process.env.NYX_PAYLOAD || '';
|
|||
// lodash.merge can throw on weird inputs; the canary observation
|
||||
// already wrote any probe before the throw.
|
||||
}
|
||||
// This block drove the sink DIRECTLY, bypassing any caller-side mitigation
|
||||
// (the fixture's own entry could not be driven). A canary observation here
|
||||
// therefore does not prove the guarded code is exploitable, so the runner
|
||||
// must downgrade to PartiallyConfirmed rather than Confirm.
|
||||
console.log('__NYX_SYNTHETIC_FALLBACK__');
|
||||
"#;
|
||||
|
||||
let tail = r#"console.log('__NYX_SINK_HIT__');
|
||||
|
|
|
|||
|
|
@ -3456,6 +3456,9 @@ def _nyx_header_probe(name, value):
|
|||
value = payload
|
||||
_nyx_header_probe(name, value)
|
||||
print("__NYX_SINK_HIT__", flush=True)
|
||||
# Synthetic sink: the real header surface (and its guards) never ran, so
|
||||
# the runner downgrades this to PartiallyConfirmed rather than Confirm.
|
||||
print("__NYX_SYNTHETIC_FALLBACK__", flush=True)
|
||||
sys.stdout.write(json.dumps({{"name": name, "value": value}}) + "\n")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
|
@ -3607,6 +3610,10 @@ def _nyx_follow_location(location):
|
|||
_nyx_redirect_probe(location, request_host)
|
||||
_nyx_follow_location(location)
|
||||
print("__NYX_SINK_HIT__", flush=True)
|
||||
# Synthetic sink: the real redirect surface (host allowlist / path guard)
|
||||
# never ran, so the runner downgrades to PartiallyConfirmed rather than an
|
||||
# OOB self-confirm.
|
||||
print("__NYX_SYNTHETIC_FALLBACK__", flush=True)
|
||||
sys.stdout.write(json.dumps({{"location": location, "request_host": request_host}}) + "\n")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue