Quarantine Package

Verdict

Do not install

fixture:hostile (version 1.0.0)

Receipt
8b42cfb93e
Started
2026-11-04T15:43:06.477Z
Finished
2026-11-04T15:43:24.352Z
Source
repo fixture, never published

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

Rules that fired

RuleTierWhyObservations
ado-not-installwrite attempt (successful or blocked) outside /work, /tmp and HOMEo1
bdo-not-installaccess attempt to docker.sock or a credential patho3
ddo-not-installnetwork attempt carrying a payload (plaintext HTTP body/POST/PUT/PATCH/chunked, or raw bytes on non-TLS TCP)o5
freviewnetwork attempt (DNS, TCP or UDP, TLS included; TLS bodies are not inspected), or a bind/listen in the sandbox network namespaceo4, o5
greviewwrite inside HOMEo2

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
networktruetruematchrecolector.example.com
filesOutsidePackagetruetruematch/etc/qp-fixture-marker, /home/qp/.qp-fixture-marker
childProcessestruetruematch/usr/bin/sh, /usr/local/bin/node

Sinkhole log

Network attempts. Nothing left the sandbox.

TypeDestinationPortSNIMethod / pathPayload bytes
dnsrecolector.example.com
tcprecolector.example.com80POST /collect15

Model's expectation before the run model, informational

The package declares an install script (node attempts.js) whose name and the author's own description ('makes benign attempts that look hostile') indicate it tries network access, out-of-tree writes, and subprocess spawns at install time. The entry module itself is inert, but installing/using the package in a sandbox will execute that script. Hosts and paths are best-guess placeholders since attempts.js contents were not provided.

Model status: ok

Observations 9

IdKindActorTargetBlocked
o1fs-writepackage/etc/qp-fixture-markeryes
o2fs-writepackage/home/qp/.qp-fixture-markerno
o3fs-accesspackage/var/run/docker.sockyes
o4net-dnspackagerecolector.example.comno
o5net-tcppackagerecolector.example.comno
o6env-enumeratepackage
o7spawnpackage
o8spawnpackage
o9loadharness

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.