use super::*;
fn b64(s: &str) -> String {
base64::engine::general_purpose::STANDARD.encode(s.as_bytes())
}
fn hexs(s: &str) -> String {
s.as_bytes().iter().map(|b| format!("{b:02x}")).collect()
}
#[test]
fn session_filter_registers_a_real_provider_key() {
let f = session_disclosure_filter(Some("sk-live-9f3a2b7c1d"));
assert!(f.leaks("Authorization: Bearer sk-live-9f3a2b7c1d"));
assert!(f.leaks(&format!("k={}", b64("sk-live-9f3a2b7c1d"))));
assert!(f.redact("token=sk-live-9f3a2b7c1d").contains("[REDACTED]"));
}
#[test]
fn session_filter_ignores_trivial_or_absent_key() {
assert!(!session_disclosure_filter(None).leaks("anything at all"));
assert!(!session_disclosure_filter(Some("x")).leaks("x marks the spot"));
}
#[test]
fn session_tls_redacts_installed_secret_and_restores() {
assert_eq!(
redact_session_ingress("plain sk-live-abc12345"),
"plain sk-live-abc12345"
);
{
let mut f = DisclosureFilter::new();
f.register("sk-live-abc12345");
let _g = scoped_session_disclosure(f);
assert!(!redact_session_ingress("token=sk-live-abc12345").contains("sk-live-abc12345"));
let enc = b64("sk-live-abc12345");
assert!(!redact_session_ingress(&format!("b={enc}")).contains(&enc));
}
assert_eq!(
redact_session_ingress("token=sk-live-abc12345"),
"token=sk-live-abc12345"
);
}
#[test]
fn catches_raw_value() {
let mut f = DisclosureFilter::new();
f.register("CANARY-7f3a9c2b");
assert!(f.leaks("the token is CANARY-7f3a9c2b right here"));
assert!(!f.leaks("nothing secret in this text"));
}
#[test]
fn catches_base64_reencoding() {
let mut f = DisclosureFilter::new();
f.register("CANARY-7f3a9c2b");
let leaked = format!("here is {} encoded", b64("CANARY-7f3a9c2b"));
assert!(f.leaks(&leaked), "base64 re-encoding must still be caught");
}
#[test]
fn catches_hex_reencoding() {
let mut f = DisclosureFilter::new();
f.register("CANARY-7f3a9c2b");
assert!(f.leaks(&format!("payload={}", hexs("CANARY-7f3a9c2b"))));
}
#[test]
fn redacts_all_forms() {
let mut f = DisclosureFilter::new();
f.register("SECRETVAL-abc123");
let text = format!(
"raw=SECRETVAL-abc123 b64={} hex={}",
b64("SECRETVAL-abc123"),
hexs("SECRETVAL-abc123")
);
let red = f.redact(&text);
assert!(!f.leaks(&red), "redacted text must not leak");
assert!(red.contains("[REDACTED]"));
}
#[test]
fn value_filter_not_shape_filter() {
let f = DisclosureFilter::new();
assert!(!f.leaks("AKIAIOSFODNN7EXAMPLE looks like a key but isn't registered"));
}
#[test]
fn empty_registration_is_ignored() {
let mut f = DisclosureFilter::new();
f.register("");
assert!(!f.leaks("anything at all"));
}
use base64::engine::general_purpose::{STANDARD_NO_PAD, URL_SAFE, URL_SAFE_NO_PAD};
const B64_DISTINCT: &str = "canary-\u{00ff}\u{00fe}\u{00fd}";
#[test]
fn catches_base64url_reencoding() {
let mut f = DisclosureFilter::new();
f.register(B64_DISTINCT);
let url = URL_SAFE.encode(B64_DISTINCT.as_bytes());
let std = base64::engine::general_purpose::STANDARD.encode(B64_DISTINCT.as_bytes());
assert_ne!(
url, std,
"test secret must distinguish base64 from base64url"
);
assert!(
f.leaks(&format!("payload={url}")),
"base64url must be caught"
);
assert!(f.leaks(&format!(
"payload={}",
URL_SAFE_NO_PAD.encode(B64_DISTINCT.as_bytes())
)));
}
#[test]
fn catches_base64_nopad_reencoding() {
let mut f = DisclosureFilter::new();
f.register("CANARY-7f3a9c2b");
assert!(f.leaks(&format!(
"b={}",
STANDARD_NO_PAD.encode("CANARY-7f3a9c2b".as_bytes())
)));
}
#[test]
fn catches_uppercase_hex() {
let mut f = DisclosureFilter::new();
f.register("CANARY-7f3a9c2b");
let upper: String = "CANARY-7f3a9c2b"
.as_bytes()
.iter()
.map(|b| format!("{b:02X}"))
.collect();
assert!(f.leaks(&format!("HX={upper}")));
}
#[test]
fn catches_percent_encoding() {
let mut f = DisclosureFilter::new();
f.register("CANARY-7f3a9c2b");
let pct: String = "CANARY-7f3a9c2b"
.as_bytes()
.iter()
.map(|b| format!("%{b:02X}"))
.collect();
assert!(
f.leaks(&format!("q={pct}")),
"URL/percent-encoding must be caught"
);
}
#[test]
fn catches_string_escapes() {
let mut f = DisclosureFilter::new();
f.register("CANARY-7f3a9c2b");
let esc_x: String = "CANARY-7f3a9c2b"
.as_bytes()
.iter()
.map(|b| format!("\\x{b:02x}"))
.collect();
let esc_u: String = "CANARY-7f3a9c2b"
.as_bytes()
.iter()
.map(|b| format!("\\u{b:04x}"))
.collect();
assert!(
f.leaks(&format!("s=\"{esc_x}\"")),
"\\xXX escape must be caught"
);
assert!(
f.leaks(&format!("s=\"{esc_u}\"")),
"\\uXXXX escape must be caught"
);
}
#[test]
fn catches_chunk_split_raw() {
let mut f = DisclosureFilter::new();
f.register("CANARY-7f3a9c2b");
assert!(f.leaks("prefix CANARY-\n7f3a9c2b suffix"));
assert!(f.leaks("C A N A R Y - 7 f 3 a 9 c 2 b"));
}
#[test]
fn catches_chunk_split_base64() {
let mut f = DisclosureFilter::new();
f.register("CANARY-7f3a9c2b");
let b64 = base64::engine::general_purpose::STANDARD.encode("CANARY-7f3a9c2b".as_bytes());
let mid = b64.len() / 2;
let wrapped = format!("{}\n{}", &b64[..mid], &b64[mid..]);
assert!(f.leaks(&wrapped), "line-wrapped base64 must be caught");
}
#[test]
fn redact_withholds_chunk_split() {
let mut f = DisclosureFilter::new();
f.register("CANARY-7f3a9c2b");
let split = "leak: CANARY-\n7f3a9c2b done";
let red = f.redact(split);
assert!(!f.leaks(&red), "redacted split text must not leak");
assert!(
red.contains("withheld"),
"split redaction withholds wholesale"
);
}
#[test]
fn redact_post_condition_holds_for_every_form() {
let mut f = DisclosureFilter::new();
f.register("SECRETVAL-abc123");
let s = "SECRETVAL-abc123";
let b64 = base64::engine::general_purpose::STANDARD.encode(s.as_bytes());
let hex: String = s.as_bytes().iter().map(|b| format!("{b:02x}")).collect();
let pct: String = s.as_bytes().iter().map(|b| format!("%{b:02X}")).collect();
let text = format!("raw={s} b64={b64} hex={hex} pct={pct} split=SEC\nRETVAL-abc123");
assert!(!f.leaks(&f.redact(&text)), "redact output must never leak");
}