Skip to main content

jsdet_core/
lib.rs

1//! # jsdet  -  JavaScript Detonation Engine
2//!
3//! Sandboxed JavaScript execution for security analysis.
4//!
5//! ## What it does
6//!
7//! Executes JavaScript in a `QuickJS` engine compiled to WebAssembly,
8//! running inside wasmtime. Every API call is intercepted, observed,
9//! and controllable. Nothing escapes.
10//!
11//! ## How to use it
12//!
13//! ```rust,no_run
14//! use std::sync::Arc;
15//! use jsdet_core::{CompiledModule, SandboxConfig, EmptyBridge};
16//!
17//! let module = CompiledModule::new().unwrap();
18//! let result = module.execute(
19//!     &["console.log('hello')".into()],
20//!     Arc::new(EmptyBridge),
21//!     &SandboxConfig::default(),
22//! ).unwrap();
23//!
24//! for obs in &result.observations {
25//!     println!("{obs:?}");
26//! }
27//! ```
28//!
29//! ## Consumers
30//!
31//! - **Sear** (URL detonation): uses `jsdet-browser` bridges for document/window/fetch
32//! - **Soleno** (extension analysis): uses `jsdet-chrome-ext` bridges for chrome.* APIs
33//! - **Your tool**: implement the `Bridge` trait to provide any API surface
34//!
35//! ## Architecture
36//!
37//! ```text
38//! ┌─────────────────────────────────────────────┐
39//! │ Your Rust application                       │
40//! │                                             │
41//! │  CompiledModule::execute(scripts, bridge)   │
42//! │       │                                     │
43//! │       ▼                                     │
44//! │  ┌─────────────────────────────────┐        │
45//! │  │ wasmtime instance               │        │
46//! │  │  ┌───────────────────────┐      │        │
47//! │  │  │ QuickJS (WASM)        │      │        │
48//! │  │  │                       │      │        │
49//! │  │  │ JS calls fetch() ─────┼──────┼──► Bridge::call("fetch", args)
50//! │  │  │                  ◄────┼──────┼─── returns fake response
51//! │  │  │                       │      │        │
52//! │  │  │ JS calls eval() ──────┼──────┼──► Observation::DynamicCodeExec
53//! │  │  │                       │      │        │
54//! │  │  └───────────────────────┘      │        │
55//! │  │  Linear memory: isolated        │        │
56//! │  │  Fuel metering: bounded         │        │
57//! │  │  Syscalls: zero                 │        │
58//! │  └─────────────────────────────────┘        │
59//! │                                             │
60//! │  Vec<Observation> ← what the code DID       │
61//! └─────────────────────────────────────────────┘
62//! ```
63
64#![allow(
65    clippy::missing_errors_doc,
66    clippy::must_use_candidate,
67    clippy::cast_possible_truncation,
68    clippy::cast_possible_wrap,
69    clippy::cast_sign_loss,
70    clippy::match_same_arms,
71    clippy::doc_markdown
72)]
73
74pub mod analysis;
75pub mod bridge;
76pub mod config;
77pub mod context;
78pub mod coverage;
79pub mod error;
80pub mod nested_wasm;
81pub mod observation;
82pub mod sandbox;
83pub mod streaming;
84pub mod taint;
85pub mod timer;
86pub mod vulnir_producer;
87
88pub use analysis::{AnalysisReport, BehavioralFinding, Category, Severity, TimelineEntry, analyze};
89pub use bridge::{Bridge, CompositeBridge, EmptyBridge, Hook, HookedBridge};
90pub use config::SandboxConfig;
91pub use context::{ContextId, ContextMessage, MessageBus};
92pub use error::{Error, Result};
93pub use observation::{
94    EvidenceDerivation, EvidenceFreshness, EvidenceProvenance, Exploitability, Maliciousness,
95    Observation, RuntimeEvidence, RuntimeEvidenceItem, TaintFlow, TaintLabel, TaintedValue, Value,
96    observations_to_contract_evidence, observations_to_runtime_evidence,
97};
98pub use sandbox::{CompiledModule, ExecutionResult};
99pub use taint::{
100    Severity as TaintSeverity, Sink, Source, TaintTracker, propagate_concat, propagate_json_parse,
101    propagate_json_stringify, propagate_replace, propagate_slice,
102};
103pub mod persistent;
104pub use coverage::{CoverageAccumulator, CoverageReport};
105pub use persistent::PersistentSandbox;
106pub use streaming::{BatchCollector, ControlFlow, CountingSink, EarlyStopSink, ObservationSink};
107pub use vulnir_producer::{JsdetProducer, ToVulnIR, to_vulnir_graph};