Files
LumaWeb/state/evidence/S00-018-review.md
T
wt 74e1fd87d9 S00-018: Approve bounded XML ingress after independent framing checks
Changes: Accept the isolated S00-018 ingress experiment and bounded ADR; record independent security findings and review handoff. Preserve all browser, live WSS, interoperability and production resource limitations.
Validation: Fresh-cache npm ci and all 55 integrated tests passed on Node 24.21.0/npm 11.19.0; six additional adversarial documents rejected before real JXT.parse with stale callback/fresh attempt checks. Verified ten dependency licenses/integrities, 340 unchanged Stanza files, upstream saxes license bytes and matching digests. Stock defects reproduced; make check passed 72 tooling tests. Initial getter-only tracing attempt failed and is recorded separately. Scope/whitespace inspected; no browser or live WSS test.

Task: S00-018
Agent: auto-security-64dc2d9fa232
Role: security
Action: review
Status: done

Task title: Validate bounded standalone XML ingress for the XMPP candidate
2026-10-15 02:35:56 +07:00

7.9 KiB

S00-018 independent security review

Reviewer: auto-security-64dc2d9fa232 (security). Executor: auto-protocol-89fe6563092c (protocol). Date: 2026-10-15. Decision: approve the bounded standalone XML ingress experiment and its ADR.

Input: master/startup/role/workflow documents, assigned show/packet, required TESTING/protocol role/ADR registry/blocker; exact ACC-004/NET-003/NET-004; accepted scope, stack and SASL ADRs, direct dependency evidence/reviews/handoffs; original parser blocker evidence/probe; executor source/tests/message/handoff. Output: independent review evidence, accepted bounded ADR metadata and handoff. No new shared contract or application implementation is introduced.

Findings against acceptance

Implementation commit e2b4dbdb76 and executor commit message match the isolated transport integration, fixtures, exact pins, notices and limitations. Scoped source and generated/state transition diff were examined. Source paths stay within parser-validation and its ADR; other paths are workflow metadata. Working tree was clean before review metadata. No specs, shared interfaces, parent candidate, SASL implementation or plan definition edit.

Finite UTF-16 precheck precedes TextEncoder, bounding its temporary allocation; 4096-byte precheck precedes SAX construction/write. A fresh namespace-aware XML 1.0 document parser validates every message and close() enforces completion. Depth 8, elements 32, total attributes 16 including xmlns, aggregate attribute units 1024, names 128 and decoded values 256 are inclusive local budgets before JXT.parse/registry.import. SAX may retain one token/attribute before callbacks, but the byte ceiling already bounds it. No DTD fetching/custom entities or handwritten XML syntax parser. DTD/comment/PI/declaration reject. Malformed, incomplete, multiple-root and binary input cannot emit an earlier complete root. The aggregate-limit fixture and Unicode boundary import the exact actual body.

Installed public Client.transports constructor declaration and Transport interface agree with actual Client.connect selection. This bypasses the stock persistent parser through a supported constructor registration, without a vendor patch or post-import interception. Tests run actual Client/JXT/registry/queue; socket injection captures external effects only and tracing invokes real methods. Original large/deep/cross-message failure categories reject, with no stanza or stream:start delivery. Disconnect marks terminal, detaches all four handlers, clears socket/config/stream, and notifies Client reset. Failed restart and old callbacks cannot revive the attempt; fresh Client.connect accepts valid input. No raw XML/error text log/event, real credentials or conversations, crypto, plaintext fallback, TLS/CORS bypass or invented channel binding found.

Dependency graph has ten exact installed versions/licenses and HTTPS/SHA512 lock entries. Preserved notices match shipped license texts; upstream saxes v6.0.0 LICENSE independently retrieved over normal HTTPS matches byte-for-byte. Strict TLS/engines and disabled lifecycle scripts retained. Stanza's 340 files byte-match the parent candidate. Lock/license checks establish repeatability and notices, not supply-chain provenance or vulnerability clearance.

No acceptance defect or missing review input found. This is a local ingress experiment, not a production transport/library selection. Browser message allocation occurs before JS checks; aggregate traffic, queue growth, CPU rate and downstream work remain unbounded. Full stream sequencing/error negotiation, redirect/keepalive/language inheritance and exhaustive SAX/JXT equivalence are not certified. Browser bundling/runtime, real WSS/server/client interoperability, load/exhaustion and advisory/provenance audit were not executed. ACC/NET product obligations and the remaining S00-003 experiment are not accepted by this review.

Actual independent commands and results

All Node/npm commands used PATH=/private/tmp/luma-stack-runtime/node-v24.21.0-darwin-arm64/bin:$PATH. Previously reviewed isolated runtime reused; no new archive verification claimed.

  • python3 scripts/tasks.py resume --agent auto-security-64dc2d9fa232; show S00-018; packet S00-018 --agent auto-security-64dc2d9fa232: exit 0 each. Review status, distinct executor and done prerequisites confirmed; reviewer did not claim.
  • Read-only git log --all --grep='^S00-018:' --oneline, git show e2b4dbd --stat, scoped source and state/generated diffs; git status --short: exit 0. Initially clean tree. Required artifact/source/test/dependency reads completed.
  • npm ci --prefix experiments/0002-xmpp-library/parser-validation --ignore-scripts --no-audit --no-fund --cache /private/tmp/luma-parser-review-64dc2d9fa232 --fetch-retries=0 --fetch-timeout=15000: exit 0, new reviewer cache, ten packages.
  • npm test --prefix experiments/0002-xmpp-library/parser-validation: exit 0, 55 passed, zero failed/skipped/cancelled, 335.373333 ms.
  • python3 experiments/0002-xmpp-library/parser-validation/check-dependencies.py: exit 0, ten exact dependency/license/integrity checks and 340 unchanged files. Lock SHA256 35b177d57aaf81778eaf3d3321b3f77eb1e755a46abee784ef62b8959aedd63c; ingress e6399ff581f59d1f09b471234d6e4b8f2ed6b61804aa4eb0eef7dd3f8e3f2dbc; saxes license 0fac2374380621b22e6b50451057721a9c52935b02d16d106a9f04897f061d0e. All match executor evidence.
  • node experiments/0002-xmpp-library/parser-probe/reproduce.mjs: exit 0, stock accepted 18-write/65536-byte reassembly, 1048576-byte body and 256 nested children. This reproduces defects, not safe behavior.
  • Inline Node --input-type=module reviewer assertions: exit 0. Six additional adversarial documents: complete stream-open plus unfinished second root, 17 total namespace attributes, surrogate char reference, literal forbidden CDATA close in text, 257 decoded character references in an attribute and unfinished CDATA. Traced real Parser.parse (the JXT exported implementation) invoked zero times on rejection and once per fresh boundary document. All four captured callbacks replayed after reconnect; fresh transport remained intact, no old delivery/error, exact boundary body imported. Tracing is process memory only; no vendor file edit or fabricated parser result.
  • npm --version: exit 0, 11.19.0; initial Node tracing error reported v24.21.0.
  • Inline Python urllib HTTPS retrieval/assertion of the versioned saxes LICENSE: exit 0; preserved bytes equal upstream.
  • make check > /private/tmp/luma-S00-018-64dc2d9fa232-check.log 2>&1: exit 0; 72 tooling tests in 17.775s. Foundation integrity only.
  • git diff --check before review metadata: exit 0; final metadata whitespace and scope checked before approval.

Exploratory failed check: first inline Node tracing tried assigning jxt.parse; exit 1, getter-only export TypeError before any assertions ran. Corrected tracing wraps the writable underlying Parser module export and calls its real function; subsequent assertions above passed. This initial attempt is not a passed check. No required artifact or environment blocker resulted.

Primary sources independently opened on 2026-10-15: RFC 7395 sections 3.2/3.3.3 for text/standalone framing, first character and one element per frame; versioned saxes README for public parser/options/entity and token-limit behavior; and versioned license. The RFC supplies framing requirements, not numerical budgets. Shipped pinned API/source supplies the exact extension and allocation-order evidence.

Reviewer changes only ADR acceptance metadata/paragraph, report, handoff and mandatory commit message, plus the CLI transition. Coordinator must commit before any further session. This reviewer exits after approve and does not continue S00-003 or launch another agent.