Quarantine Package

Verdict

Review

fixture:netbenign (version 1.0.0)

Receipt
d5af19b228
Started
2026-11-04T15:50:14.232Z
Finished
2026-11-04T15:50:32.198Z
Source
repo fixture, never published

Computed by fixed rules from what was observed. The model's explanation never changes it.

Rules that fired

RuleTierWhyObservations
freviewnetwork attempt (DNS, TCP or UDP, TLS included; TLS bodies are not inspected), or a bind/listen in the sandbox network namespaceo1, o2

Prediction vs observed

Before the run, the model on Vultr Serverless Inference read the package and predicted its behaviour. The sandbox then recorded what happened.

3 match
DimensionPredictedObservedResultDetails
networktruetruematchdownloads.qp-fixture.example
filesOutsidePackagefalsefalsematch
childProcessestruetruematch/usr/bin/sh, /usr/local/bin/node

Sinkhole log

Network attempts. Nothing left the sandbox.

TypeDestinationPortSNIMethod / pathPayload bytes
dnsdownloads.qp-fixture.example
tcpdownloads.qp-fixture.example80GET /prebuilt/v1/linux-x64.json0

Model's expectation before the run model, informational

The entry module only exports a static object, so requiring it performs no I/O. However, the package declares an `install` script (node check.js) described as probing for a binary download via a GET, which implies outbound network access and a spawned node child process at install time. No mechanism is indicated for writing files outside the package folder.

Model status: ok

Observations 5

IdKindActorTargetBlocked
o1net-dnspackagedownloads.qp-fixture.exampleno
o2net-tcppackagedownloads.qp-fixture.exampleno
o3spawnpackage
o4spawnpackage
o5loadharness

Sandbox destroyed

yes: no container, network or volume of this task remains

Limits applied
{
  "downloadSeconds": 120,
  "downloadMaxBytes": 52428800,
  "downloadMaxPackages": 300,
  "sandboxSeconds": 60,
  "pids": 64,
  "memoryBytes": 268435456,
  "cpus": 0.5,
  "tmpfsWorkBytes": 134217728,
  "tmpfsTmpBytes": 67108864,
  "tmpfsHomeBytes": 16777216
}
Known limitations
  • L-4: ICMP is out of scope: the sandbox has no capability to open raw sockets, and unprivileged ICMP is not logged.
  • L-4: TLS bodies are not inspected: the sinkhole records the SNI from the ClientHello and refuses the handshake.
  • UDP other than DNS is logged as an attempt; its original destination comes from the kernel trace when the socket names it.
  • DNS over TCP is logged as a TCP attempt to port 53 (query name not parsed).
  • Env-var reads are seen by the in-process preload only; a package can bypass or forge it in its own process. Forged preload records can only add observations; trace-derived completeness markers come from the tracer stream.
  • Inside the harness process every rule-relevant syscall is attributed to the package (the harness itself performs none).
  • Paths written through fchdir-relative or unknown directory fds are reported as unresolved and treated as outside the allowed areas.
  • Side channels inside the kernel (timing, /proc enumeration) are not observed.
  • L-4: Evasion: in the shared pid namespace a package can see that it is traced (TracerPid, the strace process) and behave benignly; S1 does not hide the tracer.
  • npm CLI processes do not get the env-read preload (npm fails with a wrapped process.env); an npm started by package code is therefore reported as incomplete instrumentation (review).
  • L-1: Shell expansion of env variables (e.g. $NPM_TOKEN inside a lifecycle sh) and env reads by sh itself (perl and awk are removed from the image since S2, X10) are invisible to both the kernel trace and the preload (DEC-11r5; their file, network and process activity is still traced and judged).
  • L-2: DEC-11r4: a package lifecycle that executes a script directly from /work, /tmp or HOME (e.g. "./install.sh" rather than "sh ./install.sh" or "node x.js") fails the instrumentation marker and gets review (i): the trace cannot tell a script from an ELF binary there (fail closed; narrowed in S2, X8).
  • L-3: Download phase: a non-registry spec in the root manifest aborts before any network request; one deeper in the tree is rejected before it is fetched, but registry metadata of the dependencies visited before it has been fetched. Download-container egress is not limited to the registry host in S1.
  • L-4: execveat is handled (envp never trusted, SR-3) but is covered by unit tests only, not by a runtime fixture.
  • L-4: image builds are not byte-reproducible: the bases are pinned by digest, but distribution packages (strace, iptables, tcpdump) are installed at build time.
  • L-6b: relative file operations of a child process printed before the clone return of its parent have no inherited cwd: they are unresolved, so a write gives (a) and a read gives review (fail closed).
  • L-8: a chdir by a thread not yet attributed to any process that overlaps an unrelated fork marks that fork raced: relative paths of the child are unresolved (over-condemnation, never install).
  • L-8b: a benign multi-threaded package whose non-forking thread ever changes directory (e.g. main thread process.chdir while a worker spawns) gets the relative paths of its children unresolved: relative writes give do-not-install (a), relative reads give review. Fail closed by design (dispatch 3).
  • L-9: a chdir whose outcome is unknown (killed mid-call, "= ?", or never resumed before the trace ends) is treated as applied: the cwd of the thread group and of overlapping or later children become unresolved (fail closed).
  • L-10: a process cloned with CLONE_FS but not CLONE_THREAD shares its working directory with its parent; both sides get an unresolved cwd for the whole trace (fail closed). Only native code issues such a clone; node, dash and perl do not.
  • L-11: io_uring is not traced. Node 22 / libuv in the sandbox never issues io_uring_setup (checked with UV_USE_IO_URING=1), and native io_uring is denied by the default Docker seccomp profile the sandbox runs under; native code from a writable mount gives review anyway (L-2).
  • L-13: a native addon (.node) that the package loads can read env in-process with getenv(); there is no exec and no preload record, so only the intent signal (c1) is lost. Same class as L-1: the sandbox env holds no secret value (C7) and any exfiltration still fires (d)/(f).
  • Sinkhole memory bound: when more than 128 MB is buffered across open connections, the connection holding the most is recorded early with what it sent so far; later bytes on it are not counted.
  • UDP payloads are logged but, per DEC-2r1, UDP attempts are rated review (f), never do-not-install by payload.