S00-018: Bound standalone XML ingress before Stanza parsing and import
Changes: Add an isolated public transport integration with finite byte, depth, element and attribute budgets; validate complete text XML with pinned saxes before real JXT parsing/import. Add adversarial and boundary fixtures, terminal cleanup tests, dependency notices and a proposed parser ADR. Validation: Fresh-cache npm ci and npm test passed all 55 tests with Node 24.21.0/npm 11.19.0. Reproduced three stock parser failures, checked ten exact dependency licenses/integrities and 340 unchanged Stanza files; make check passed 72 tooling tests. Scope and whitespace inspected. Browser runtime, live WSS and interoperability were not tested. Task: S00-018 Agent: auto-protocol-89fe6563092c Role: protocol Action: claim Status: review Task title: Validate bounded standalone XML ingress for the XMPP candidate
This commit is contained in:
1 parent
f556fc0deb
commit
e2b4dbdb76
19 files changed
+1648
-8
No files matched your search
@@ -0,0 +1,4 @@
|
||||
Bound standalone XML ingress before Stanza parsing and import
|
||||
|
||||
Changes: Add an isolated public transport integration with finite byte, depth, element and attribute budgets; validate complete text XML with pinned saxes before real JXT parsing/import. Add adversarial and boundary fixtures, terminal cleanup tests, dependency notices and a proposed parser ADR.
|
||||
Validation: Fresh-cache npm ci and npm test passed all 55 tests with Node 24.21.0/npm 11.19.0. Reproduced three stock parser failures, checked ten exact dependency licenses/integrities and 340 unchanged Stanza files; make check passed 72 tooling tests. Scope and whitespace inspected. Browser runtime, live WSS and interoperability were not tested.
|
||||
@@ -0,0 +1,118 @@
|
||||
# S00-018 executor evidence
|
||||
|
||||
Agent: auto-protocol-89fe6563092c (protocol). Date: 2026-10-15.
|
||||
Result: bounded standalone XML ingress experiment and proposed ADR; independent security review pending.
|
||||
|
||||
Input: assigned master/startup/role/workflow instructions; resume/show/packet;
|
||||
required TESTING, decisions/README, blocker S00-018; exact ACC-004/NET-003/NET-004;
|
||||
accepted scope/stack/SASL ADRs and all direct dependency evidence/reviews/handoffs;
|
||||
original parser blocker evidence/handoff/probe; shipped Client/Transport/JXT and
|
||||
saxes API/source. No missing required input. No new shared contract is needed.
|
||||
Output: only experiments/0002-xmpp-library/parser-validation and
|
||||
docs/decisions/0002-xmpp-parser-validation.md, plus workflow metadata.
|
||||
|
||||
## Actual changes and demonstrated acceptance
|
||||
|
||||
Public Client.transports constructor registration and explicit single transport
|
||||
selection run real Client.connect. Per-message type/unit/UTF-8 byte checks precede
|
||||
new saxes XML 1.0 namespace-aware document parsing. Callback depth/element/
|
||||
attribute/name/value budgets precede candidate JXT.parse/registry.import.
|
||||
SAX close detects incompleteness; malformed/multiple-root documents never import
|
||||
an earlier complete root. All XML syntax uses existing libraries. Global input
|
||||
bytes bound unfinished/oversized tokens before event callbacks. No vendor patch,
|
||||
late interception, fixture parser or handwritten XML security parser.
|
||||
|
||||
Local inclusive budgets: 4096 UTF-8 bytes, depth 8, elements 32, attributes 16
|
||||
including namespace declarations, aggregate attribute name+decoded value units
|
||||
1024, names 128, decoded attribute values 256. Combined boundary fixture meets
|
||||
all aggregate ceilings simultaneously and yields its exact real imported body;
|
||||
separate Unicode/name/value equality cases pass. Limits remain experiment policy,
|
||||
not product/shared contract decisions. DTD/comment/PI/declaration reject;
|
||||
namespace, entities, malformed chars and duplicate attributes checked by saxes.
|
||||
|
||||
55 tests use actual Client/JXT/registry/queue. FixtureSocket captures only socket
|
||||
effects; registry tracing calls the real import. Original 1 MiB body, depth 256,
|
||||
and 18-message partial-document categories reject terminally. Bad input never
|
||||
delivers stanza or stream:start, invalid syntax/budgets never reach registry
|
||||
import, and old captured callbacks cannot revive the attempt. Callback detachment,
|
||||
stream/config cleanup, fresh Client.connect, successive independent documents,
|
||||
stream open/close/restart, export/send and subprotocol/socket failure are tested.
|
||||
No peer payload/error text is logged or raw-evented.
|
||||
|
||||
## Actual commands and results
|
||||
|
||||
All Node/npm commands used
|
||||
PATH=/private/tmp/luma-stack-runtime/node-v24.21.0-darwin-arm64/bin:$PATH,
|
||||
the previously reviewed isolated Node 24.21.0/npm 11.19.0, from project root.
|
||||
No system install or certificate override. Exact engine pins and strict SSL
|
||||
remain in manifest/.npmrc. No new runtime archive verification claimed.
|
||||
|
||||
| Command | Exit | Observed result |
|
||||
| --- | --- | --- |
|
||||
| python3 scripts/tasks.py resume --agent auto-protocol-89fe6563092c | 0 | Assigned S00-018 in_progress, no repeat claim |
|
||||
| python3 scripts/tasks.py show S00-018; packet S00-018 --agent auto-protocol-89fe6563092c (separate invocations) | 0 each | Scope/prerequisites/requirements confirmed |
|
||||
| node experiments/0002-xmpp-library/parser-probe/reproduce.mjs | 0 | Stock accepted 18 writes/65536 body bytes, 1048576-byte body, 256 nested children; defect reproduction, not safe result |
|
||||
| npm view saxes@6.0.0 version license engines dependencies --json --cache /private/tmp/luma-parser-cache --fetch-retries=0 --fetch-timeout=15000 --strict-ssl=true | 0 | 6.0.0, ISC, Node >=v12.22.7, xmlchars ^2.2.0 |
|
||||
| npm install --prefix experiments/0002-xmpp-library/parser-validation --ignore-scripts --no-audit --no-fund --cache /private/tmp/luma-parser-cache --fetch-retries=0 --fetch-timeout=15000 | 0 | Ten packages, independent lock generated |
|
||||
| npm test --prefix experiments/0002-xmpp-library/parser-validation | 0 | 55 passed, zero failed/skipped/cancelled, 378.193208 ms |
|
||||
| npm ci --prefix experiments/0002-xmpp-library/parser-validation --ignore-scripts --no-audit --no-fund --cache /private/tmp/luma-parser-clean-89fe6563092c --fetch-retries=0 --fetch-timeout=15000 | 0 | Actual clean install with fresh cache, ten packages, scripts disabled |
|
||||
| npm test --prefix experiments/0002-xmpp-library/parser-validation after ci | 0 | 55 passed, zero failed/skipped/cancelled, 341.101792 ms; runtime/test source unchanged afterward |
|
||||
| curl --fail --silent --show-error https://raw.githubusercontent.com/lddubeau/saxes/v6.0.0/LICENSE -o /private/tmp/luma-parser-saxes-LICENSE | 0 | Upstream full ISC lineage/historical MIT notice retrieved through verified HTTPS; preserved in experiment |
|
||||
| Corrected inline Python license collector | 0 | Ten exact installed versions/licenses/HTTPS/SHA512 entries; preserved shipped notices plus upstream saxes LICENSE |
|
||||
| python3 experiments/0002-xmpp-library/parser-validation/check-dependencies.py | 0 | Ten exact graph/license checks; all 340 Stanza files byte-match original candidate |
|
||||
| make check | 0 | 283 tasks, 22 stages, 221 requirements, 211 Web requirements, revision 44; 72 tooling tests in 18.439s |
|
||||
| git diff --check; git status --short --untracked-files=all (separate checks) | 0 each | Scoped source only plus coordinator state claim before evidence |
|
||||
| Inline Python authored-file whitespace/final-newline checks | 0 | All 12 authored experiment/ADR files checked, including untracked files |
|
||||
|
||||
Exploratory failures are not passed checks: guessed transports/index.d.ts absent
|
||||
(actual Transport API is index.d.ts); first license collector failed because
|
||||
saxes tarball omits LICENSE (Python AssertionError, surrounding shell ended 0
|
||||
because following npm ci succeeded). Guessed upstream root saxes.ts URL returned
|
||||
404; subsequent head/rg saw no file (combined command exit 2). Actual upstream
|
||||
LICENSE fetch succeeded; no required artifact is missing and no source patch
|
||||
was attempted. These failures do not affect the reproduced acceptance checks.
|
||||
|
||||
## Primary sources and dependencies
|
||||
|
||||
Opened RFC 7395 §3.2/3.3.3 through web tools; versioned saxes README/package source,
|
||||
upstream Stanza Client source; inspected installed version-pinned declarations
|
||||
and implementation. Direct links and constraints are in ADR. Sources inspected
|
||||
2026-10-15. The supported extension claim rests on public shipped constructor
|
||||
registry/Transport interface and actual Client selection, not private fields.
|
||||
|
||||
New direct pins saxes 6.0.0 ISC / xmlchars 2.2.0 MIT, existing Stanza 12.22.1 MIT.
|
||||
Other exact installed packages: @types/node 22.20.5, @types/punycode 2.1.4,
|
||||
@types/ws 8.18.2, punycode 2.3.1, sdp 3.2.2, undici-types 6.21.0, ws 8.22.0,
|
||||
all MIT. Inventory/notices and lock are preserved. Saxes release is older;
|
||||
continued support/advisory/provenance clearance is not assumed. Node-focused
|
||||
CommonJS packages require browser bundling. Default adapter uses native browser
|
||||
WebSocket, URL, TextEncoder and private fields; fixture injection is explicit.
|
||||
|
||||
SHA256:
|
||||
- package-lock.json: 35b177d57aaf81778eaf3d3321b3f77eb1e755a46abee784ef62b8959aedd63c
|
||||
- bounded-ingress.mjs: e6399ff581f59d1f09b471234d6e4b8f2ed6b61804aa4eb0eef7dd3f8e3f2dbc
|
||||
- licenses/saxes-6.0.0-LICENSE: 0fac2374380621b22e6b50451057721a9c52935b02d16d106a9f04897f061d0e
|
||||
|
||||
## Limits and independent review input
|
||||
|
||||
No browser build/runtime, actual WSS/TLS/server handshake, auth changes,
|
||||
independent client interoperability, load/exhaustion benchmark or security audit
|
||||
was performed. No TLS/CORS bypass, real credentials/conversations, custom crypto
|
||||
or invented binding. Original candidate, reviewed SASL plugin, app modules,
|
||||
shared contracts, immutable specs and plan definitions unchanged. Git mutations
|
||||
and additional task/agent launch were not performed.
|
||||
|
||||
Browser WebSocket allocates a complete inbound message before JavaScript checks;
|
||||
this experiment bounds parser work afterward, not network-stack memory. SAX can
|
||||
store one token/attribute before a callback, bounded by the byte precheck. Total
|
||||
traffic, Client queues, downstream extension work and CPU rate are not bounded.
|
||||
Minimal transport lacks full stream-error/close negotiation/redirect/keepalive/
|
||||
language inheritance/stream sequencing. Complete SAX/JXT semantic equivalence
|
||||
is not certified. See README/ADR; these limits prohibit production-readiness
|
||||
claims but do not invalidate the assigned local parser/framing experiment.
|
||||
|
||||
Separate security reviewer must reproduce README clean install/tests/license
|
||||
checks, inspect actual scope/order/API/cleanup and compare this evidence and
|
||||
executor commit message with actual patch. ADR remains proposed and task is
|
||||
submitted for review, not done. Coordinator commits and launches fresh review;
|
||||
this executor stops after submit and does not resume S00-003.
|
||||
@@ -0,0 +1,39 @@
|
||||
# S00-018 handoff for independent security review
|
||||
|
||||
Executor: auto-protocol-89fe6563092c (protocol), 2026-10-15.
|
||||
Outcome: isolated bounded XML ingress experiment and proposed parser ADR.
|
||||
No blocker; implementation awaits independent security review.
|
||||
|
||||
Actual result: new public Client.transports constructor selected by actual
|
||||
Client.connect, finite byte precheck, fresh saxes strict namespace-aware XML 1.0
|
||||
validation/close per message, then actual JXT.parse/registry.import. Explicit
|
||||
local byte/depth/element/attribute/name/value limits apply before tree/import.
|
||||
Malformed/incomplete/multiple-root/binary/budget violations close attempt,
|
||||
detach callbacks, clear stream/config; stale callbacks cannot revive it. A fresh
|
||||
connection works. No persistent parser, vendor patch or custom XML syntax parser.
|
||||
|
||||
Pinned Node 24.21.0/npm 11.19.0 fresh-cache npm ci and 55 integrated tests passed;
|
||||
stock probe reproduced all three failures; license checks for all ten packages
|
||||
and byte comparison of all 340 Stanza files passed. make check: 72 tests passed.
|
||||
Commands/digests/failures/limits: state/evidence/S00-018-auto-protocol-89fe6563092c.md.
|
||||
|
||||
Next belongs only to security reviewer: inspect proposed
|
||||
docs/decisions/0002-xmpp-parser-validation.md, experiment source/tests/notices,
|
||||
executor diff/message and README. Run README commands with the reviewed isolated
|
||||
runtime at /private/tmp/luma-stack-runtime/node-v24.21.0-darwin-arm64/bin and a
|
||||
fresh reviewer cache. Verify budget/framing checks precede JXT allocations/import,
|
||||
actual Client registry selection, boundary success, zero delivery for bad input,
|
||||
terminal callback replay/cleanup and fresh attempts. check-dependencies.py also
|
||||
needs the original parent candidate installed for vendor comparison. Saxes
|
||||
published package omits LICENSE; preserved v6.0.0 upstream LICENSE and source are
|
||||
recorded. Keep ADR proposed until independent acceptance.
|
||||
|
||||
Limits: fixture socket only, no browser build/runtime or real WSS/server/client
|
||||
interop; byte checks begin after browser allocates the message. No aggregate
|
||||
traffic/Client queue/rate bounds or production policy. Minimal transport lacks
|
||||
full stream-error/close negotiation/redirect/keepalive/language inheritance/
|
||||
sequencing, and exhaustive SAX/JXT equivalence is not certified. Auth/crypto and
|
||||
accepted SASL experiment unchanged. No specs/shared interfaces/app modules or
|
||||
original candidate files changed. S00-003 remains separate; only reviewed done
|
||||
and coordinator commit allow a fresh original executor to continue it. This
|
||||
executor exits after submit; no commit/next agent/original work is performed.
|
||||
+31
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"revision": 43,
|
||||
"revision": 45,
|
||||
"tasks": {
|
||||
"S00-001": {
|
||||
"status": "done",
|
||||
@@ -1236,10 +1236,14 @@
|
||||
"completed_at": "2026-10-14T19:20:57+00:00"
|
||||
},
|
||||
"S00-018": {
|
||||
"status": "todo",
|
||||
"owner": null,
|
||||
"status": "review",
|
||||
"owner": "auto-protocol-89fe6563092c",
|
||||
"external_wait": false,
|
||||
"reason": null
|
||||
"reason": null,
|
||||
"started_at": "2026-10-14T19:24:01+00:00",
|
||||
"updated_at": "2026-10-14T19:31:32+00:00",
|
||||
"evidence": "state/evidence/S00-018-auto-protocol-89fe6563092c.md",
|
||||
"handoff": "state/handoffs/S00-018.md"
|
||||
}
|
||||
},
|
||||
"events": [
|
||||
@@ -1798,6 +1802,29 @@
|
||||
"from": "in_progress",
|
||||
"to": "blocked",
|
||||
"reason": "S00-003 cannot attest parser limits: Stanza 12.22.1 exposes no resource bounds and its persistent WebSocket parser accepts large/deep XML and reassembles incomplete documents across separate input messages."
|
||||
},
|
||||
{
|
||||
"revision": 44,
|
||||
"at": "2026-10-14T19:24:01+00:00",
|
||||
"action": "claim",
|
||||
"task": "S00-018",
|
||||
"agent": "auto-protocol-89fe6563092c",
|
||||
"role": "protocol",
|
||||
"from": "todo",
|
||||
"to": "in_progress",
|
||||
"reason": null
|
||||
},
|
||||
{
|
||||
"revision": 45,
|
||||
"at": "2026-10-14T19:31:32+00:00",
|
||||
"action": "submit",
|
||||
"task": "S00-018",
|
||||
"agent": "auto-protocol-89fe6563092c",
|
||||
"role": null,
|
||||
"from": "in_progress",
|
||||
"to": "review",
|
||||
"reason": null,
|
||||
"evidence": "state/evidence/S00-018-auto-protocol-89fe6563092c.md"
|
||||
}
|
||||
],
|
||||
"retired_agents": [
|
||||
|
||||
Reference in new issue
Block a user