Repository navigation
Security
Security fixes are applied to the latest stable version only.
| Version | Supported |
|---|---|
| v5.15.x (latest) | ✅ Yes |
| v5.0.x – v5.14.x | |
| v4.x and earlier | ❌ No |
Two 5.x releases to skip. 5.0.3 breaks
nodus-sdkat construction (fixed in 5.0.4) and 5.7.0 makesnodus checkreject correct code (fixed in 5.7.1).Anything embedding a capability policy should be on 5.6.0 or later: before it, a policy could be bypassed by writing the async form of a call.
If you discover a security vulnerability, do not open a public GitHub issue.
Instead:
- Email the maintainer, or
- Open a private security report via GitHub's private vulnerability reporting
- Description of the vulnerability
- Steps to reproduce (minimal
.ndscript if applicable) - Potential impact
- Suggested mitigation if known
An embedded NodusRuntime denies subprocess, network and environment access
by default. Advice written against v4.x — including "a bare runtime can shell
out" — is now backwards. Grant explicitly:
NodusRuntime(allow_subprocess=True, allow_network=True)allowed_paths was already a jail on the current working directory and still is.
nodus run and the rest of the CLI are deliberately unaffected, and a test
pins both halves so the asymmetry is not tidied away by a later reader. What
deny-by-default protects is work you did not fully author; a developer running a
script they just wrote is not that.
nodus serve is confined too, since v5.10.0 — code submitted to the server
cannot run subprocesses, open sockets or read the environment unless granted
with --allow-subprocess / --allow-network / --allow-env, narrowed by
--allowed-commands / --allowed-hosts.
Since v5.13.0 the filesystem is confined as well. Submitted code is jailed to
the server's working directory; --allow-paths widens or narrows it. Before that
it could read and write anywhere the server process could — and --allow-paths,
the documented mitigation, compared roots it had not normalised and so refused
every path including the ones it was given. If you run nodus serve on v5.12.0
or earlier, treat it as having no filesystem boundary.
Since v5.15.0 a resume cannot exceed the bounds the host set. A workflow
that parks at workflow_wait and resumes runs on a derived VM, and through
v5.14.0 that VM was given no limits at all — not the step budget, not the
wall-clock deadline, not the memory ceiling, and a tighter frame cap reverted
to the default. So a guest escaped every bound by parking and resuming, and the
caller's own deadline did not catch it: a deadline is only consulted every 100
instructions, and a program doing a handful of resume_workflow calls never
executes 100 more. Measured against v5.14.0 — 8 resumes and roughly 800 ms of
work inside a 300 ms budget, and about 270,000 instructions inside a budget of
5,000 (#873). Ceilings are inherited now, and the step budget is passed down as
the caller's remainder and charged back when the resume returns, so repeated
resumes accumulate rather than each receiving a fresh allowance.
Also in v5.15.0: a module function's agent_call no longer reaches the
process-global agent registry. A NodusRuntime given its own agent_registry
isolates agents per tenant (#185), and crossing into a module function undid it —
the same call answered from the tenant's registry at top level and from the
shared one inside a module. If you run more than one tenant in a process and
your tools call agents from module code, upgrade (#868).
Since v5.14.0 the execution budget is bounded and settable. Every program
submitted to the server runs under a wall-clock budget; nodus serve --time-limit SECS sets the ceiling, and a request may pass timeout_ms to ask
for less — never more. Through v5.13.0 the budget was the CLI's 200 ms with no
way to raise it, and a step that exceeded it under the server did not time out:
it hung the request forever, so while (true) in a workflow step was a
one-line denial of service against any nodus serve instance (#862). A breach
now returns ok: false with Execution timed out. If you run nodus serve on
v5.13.0 or earlier, do not accept workflow submissions from callers you do not
trust to terminate.
| Issue Type | Report As |
|---|---|
| Arbitrary code execution through the runtime | Security vulnerability |
Sandbox escape (bypassing allowed_paths, step limits, etc.) |
Security vulnerability |
| Unsafe filesystem access bypassing the allowlist | Security vulnerability |
| VM state corruption | Security vulnerability |
| Unsafe interpreter behavior (memory, stack) | Security vulnerability |
| General crashes and incorrect behavior | Normal GitHub issue |
| Feature requests | Normal GitHub issue |
Once a vulnerability is reported:
- It will be investigated by the maintainer
- A fix will be developed
- A patch release will be published
- Contributors who report vulnerabilities responsibly will be credited in the release notes where appropriate
Nodus prioritizes:
- Predictable runtime behavior — explicit execution semantics, no hidden side effects
- Explicit sandboxing — sandbox limits (steps, time, stdout, filesystem, input, call stack) are enforced by the runtime and configurable by the host
- Minimal attack surface — the language core is small; advanced capabilities live in runtime services that can be restricted or omitted
When embedding Nodus, configure appropriate limits for untrusted code:
from nodus import NodusRuntime
rt = NodusRuntime(
max_steps=50_000, # instruction count cap
timeout_ms=2000, # wall-clock timeout
max_stdout_chars=10_000, # output cap
allowed_paths=["/safe/dir"], # filesystem allowlist
allow_input=False, # disallow input()
max_frames=100, # call stack depth cap
)A sandbox error is raised as err.kind = "sandbox" inside scripts and as RuntimeLimitExceeded in the Python host.
One remaining gap is a memory limit — the amount of data a script can allocate in its VM state. All other sandbox dimensions (steps, time, stdout, filesystem, input, call stack) are enforced.
- Embedded mode — the host controls all sandbox parameters; untrusted scripts should always run with limits configured
-
CLI mode —
nodus run --step-limit N --time-limit N --allow-paths <paths>for sandboxed execution from the command line -
Server mode —
nodus serve --auth-token <token>requires anAuthorizationheader on all HTTP requests;--allow-pathsrestricts filesystem access;--time-limit SECSbounds each submitted program (v5.14.0)
Because Nodus executes code, careful review of runtime and VM behavior is important when accepting scripts from untrusted sources. Always:
- Set
max_stepsandtimeout_msto prevent runaway scripts - Set
allowed_pathsto prevent unauthorized filesystem access - Set
allow_input=Falseto prevent scripts from reading stdin - Set
max_framesto prevent stack overflow from pathological recursion
Nodus v5.15.0 — Release · GitHub · Issues · Changelog
Opcode set frozen at v1.0. See Bytecode Reference for the freeze declaration.
Getting Started
Language Reference
- Syntax Reference
- Type System
- Control Flow
- Functions
- Modules and Imports
- Error Handling
- Coroutines and Channels
- Workflows and Task Graphs
- Standard Library
Tooling
Embedding
Project