parlov-core 0.3.0

Shared types, error types, and oracle class definitions for parlov.
Documentation

parlov-core

Shared types for HTTP oracle detection. Zero I/O, zero async — just data structures.

types

use parlov_core::{ResponseSurface, ProbeDefinition, ProbeSet, OracleResult};

ResponseSurface — one captured HTTP interaction:

pub struct ResponseSurface {
    pub status: StatusCode,
    pub headers: HeaderMap,
    pub body: Bytes,
    pub timing_ns: u64,
}

ProbeDefinition — one HTTP request to execute:

pub struct ProbeDefinition {
    pub url: String,
    pub method: Method,
    pub headers: HeaderMap,      // auth context lives here
    pub body: Option<Bytes>,
}

ProbeSet — paired surfaces for differential analysis:

pub struct ProbeSet {
    pub baseline: Vec<ResponseSurface>,  // known-valid input
    pub probe: Vec<ResponseSurface>,     // suspect input
}

OracleResult — the analysis output:

pub struct OracleResult {
    pub class: OracleClass,                          // Existence, Authentication, Timing, ...
    pub verdict: OracleVerdict,                      // Confirmed / Likely / NotPresent
    pub evidence: Vec<String>,                       // "403 (baseline) vs 404 (probe)"
    pub severity: Option<Severity>,                  // High / Medium / Low
    pub label: Option<String>,                       // "Authorization-based differential"
    pub leaks: Option<String>,                       // "Resource existence confirmed to low-privilege callers"
    pub rfc_basis: Option<String>,                   // "RFC 9110 §15.5.4"
    pub baseline_summary: Option<ResponseSummary>,   // per-side status on the baseline
    pub probe_summary: Option<ResponseSummary>,      // per-side status on the probe
    pub header_diffs: Vec<DiffedHeader>,             // headers that differed between sides
}

label, leaks, rfc_basis, baseline_summary, and probe_summary are omitted from JSON when None. header_diffs is omitted when empty. All use skip_serializing_if and default — backward-compatible when deserializing pre-0.3.0 data.

DiffedHeader — one header that differed between baseline and probe:

pub struct DiffedHeader {
    pub name: String,              // lowercase header name, e.g. "x-rate-limit-remaining"
    pub baseline: Option<String>,  // value on baseline side; None if absent
    pub probe: Option<String>,     // value on probe side; None if absent
}

ResponseSummary — per-side response summary:

pub struct ResponseSummary {
    pub status: u16,  // HTTP status code
}

Intentionally minimal — carries only status now. Will grow when body diffing lands.

All types derive Serialize and Deserialize with custom serde helpers for StatusCode, Method, and HeaderMap (the http crate types lack native serde support).

use it

Construct a probe set from captured HTTP interactions:

use parlov_core::{ProbeSet, ResponseSurface};
use bytes::Bytes;
use http::{HeaderMap, StatusCode};

let baseline = ResponseSurface {
    status: StatusCode::FORBIDDEN,
    headers: HeaderMap::new(),
    body: Bytes::new(),
    timing_ns: 12_500_000,
};

let probe = ResponseSurface {
    status: StatusCode::NOT_FOUND,
    headers: HeaderMap::new(),
    body: Bytes::new(),
    timing_ns: 11_800_000,
};

let probe_set = ProbeSet {
    baseline: vec![baseline],
    probe: vec![probe],
};

Build a request definition for the probe engine:

use parlov_core::ProbeDefinition;
use http::{Method, HeaderMap};

let def = ProbeDefinition {
    url: "https://api.example.com/users/123".into(),
    method: Method::GET,
    headers: HeaderMap::new(),
    body: None,
};

errors

use parlov_core::Error;

Three variants via thiserror: Http(String), Analysis(String), Serialization(serde_json::Error).

license

MIT OR Apache-2.0