/** * @module @arcis/node/rasp * EXPERIMENTAL runtime application self-protection (RASP) spike — Day 3. * * The capability gap vs Aikido Zen: instead of guessing at the perimeter with * regex, RASP confirms an attack AT THE SINK. It tracks request-derived * ("tainted") input through the request via AsyncLocalStorage, instruments a * dangerous sink (child_process), and flags only when tainted input that * carries shell metacharacters actually reaches `exec`. That means it catches * obfuscated payloads a regex misses AND fires far fewer false positives, * because pure-data input (no metacharacters) reaching a sink is allowed. * * Opt-in and OFF by default: nothing here runs unless `enableRasp()` is called, * and the taint context is only populated when `raspMiddleware()` is mounted. * Behind a flag, as the plan requires. This is a spike, not a shipped pillar — * see documents/rasp-go-no-go.md. */ import type { RequestHandler } from 'express'; /** A confirmed tainted-input-reaching-sink event. */ export interface RaspFinding { /** The instrumented sink, e.g. "child_process.exec". */ sink: string; /** The tainted request value that reached the sink. */ tainted: string; /** The full command/argument passed to the sink (truncated for logs). */ command: string; } export declare class RaspViolation extends Error { readonly finding: RaspFinding; constructor(finding: RaspFinding); } /** * Pure core: does any tainted value appear in `command` AND carry shell * metacharacters? Returns the finding or null. Exported for testing — this is * the load-bearing logic; the monkey-patch below just wires it to the sink. */ export declare function detectTaintedSink(command: string, tainted: Iterable, sink?: string): RaspFinding | null; /** * Express middleware that builds the per-request taint set (from body / query / * params) and runs the rest of the request inside the AsyncLocalStorage scope, * so an instrumented sink can see which inputs are request-derived. */ export declare function raspMiddleware(): RequestHandler; interface RaspOptions { /** Throw RaspViolation on a finding (default). false = observe-only. */ block?: boolean; /** Called on every finding, regardless of block mode. */ onViolation?: (finding: RaspFinding) => void; } /** * Install the sink instrumentation. Idempotent, opt-in, process-global (it * mutates the shared child_process module — the monkey-patch fragility the * go/no-go writeup weighs). Call once at startup; pair with `raspMiddleware()`. */ export declare function enableRasp(options?: RaspOptions): void; /** Restore the original sinks. Idempotent. Primarily for tests / teardown. */ export declare function disableRasp(): void; /** Run a function inside a taint scope. Test helper / non-Express integration. */ export declare function withTaintScope(taintedValues: Iterable, fn: () => T): T; export {}; //# sourceMappingURL=index.d.ts.map