diff --git a/src/openultrasast/search/oracles.py b/src/openultrasast/search/oracles.py index 61c7e07..72aca91 100644 --- a/src/openultrasast/search/oracles.py +++ b/src/openultrasast/search/oracles.py @@ -92,6 +92,10 @@ class PathOracle(OutputOracle): (canary.root / "public").mkdir() (canary.root / "canary").write_text(canary.nonce) (canary.root / "canary").chmod(0o600) + # Parent canary covers classic traversal; this sibling covers prefix checks + # using startswith without a separator. + (canary.root / "public_leak").write_text(canary.nonce) + (canary.root / "public_leak").chmod(0o600) # A benign in-root control file, distinct from the out-of-root secret, so a # correctly serving app returns it on BOTH revisions without any traversal. # Drawn from os.urandom, not secrets.token_hex, so it never perturbs callers diff --git a/src/openultrasast/search/worker.py b/src/openultrasast/search/worker.py index 3b32c45..682742a 100644 --- a/src/openultrasast/search/worker.py +++ b/src/openultrasast/search/worker.py @@ -102,9 +102,10 @@ ORACLE_GUIDE = ( "Explore reachability/disclosure using app code/own sandbox data; demos target below. " "Only differential verification across revisions proves it. " "Path observes app output for private nonce file canary in ${served_root}'s parent. " - "MUST set the app's served/root to exactly the ${served_root} placeholder via its command-line argument " - "(e.g. --dir ${served_root}), environment variable or config in start.files. " - "It lives relative to ${served_root}; serving elsewhere makes it unreachable: the search cannot succeed. " + "Prefix-sibling nonce file public_leak beside public extends the served name: reachable with startswith WITHOUT " + "a trailing separator until the fix adds one. " + "Target the code's vector: classic parent traversal or prefix-bypass. " + "MUST serve ${served_root} via CLI, environment or start.files. " "SQL observes secret rows in ${database_path} (${database_url} is its SQLite URL). " "Command observes marker creation at marker location ${marker_dir}/marker. " "SSRF observes the nonce URL at its loopback listener ${callback_url}. "