use security_core::severity::SecuritySeverity;
use security_events::sanitize::sanitize_for_text_sink;
use security_events::{
event::{EventOutcome, SecurityEvent},
kind::EventKind,
AuditChain,
};
#[test]
fn cve_log_injection_newline_sanitized() {
let malicious = "user: admin\nINFO [AUTH] login_success user=attacker";
let sanitized = sanitize_for_text_sink(malicious);
assert!(
!sanitized.contains('\n'),
"Log injection: raw newline must be sanitized, got: {sanitized:?}"
);
assert!(
sanitized.contains(r"\n"),
"Log injection: sanitized output must contain escaped newline marker"
);
}
#[test]
fn cve_log_injection_crlf_sanitized() {
let malicious = "user: admin\r\nContent-Type: text/plain\r\nINJECTED";
let sanitized = sanitize_for_text_sink(malicious);
assert!(!sanitized.contains('\r'), "raw CR must be sanitized");
assert!(!sanitized.contains('\n'), "raw LF must be sanitized");
}
#[test]
fn cve_log_injection_null_byte_sanitized() {
let malicious = "token: secret\x00INJECTED";
let sanitized = sanitize_for_text_sink(malicious);
assert!(
!sanitized.contains('\x00'),
"Null byte must be sanitized from log output"
);
}
#[test]
fn cve_audit_chain_tamper_detected() {
let mut chain = AuditChain::new();
chain.append(SecurityEvent::new(
EventKind::AdminAction,
SecuritySeverity::Info,
EventOutcome::Success,
));
chain.append(SecurityEvent::new(
EventKind::AuthnFailure,
SecuritySeverity::High,
EventOutcome::Failure,
));
assert!(chain.verify(), "untampered chain must verify");
let entries = chain.entries();
assert_eq!(entries.len(), 2);
let first_hash = &entries[0].hash;
let second_prev = entries[1].previous_hash.as_ref().unwrap();
assert_eq!(
first_hash, second_prev,
"hash chain linkage must be consistent"
);
}
#[test]
fn cve_audit_chain_empty_verifies() {
let chain = AuditChain::new();
assert!(chain.verify());
}