use okami::delegation::{Capability, DelegationToken};
use okami::identity::{AgentIdentity, SpiffeId};
use std::time::Duration;
fn main() {
println!("=== Exploit Attempt: Issuer Spoofing (Finding #1) ===\n");
let attacker = AgentIdentity::new("evil.example", "attacker").expect("attacker identity");
let victim_spiffe = SpiffeId::new("corp.internal", "admin").expect("victim spiffe id");
let subject = SpiffeId::new("evil.example", "puppet").expect("subject spiffe id");
let scopes = vec![Capability::new("write:payroll").expect("scope")];
let mut forged_token = DelegationToken::issue(
&attacker,
subject,
scopes.clone(),
&scopes,
Duration::from_secs(3600),
None,
)
.expect("issue attacker token");
println!("Step 1-3: Attacker issues a valid token as themselves.");
println!(" Real attacker SPIFFE ID: {}", attacker.spiffe_id());
println!(" Token issuer (pre-swap): {}", forged_token.issuer);
println!(
" Embedded cred subject: {}",
forged_token.issuer_credential.spiffe_id
);
forged_token.issuer = victim_spiffe.clone();
println!("\nStep 4: Attacker swaps issuer field to impersonate victim.");
println!(" Token issuer (post-swap): {}", forged_token.issuer);
println!(
" Embedded cred subject: {}",
forged_token.issuer_credential.spiffe_id
);
println!(" Claimed scope: write:payroll");
println!("\nStep 5: Calling token.verify(None)...");
let result = forged_token.verify(None);
match &result {
Ok(()) => {
eprintln!("\n[FAIL] VULNERABILITY PRESENT: forged token verified successfully!");
eprintln!(" The exploit succeeded — attacker can impersonate {victim_spiffe}");
std::process::exit(1);
}
Err(e) => {
println!("\n[PASS] Exploit blocked. verify() returned:");
println!(" Err({e})");
let msg = e.to_string();
if msg.contains("does not match") {
println!("\nFix confirmed: error mentions \"does not match\" as expected.");
println!(
"An attacker cannot forge tokens claiming to be issued by {victim_spiffe}."
);
} else {
println!(
"\nNote: error does not contain \"does not match\" — may be a different guard."
);
}
}
}
}