jsdet-core 0.1.1

Core WASM-sandboxed JavaScript detonation engine
Documentation
use jsdet_core::{
    observation::{DynamicCodeSource, Observation, TaintLabel, Value},
    sandbox::ExecutionResult,
    vulnir_producer::ToVulnIR,
};

#[test]
fn test_adversarial_massive_strings_are_truncated() {
    // Generate a massive string
    let massive_string = "A".repeat(10000);

    let result = ExecutionResult {
        observations: vec![Observation::DynamicCodeExec {
            source: DynamicCodeSource::Eval,
            code_preview: massive_string.clone(),
        }],
        scripts_executed: 1,
        errors: vec![],
        duration_us: 1000,
        timed_out: false,
    };

    let graph = result.to_vulnir_graph();

    assert_eq!(graph.node_count(), 1);

    // Check that the target is truncated to 100 chars
    let node = graph
        .node_weight(petgraph::graph::NodeIndex::new(0))
        .expect("graph node");
    if let vulnir::VulnNode::Capability { target, .. } = node {
        let t = target.as_ref().unwrap();
        assert_eq!(t.len(), 100);
        assert!(t.chars().all(|c| c == 'A'));
    } else {
        panic!("Expected Capability node");
    }
}

#[test]
fn test_adversarial_empty_result() {
    let result = ExecutionResult {
        observations: vec![],
        scripts_executed: 0,
        errors: vec![],
        duration_us: 0,
        timed_out: false,
    };

    let graph = result.to_vulnir_graph();

    assert_eq!(graph.node_count(), 0);
    assert_eq!(graph.edge_count(), 0);
}

#[test]
fn test_adversarial_taint_flow_with_multiple_args() {
    let result = ExecutionResult {
        observations: vec![
            Observation::NetworkRequest {
                url: "https://evil.com".to_string(),
                method: "POST".to_string(),
                headers: vec![],
                body: None,
            },
            Observation::ApiCall {
                api: "eval".to_string(),
                args: vec![
                    Value::string("console.log"),
                    Value::tainted_string("malicious_payload", TaintLabel::new(1)),
                ],
                result: Value::Null,
            },
        ],
        scripts_executed: 1,
        errors: vec![],
        duration_us: 1000,
        timed_out: false,
    };

    let graph = result.to_vulnir_graph();

    assert_eq!(graph.node_count(), 2);
    assert_eq!(graph.edge_count(), 1);

    // We expect the edge to indicate that arg[1] was tainted, not arg[0]
    let edge = graph
        .edge_weight(petgraph::graph::EdgeIndex::new(0))
        .expect("graph edge");
    if let vulnir::VulnEdge::TaintReach { path, .. } = edge {
        assert!(path.contains("arg[[1]]"));
    } else {
        panic!("Expected TaintReach edge");
    }
}