parlov docs

Existence Oracle

An existence oracle is any observable behavior difference in a server's response that reveals whether a protected resource exists — without requiring access to the resource itself.

Implemented

An existence oracle is any observable behavior difference in a server's response that reveals whether a protected resource exists — without requiring access to the resource itself. The server isn't exploited. It isn't misconfigured. It behaves correctly, and that correct behavior leaks internal state.

HTTP servers that faithfully implement RFC 9110 semantics produce deterministic responses to well-formed requests. When those responses differ based on whether a resource identifier resolves internally — a 403 instead of a 404, a cache hit instead of a miss, a validation error instead of a not-found — the difference itself is the oracle. The attacker doesn't need to read the resource. They only need to observe that the server treated it differently.


Why It Matters

Existence oracles are the first step in nearly every targeted attack chain:

  • Account enumeration — confirming which email addresses or usernames are registered before credential stuffing or phishing campaigns
  • Hidden resource discovery — mapping internal API endpoints, admin panels, or feature-flagged routes that weren't meant to be visible
  • Resource ID harvesting — enumerating valid object IDs (user IDs, document IDs, order numbers) to feed into IDOR attacks
  • Pre-attack reconnaissance — building a target inventory without triggering access-control alarms, since every probe uses legitimate HTTP semantics
  • Deleted resource confirmation — verifying whether data was truly purged or whether tombstone records persist (regulatory and compliance implications)

The danger isn't the oracle alone — it's what comes next. Existence confirmation converts a blind attack surface into a known one.


Vectors

Existence oracles are organized by the type of signal used to detect the differential. parlov implements three detection vectors. Each exploits a different aspect of RFC-compliant server behavior.

Vectors define what to observe. Strategies define what to send. The analysis pipeline runs all vectors against every probe pair regardless of which strategy generated it — a probe designed for status code diff may also surface cache probing signals from the same response.

Status Code Differential

The server returns different HTTP status codes for existing vs. nonexistent resources on the same endpoint. This is the most common and most exploitable vector.

A 403 Forbidden (baseline) vs. 404 Not Found (probe) directly confirms existence. A 410 Gone vs. 404 confirms historical existence. Dozens of other code pairs — 401, 405, 409, 412, 415, 422, 429 — create the same binary signal when the server resolves the resource before applying the check that produces the non-404 code.

16 elicitation strategies across all three risk tiers. See the Status Code Diff sub-page for the full strategy inventory.

Cache Probing

Conditional requests (If-None-Match, If-Modified-Since) and range requests (Range: bytes=0-0) interact with caching and content-delivery layers that sit in front of access control. A 304 Not Modified or 206 Partial Content confirms the resource exists at the cache/CDN layer — even if the origin server would deny access. The server must locate the resource to evaluate the condition, making the evaluation itself the oracle.

The key insight: every conditional or range response requires the server to first locate an existing representation. If the representation doesn't exist, none of these mechanisms can fire.

8 elicitation strategies, all Safe risk tier. See the Cache Probing sub-page for the full strategy inventory.

Error Message Granularity

The server returns the same status code for both existing and nonexistent resources, but the response body differs. Variations in error messages, error codes, JSON field presence, Content-Length, or content type reveal which internal code path executed. This is the hardest vector to detect automatically and the hardest to eliminate — it requires auditing every error response surface for information leakage.

Error message granularity catches oracles that evade status-code-based detection. A server that normalizes all errors to 400 Bad Request may still leak existence through the message body: {"error": "access denied"} for existing resources vs. {"error": "not found"} for nonexistent ones.

7 elicitation strategies across Safe and Method-Destructive risk tiers. See the Error Message Granularity sub-page for the full strategy inventory.


Scope and Boundaries

What this covers: Passive observation of correct server behavior. Every probe documented here uses legitimate, RFC-compliant HTTP requests. No vulnerabilities are exploited — the oracle is the correct behavior.

What this doesn't cover: Active exploitation (SQLi, XSS, RCE), authentication bypass, or direct data exfiltration. Existence oracles are reconnaissance — they tell you what exists, not what it contains.

Overlapping classifications: Some strategies span multiple vectors. A 304 response is both a status code differential (304 vs. 404) and a cache probing signal (conditional request evaluation). The analysis pipeline evaluates every probe pair against all vectors simultaneously — classification is by observed signal, not by which strategy generated the probe.

On this page