jsdet-core 0.1.0

Core WASM-sandboxed JavaScript detonation engine
Documentation
//! # jsdet — JavaScript Detonation Engine
//!
//! Sandboxed JavaScript execution for security analysis.
//!
//! ## What it does
//!
//! Executes JavaScript in a `QuickJS` engine compiled to WebAssembly,
//! running inside wasmtime. Every API call is intercepted, observed,
//! and controllable. Nothing escapes.
//!
//! ## How to use it
//!
//! ```rust,no_run
//! use std::sync::Arc;
//! use jsdet_core::{CompiledModule, SandboxConfig, EmptyBridge};
//!
//! let module = CompiledModule::new().unwrap();
//! let result = module.execute(
//!     &["console.log('hello')".into()],
//!     Arc::new(EmptyBridge),
//!     &SandboxConfig::default(),
//! ).unwrap();
//!
//! for obs in &result.observations {
//!     println!("{obs:?}");
//! }
//! ```
//!
//! ## Consumers
//!
//! - **Sear** (URL detonation): uses `jsdet-browser` bridges for document/window/fetch
//! - **Soleno** (extension analysis): uses `jsdet-chrome-ext` bridges for chrome.* APIs
//! - **Your tool**: implement the `Bridge` trait to provide any API surface
//!
//! ## Architecture
//!
//! ```text
//! ┌─────────────────────────────────────────────┐
//! │ Your Rust application                       │
//! │                                             │
//! │  CompiledModule::execute(scripts, bridge)   │
//! │       │                                     │
//! │       ▼                                     │
//! │  ┌─────────────────────────────────┐        │
//! │  │ wasmtime instance               │        │
//! │  │  ┌───────────────────────┐      │        │
//! │  │  │ QuickJS (WASM)        │      │        │
//! │  │  │                       │      │        │
//! │  │  │ JS calls fetch() ─────┼──────┼──► Bridge::call("fetch", args)
//! │  │  │                  ◄────┼──────┼─── returns fake response
//! │  │  │                       │      │        │
//! │  │  │ JS calls eval() ──────┼──────┼──► Observation::DynamicCodeExec
//! │  │  │                       │      │        │
//! │  │  └───────────────────────┘      │        │
//! │  │  Linear memory: isolated        │        │
//! │  │  Fuel metering: bounded         │        │
//! │  │  Syscalls: zero                 │        │
//! │  └─────────────────────────────────┘        │
//! │                                             │
//! │  Vec<Observation> ← what the code DID       │
//! └─────────────────────────────────────────────┘
//! ```

#![allow(
    clippy::missing_errors_doc,
    clippy::must_use_candidate,
    clippy::cast_possible_truncation,
    clippy::cast_possible_wrap,
    clippy::cast_sign_loss,
    clippy::match_same_arms,
    clippy::doc_markdown
)]

pub mod bridge;
pub mod config;
pub mod context;
pub mod coverage;
pub mod error;
pub mod nested_wasm;
pub mod observation;
pub mod sandbox;
pub mod streaming;
pub mod taint;
pub mod timer;
pub mod vulnir_producer;

pub use bridge::{Bridge, CompositeBridge, EmptyBridge, Hook, HookedBridge};
pub use config::SandboxConfig;
pub use context::{ContextId, ContextMessage, MessageBus};
pub use error::{Error, Result};
pub use observation::{Observation, TaintFlow, TaintLabel, TaintedValue, Value};
pub use sandbox::{CompiledModule, ExecutionResult};
pub use taint::{
    Severity, Sink, Source, TaintTracker, propagate_concat, propagate_json_parse,
    propagate_json_stringify, propagate_replace, propagate_slice,
};
pub mod persistent;
pub use coverage::{CoverageAccumulator, CoverageReport};
pub use persistent::PersistentSandbox;
pub use streaming::{BatchCollector, ControlFlow, CountingSink, EarlyStopSink, ObservationSink};
pub use vulnir_producer::{JsdetProducer, ToVulnIR, to_vulnir_graph};