Skip to content

backlog: file #1237-#1241 -- decompression ceilings, listing-name containment, and three FHIR findings - #363

Merged
wshallwshall merged 6 commits into
mainfrom
claude/builder-2-session-802d3a
Aug 13, 2026
Merged

backlog: file #1237-#1241 -- decompression ceilings, listing-name containment, and three FHIR findings#363
wshallwshall merged 6 commits into
mainfrom
claude/builder-2-session-802d3a

Conversation

@wshallwshall

Copy link
Copy Markdown
Collaborator

Files five backlog items from Lane B. Docs-only: docs/BACKLOG.md, +121 lines, 0 deletions, no
other file touched.

commit item
4c4a090 #1237 require an explicit decompression ceiling on the Handler-facing primitives
766011d #1238 contain the remote listing name by rejecting it, never rewriting it
3414f06 #1239 fhir.py's two control-char predicates are identical today -- latent drift
6bb4872 #1240 + #1241 FHIR grammar-gate newline; operator-config values reach sinks unscreened

Why these are safe to land as filings

Every one is an OPEN ledger filing -- a to-do, not a shipped claim about the engine. Each carries
the clause that keeps it honest, and none asserts a live exposure or moves a verdict:

  • #1237 states explicitly it does not move ASVS 5.2.3 by itself.
  • #1238 records an owner ruling of 2026-08-13 verbatim; states the cell holds at partial and that
    this is a build item, not a rescore.
  • #1239 leads with "the two predicates are byte-identical TODAY" and says it must not be cited as
    evidence of a current gap.
  • #1240 leads with "NOT EXPLOITABLE TODAY" and gives the mechanism.
  • #1241 names all three sinks and says fixing one misses the point.

Severity statements are written in the conditional per CLAUDE.md section 0.

Conflict resolution

The branch conflicts with main positionally only: both sides append at the tail of
docs/BACKLOG.md. Resolve keep-both-sides.

That is a measured result, not the default assumption. main gained a correction commit
(9760eb9, which amended #1131 and #1020) plus #1236 and #1242, and a correction landing beside an
untouched document is exactly the setup where a mechanical merge silently preserves a superseded
citation -- no marker, both sides present, everything green. So what these five items actually cite
was checked: #1129, #1107, #1130 and each other. None cites #1131 or #1020. Nothing the
correction commit touched is load-bearing for anything here.

Had even one of the five quoted #1131's pre-correction text, keep-both-sides would have been wrong
and silent.

Verification

  • base fd2d8325 is a real ancestor of main -- not stacked on an unmerged PR head
  • range is docs-only; filtering the file list for anything that is not docs/BACKLOG.md returns empty
  • parse_items: all five present, all OPEN, exactly one status banner each

Checked independently by both Lane B and the coordinator, agreeing on every mechanical fact.

…he Handler-facing primitives

Splits the BUILD half out of #1129 (ASVS 5.2.3) so the research item can close
on its research. All three *_decompress primitives in parsing/compression.py
default max_output_bytes=None, so a Handler author who does not think about a
ceiling silently gets none.

Measured on 9d98f33 by loading the module directly with default arguments:
65,982 bytes in, 67,108,864 out across 8 members (1017:1), nothing raised.
This is not bounded by the transports -- the File connector decompresses
single-stream gzip only, so no transport ceiling ever sees a zip expansion.

The item records why a required keyword is not the move #1129 forbids (a
parameter with no default is a gate that refuses when the precondition is
absent, not a new default), scopes OUT the output-discarding pre-pass with its
runtime cost stated as an owner call, and states explicitly that it does not by
itself move the ASVS cell -- the verdict is the assessor's and the vault
scorecard is the record of record.

Number allocated atomically via scripts/coord/alloc.ps1, never by grepping.
…t, never rewriting it

The BUILD half of #1130 (ASVS 5.3.2, which holds at partial). Records the
owner ruling of 2026-08-13: reject, never mutate.

The item exists mainly to stop a later reader reaching for posixpath.basename,
which is the obvious fix and is actively harmful. Measured on 3.14.6:

  basename('../../etc/adt_20260812.hl7') -> 'adt_20260812.hl7', which rejoins
  to a REAL file, so a hostile entry would drive retrieve and then the
  after_read action against a file it does not name -- including remote delete.

  basename('..\..\etc\passwd.hl7') is UNCHANGED; posixpath tokenizes only '/'.

  Its output can never contain '/', so any check placed after it is unreachable
  and a traversal test would go green for the wrong reason.

  Under after_read="leave" the alias and the real file hash to the SAME dedup
  key (both 1c2195def3461a12), so one clinical message is silently skipped --
  a section 2 count-and-log violation reached by way of the security fix.

Also records that the NLST arm's basename stays (some servers return full
pathnames from NLST) but must never be cited as containment, that no cell
anchors it today, and the honest limit: name containment is ours, resolved-path
containment is not.

No closed consumer count is given. The set grew at all four measurement passes
and never shrank, which is itself the argument for one chokepoint at the source.

Number allocated atomically via scripts/coord/alloc.ps1.
…tical today

Records a LATENT drift hazard found during #1107's ASVS 1.2.2 surface
enumeration, and records it with its current identity MEASURED so a later
reader cannot mistake it for a live divergence.

_reject_control_chars (fhir.py:166, path context, raises NegativeAckError) and
_has_control_char (fhir.py:658, flat-query context, returns bool) compute the
byte-identical expression:

  any(ord(ch) < 0x20 or ord(ch) == 0x7F for ch in ...)

The differing wrappers are CORRECT and must not be collapsed: a raise suits the
path context, a bool suits the query context, and the query path deliberately
screens both the raw and the percent-decoded string, which one call could not
do. Only the duplicated predicate is at issue.

The hazard is future-tense: widening one for C1 controls or U+2028/U+2029 would
silently leave the other narrower. The durable control is a test asserting the
two agree across a shared corpus, which is worth more than the extraction.

Number allocated atomically via scripts/coord/alloc.ps1.
Filed together because they came out of one analysis pass and are docs-only;
they remain independently actionable.

#1240 is a BUG. Both FHIR grammar regexes anchor with '$', which in Python
matches before a trailing newline, so _FHIR_ID_RE.match("abc\n") returns True.
The item states its own reachability honestly: NOT exploitable today, because
the write path screens control chars before the gate (:424, :463) and quote()
encodes the newline to %0A on both paths. But the fhir_lookup READ path
(:705-718) has no control-char screen, so there the gate is the sole grammar
control and admits a value its grammar excludes. match -> fullmatch.

#1241 is a MISSING CONTROL, and its subject is the asymmetry rather than any
one site: conditional_query reaches a URL query (:431) and the If-None-Exist
header (:436) unscreened, while the versionId limb at :446/:449 in the same
file deliberately rejects-not-encodes for exactly that threat. dicomweb.py:241
is folded in as the third instance. The item records that ENCODING is the wrong
fix -- CONNECTIONS.md:1479 documents 'identifier=sys|val' as intended and
test_fhir_transport.py:220 pins it -- so a construction-time screen is correct.

Numbers allocated atomically via scripts/coord/alloc.ps1.
Resolves the single tail-append conflict in docs/BACKLOG.md by union, ordered
numerically: main's #1236, then #1237-#1241, then main's #1242.

Deliberately NOT a hand-assembled "keep every line" merge. Main modified two
lines in place since fd2d832 -- the #1020 summary row and the "THE REMEDY IS
STRONGER" limb -- and my branch carries the pre-correction text as untouched
context. The three-way merge takes main's side for both; verified by comparing
the merged lines byte-for-byte against origin/main's versions rather than by
counting occurrences.

Verified after resolving: zero deletions against origin/main; exactly five
added headings (#1237-#1241); docs/BACKLOG.md the only file differing from
main; no conflict markers; parse_items reads 273 items with all seven of the
tail items OPEN and in numeric order.
@wshallwshall
wshallwshall enabled auto-merge (squash) August 13, 2026 11:27
@wshallwshall
wshallwshall merged commit c4c6863 into main Aug 13, 2026
33 of 34 checks passed
@wshallwshall
wshallwshall deleted the claude/builder-2-session-802d3a branch August 13, 2026 11:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant