Major additions: - Community Next.js app (port 18187) for browsing claims with API docs - stemedb-chaos crate: Fault injection, chaos testing, CRDT properties - Latent ingestion system: Reddit/FDA ingesters with ADK-Go agents - Disputed claims handling: Manual review workflows and validation - Aphoria security scanner: New extractors (SQL injection, command injection, weak crypto, TLS version), policy-based ignores, UAT reports - Docker infrastructure: Dockerfile, docker-compose.yml for full stack - VulnBank demo: Intentionally vulnerable multi-language test corpus SDK & API enhancements: - Source registry handlers for tracking data provenance - Metrics endpoint - Skeptic filtering improvements Code quality: - Split 14 large files (>500 lines) into focused modules - All files now under 500-line limit per project guidelines Documentation: - Chaos testing guide, circuit breakers, observability docs - Phase 7 UAT documentation updates - Martin Kleppmann technical writer agent Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
53 lines
1.7 KiB
Rust
53 lines
1.7 KiB
Rust
//! Cryptography - Contains intentional vulnerabilities
|
|
//!
|
|
//! Vulnerabilities:
|
|
//! - MD5 for hashing (collision attacks)
|
|
//! - SHA1 for hashing (collision attacks)
|
|
//! - DES encryption (56-bit key, brute-forceable)
|
|
|
|
use md5::{Md5, Digest as Md5Digest};
|
|
use sha1::{Sha1, Digest as Sha1Digest};
|
|
use des::Des;
|
|
use des::cipher::{BlockEncrypt, KeyInit, generic_array::GenericArray};
|
|
|
|
/// VULNERABILITY: MD5 is cryptographically broken
|
|
/// Collision attacks are practical since 2004
|
|
pub fn hash_password_md5(password: &str) -> String {
|
|
// BLOCK: MD5 is cryptographically broken - use SHA-256 or better
|
|
let mut hasher = Md5::new();
|
|
hasher.update(password.as_bytes());
|
|
format!("{:x}", hasher.finalize())
|
|
}
|
|
|
|
/// VULNERABILITY: SHA1 is cryptographically broken
|
|
/// Google demonstrated practical collision in 2017 (SHAttered)
|
|
pub fn hash_document_sha1(data: &[u8]) -> String {
|
|
// BLOCK: SHA1 is cryptographically broken - use SHA-256 or better
|
|
let mut hasher = Sha1::new();
|
|
hasher.update(data);
|
|
format!("{:x}", hasher.finalize())
|
|
}
|
|
|
|
/// VULNERABILITY: DES uses 56-bit keys
|
|
/// Can be brute-forced in hours with modern hardware
|
|
pub fn encrypt_des(key: &[u8; 8], plaintext: &[u8; 8]) -> [u8; 8] {
|
|
// BLOCK: DES uses 56-bit keys - use AES-256 instead
|
|
let cipher = Des::new(GenericArray::from_slice(key));
|
|
let mut block = GenericArray::clone_from_slice(plaintext);
|
|
cipher.encrypt_block(&mut block);
|
|
block.into()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_weak_crypto_patterns() {
|
|
// Verify vulnerable patterns exist for demo
|
|
let _ = hash_password_md5("password123");
|
|
let _ = hash_document_sha1(b"document content");
|
|
let _ = encrypt_des(&[0u8; 8], &[0u8; 8]);
|
|
}
|
|
}
|