use crate::target_spec::{join_capped, load_canonicals, scan, sufficient_canonicals, surfaces};
use base64::{engine::general_purpose, Engine as _};
fn b64(s: &str) -> String {
general_purpose::STANDARD.encode(s.as_bytes())
}
fn carry(payload: &str, depth: usize) -> String {
format!("apiVersion: v1\nkind: Secret\ndata:\n layer{depth}: {payload}\n")
}
const DECODE_TARGET_RECALL: f64 = 0.95;
#[test]
fn credential_sufficient_tokens_survive_three_decode_layers() {
let all = load_canonicals();
let sufficient = sufficient_canonicals(&all);
assert!(
sufficient.len() >= 150,
"expected >= 150 credential-sufficient detectors, found {}",
sufficient.len()
);
for depth in 1usize..=3 {
let mut total = 0usize;
let mut surfaced = 0usize;
let mut failures: Vec<String> = Vec::new();
for canon in &sufficient {
let mut payload = canon.canonical_text.clone();
for d in 0..depth {
payload = b64(&carry(&payload, d));
}
let body = carry(&payload, depth);
let matches = scan(&body, &format!("nested/depth{depth}/secret.yaml"));
total += 1;
if surfaces(&matches, &canon.credential) {
surfaced += 1;
} else {
failures.push(canon.detector_id.clone());
}
}
let ratio = surfaced as f64 / total.max(1) as f64;
println!(
"decode-depth {depth}: recovered {surfaced}/{total} = {ratio:.4}; {} lost",
failures.len()
);
assert!(
ratio >= DECODE_TARGET_RECALL,
"decode-depth {depth}: only {surfaced}/{total} = {ratio:.4} of credential-sufficient \
tokens were recovered through {depth} base64 layer(s); target {DECODE_TARGET_RECALL:.2}. \
The engine is not recursing far enough on a realistic Secret carrier, each lost \
detector is a decode-recursion gap:\n - {}",
join_capped(&failures, 50)
);
}
}
#[test]
fn single_token_decode_ladder_reaches_depth_three() {
let all = load_canonicals();
let aws = all
.iter()
.find(|c| c.detector_id == "aws-access-key")
.expect("aws-access-key contract present");
let mut payload = aws.canonical_text.clone();
let mut depth_recovered = 0usize;
for d in 0..3 {
payload = b64(&carry(&payload, d));
let body = carry(&payload, d + 1);
let matches = scan(&body, &format!("ladder/depth{}.yaml", d + 1));
if surfaces(&matches, &aws.credential) {
depth_recovered = d + 1;
}
}
assert_eq!(
depth_recovered, 3,
"AWS access key recovered only through depth {depth_recovered} of a 3-layer base64 \
nest; the multi-layer decode claim requires depth 3. (credential: {})",
aws.credential
);
}
#[test]
fn credential_sufficient_tokens_reassemble_across_two_lines() {
let all = load_canonicals();
let sufficient = sufficient_canonicals(&all);
let mut total = 0usize;
let mut surfaced = 0usize;
let mut failures: Vec<String> = Vec::new();
for canon in &sufficient {
let cred = &canon.credential;
if cred.len() < 16 {
continue;
}
let mid = cred.len() / 2;
if !cred.is_char_boundary(mid) {
continue;
}
let (head, tail) = cred.split_at(mid);
let body = format!("api_token = \"{head}\" +\n \"{tail}\"\n");
let matches = scan(&body, "src/build_token.py");
total += 1;
if surfaces(&matches, cred) {
surfaced += 1;
} else {
failures.push(format!("{} (split `{head}` | `{tail}`)", canon.detector_id));
}
}
let ratio = surfaced as f64 / total.max(1) as f64;
println!(
"multiline 2-line reassembly: {surfaced}/{total} = {ratio:.4}; {} lost",
failures.len()
);
assert!(
total >= 150,
"expected >= 150 splittable credential-sufficient detectors, ran {total}"
);
assert!(
ratio >= 0.90,
"multiline reassembly recovered only {surfaced}/{total} = {ratio:.4} of split tokens; \
target 0.90. A secret broken across two concatenated source lines slips past these \
detectors: the config-as-code leak shape:\n - {}",
join_capped(&failures, 50)
);
}
#[test]
fn credential_sufficient_tokens_reassemble_across_three_lines() {
let all = load_canonicals();
let sufficient = sufficient_canonicals(&all);
let mut total = 0usize;
let mut surfaced = 0usize;
let mut failures: Vec<String> = Vec::new();
for canon in &sufficient {
let cred = &canon.credential;
if cred.len() < 24 {
continue; }
let third = cred.len() / 3;
if !cred.is_char_boundary(third) || !cred.is_char_boundary(third * 2) {
continue;
}
let a = &cred[..third];
let b = &cred[third..third * 2];
let c = &cred[third * 2..];
let body = format!("token = (\n \"{a}\"\n \"{b}\"\n \"{c}\"\n)\n");
let matches = scan(&body, "src/three_part.py");
total += 1;
if surfaces(&matches, cred) {
surfaced += 1;
} else {
failures.push(canon.detector_id.clone());
}
}
let ratio = surfaced as f64 / total.max(1) as f64;
println!(
"multiline 3-line reassembly: {surfaced}/{total} = {ratio:.4}; {} lost",
failures.len()
);
assert!(
total >= 100,
"expected >= 100 tri-splittable detectors, ran {total}"
);
assert!(
ratio >= 0.85,
"three-line reassembly recovered only {surfaced}/{total} = {ratio:.4}; target 0.85. \
A token broken across THREE concatenated lines is not reassembled for these detectors:\n - {}",
join_capped(&failures, 50)
);
}