stealthreq 0.1.0

Trait-driven, human-like request mutation primitives for crawlers and scrapers.
Documentation

stealthreq

stealthreq is a Rust library for generating human-like outbound request behavior across HTTP clients. It focuses on three anti-fingerprint layers:

  • randomized request headers and header order noise
  • timing jitter before sends
  • selectable TLS fingerprint profiles (for clients that can consume them)

RequestModifier is intentionally trait-based so any client can adopt it through a small adapter.

Features

  • StealthProfile and StealthPolicy to generate per-request traffic noise.
  • RequestModifier trait with deterministic and randomized application options.
  • MutableRequest adapter trait so reqwest, hyper, ureq, or custom clients can participate.
  • WAF fingerprint detection and suggested evasions based on the extracted karyx logic.

Installation

[dependencies]
stealthreq = "0.1"

Quick Start

use stealthreq::{RequestModifier, StealthPolicy, MutableRequest};

struct BuilderAdapter {
    headers: Vec<(String, String)>,
}

impl MutableRequest for BuilderAdapter {
    fn set_header(&mut self, name: &str, value: &str) {
        self.headers.push((name.to_string(), value.to_string()));
    }
}

let mut request = BuilderAdapter { headers: vec![] };
let policy = StealthPolicy::default();
let applied = policy.apply(&mut request).unwrap();

println!("ua={}", applied.user_agent);
println!("headers={:?}", request.headers);
println!("jitter={:?}", applied.jitter);
println!("tls={}", applied.tls_profile.name);

Example: reqwest integration

use reqwest::Client;
use stealthreq::{RequestModifier, StealthPolicy, MutableRequest};

struct ReqwestAdapter {
    pub builder: reqwest::RequestBuilder,
}

impl MutableRequest for ReqwestAdapter {
    fn set_header(&mut self, name: &str, value: &str) {
        self.builder = self.builder.header(name, value);
    }
}

#[tokio::main]
async fn main() {
    let client = Client::new();
    let mut req = ReqwestAdapter { builder: client.get("https://example.com") };
    let policy = StealthPolicy::default();
    let _ = policy.apply(&mut req).unwrap();

    let request = req.builder.build().unwrap();
    let _ = client.execute(request).await.unwrap();
}

Example: custom timing only

use stealthreq::StealthProfileConfig;

let config_toml = r#"jitter_ms_min = 200
jitter_ms_max = 800
rotate_tls = false
seed = 4242
"#;
let profile = StealthProfileConfig::from_toml(config_toml).unwrap();
println!("{} ms", profile.timing.min_ms);

WAF-aware suggestion flow

Use the bundled waf module to read a snapshot and choose safer payload encodings:

use stealthreq::waf::{HttpResponseSnapshot, detect_waf, suggest_evasion};

let snapshot = HttpResponseSnapshot {
    status: 403,
    headers: vec![("Server".into(), "cloudflare".into())],
    body: b"Access denied".to_vec(),
};
if let Some(fp) = detect_waf(&snapshot) {
    let encodings = suggest_evasion(&fp);
    println!("{}", fp.name);
    println!("{} strategies", encodings.len());
}

Contributing

Open issues or PRs with tests for new fingerprints, profiles, and client adapters.