π¦ Nika 0.56.2 β Security Batch
π¦ Nika 0.56.2 β Security Batch
Inference as Code Β· March 31, 2026 Β· 18 commits
| π§ͺ Tests | π§ Builtins | π¦ Transforms | π Providers |
|---|---|---|---|
| 9,109 | 30 | 31 | 7+1+1 |
β§ infer Β· β exec Β· β fetch Β· β invoke Β· β agent
12 fixes across 4 attack surfaces π‘οΈ
This is a pure security and hardening batch. No features. No refactors. Just 12 fixes that close real vulnerabilities discovered during the serve hardening sprint. SVG entity bombs, TOCTOU races, fetch overflow, serve DoS vectors β each one found, fixed, and tested.
The nika serve module that launched in v0.56.0 got particular attention: localhost-only binding by default, request timeouts, atomic job queue accounting, and worker lifecycle fixes. If you're running nika serve in production, this is a mandatory update.
π Security fixes
π£ SVG entity expansion bomb (billion laughs)
The SVG sanitizer accepted DOCTYPE declarations, which means an attacker could submit:
<!DOCTYPE svg [
<!ENTITY a "AAAA...">
<!ENTITY b "&a;&a;&a;&a;&a;&a;&a;&a;">
<!ENTITY c "&b;&b;&b;&b;&b;&b;&b;&b;">
<!-- ... exponential expansion -->
]>
<svg>&c;</svg>This causes exponential memory allocation β the classic "billion laughs" attack. The fix: strip all DOCTYPE declarations from SVG inputs before parsing. No DOCTYPE, no entity expansion, no bomb.
β±οΈ TOCTOU atomic write
nika:write had a time-of-check-to-time-of-use race:
Thread A: check if file exists β no
Thread B: check if file exists β no
Thread A: create file β success
Thread B: create file β overwrites Thread A's file
Now uses create_new (O_EXCL) for atomic file creation. If two threads race, one wins and the other gets a clean error. No silent overwrite.
π Secret redaction in events
BindingDefaultApplied events could leak API keys when a with: binding used $env.API_KEY with a default() fallback. The default value appeared unredacted in trace events. Now all binding events go through the secret redactor.
π Serve hardening (4 fixes)
| Fix | Before | After |
|---|---|---|
| Bind address | 0.0.0.0 (all interfaces) |
127.0.0.1 (localhost only) |
| Request timeout | None (infinite) | 30 seconds |
| Job counter | Non-atomic increment | compare_exchange (CAS) |
| Counter underflow | Decrement always | Decrement only if successfully incremented |
Warning
If you were relying on nika serve being accessible from other machines on the network, you now need to explicitly set the bind address: nika serve --bind 0.0.0.0:3000. The default changed to localhost-only for security.
π Engine fixes
5 engine fixes (expand)
-
Retry
max_attempts: 0rejected β AST analyzer now rejectsretry: { max_attempts: 0 }at analysis time. Previously, this silently created a no-op retry that would "succeed" without executing the task. Zero retries is never intentional β if you don't want retry, don't add the block. -
Duplicate task IDs in
include:β When including partial workflows without aprefix:, duplicate task IDs between the main workflow and the included partial were silently merged. Now the analyzer catches this and reports a clear error with both task locations. -
Fetch backoff overflow β Exponential backoff calculation could overflow to
Infinitythen wrap to0on very high retry counts (e.g.,max_attempts: 50). Now capped at a reasonable maximum delay. -
last(N)on strings and objects β Thelast(N)transform only worked on arrays. Now it also works on strings (last N characters) and objects (last N key-value pairs by insertion order). -
Invoke
timeout: 0rejected β Likeretry: { max_attempts: 0 }, a zero timeout on an invoke call is never intentional. Now rejected at runtime with a clear error.
π Extraction fixes
- HTML in
llm_txtextractor β Some sites return HTML "not found" pages at/llms.txtinstead of a proper 404. The extractor now detects HTML responses and skips them instead of returning garbled markup as if it were valid llm.txt content. - Duplicate task IDs in
include:β See above under engine fixes.
β»οΈ CI improvements
- Windows CI matrix β Windows is now part of the standard CI test matrix, catching platform-specific issues before release.
- release-plz scope β Fixed to test all workspace crates, not just the
nikabinary crate.
π Test evolution
v0.55 ββββββββββββββββββββ 9,086 tests
v0.56 ββββββββββββββββββββ 9,093 tests (+7)
v0.56.2ββββββββββββββββββββ 9,109 tests (+16) β you are here
Note
+16 tests specifically for serve hardening scenarios: CORS, auth edge cases, concurrent job submission, and SVG sanitization.
π¦ Install
| Method | Command | |
|---|---|---|
| π | Quick | curl -fsSL https://raw.githubusercontent.com/supernovae-st/nika/main/install.sh | sh |
| πΊ | Homebrew | brew install supernovae-st/tap/nika |
| π¦ | npm | npx @supernovae-st/nika |
| π¦ | Cargo | cargo install nika |
| π³ | Docker | docker run --rm ghcr.io/supernovae-st/nika:0.56.2 |
| π» | VS Code | Search "Nika" or ext install supernovae.nika-lang |
Made with π by SuperNovae Studio β Open Source, AGPL-3.0
Full Changelog: v0.56.1...v0.56.2