Expand description
Background worker that drains plugin_security_scans rows in the
"pending" state, re-downloads the published WASM artifact, runs a set of
integrity + static-analysis checks against it, and persists the result.
The checks fall into three buckets:
- Storage integrity — the artifact exists, downloads, and matches the declared file size and SHA-256 checksum.
- Format validity — bytes parse as a WebAssembly module via
wasmparser, with a parse-time budget to catch pathological inputs. - Static analysis — import/export inventory (unknown host namespaces,
high-risk WASI capabilities like
path_openorsock_*), data-segment byte-pattern scanning for hardcoded credentials, suspicious URLs, and known-bad command strings, and section-size anomaly detection.
Isolation. Every scan runs in spawn_blocking with a hard wall-clock
timeout. A scan that panics or burns CPU past the budget fails the job
(recorded as "fail" with a clear finding) but cannot take down the
worker or the request-serving process. This is not a substitute for an
out-of-process sandbox — the scanner still runs in the same address
space as the server — but it bounds blast radius to a single thread and
single scan.
What this explicitly does not do. It does not execute the WASM module. It does not run dependency vulnerability checks against external advisory databases. It does not claim a passing verdict means the plugin is safe — only that no static red flag was raised. Dynamic sandbox execution in a subprocess is tracked separately.
The worker is stateless: on every tick it re-queries for status = 'pending' rows, claims each by upserting a result, and moves on.
Concurrent workers are safe because the upsert is idempotent — the last
writer wins.