fix(package): scan semantic content for internal references - #618
fix(package): scan semantic content for internal references#618mldangelo-oai wants to merge 4 commits into
Conversation
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
…ckage-semantic-content-scan
…ckage-semantic-content-scan
|
@codex review |
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
kmbroai
left a comment
There was a problem hiding this comment.
Critical review
Reviewed head 35cc277e85843e61a6cd55a051f4425bc9fdd6d7.
Recommendation: keep semantic-content scanning; no new blocking correctness defect found in the reviewed changes. Decoding compressed archive bytes as text can reject a clean package because of coincidental byte sequences. Scanning filenames, actual text, and decompressed bundled code fixes the right problem without weakening the intended disclosure check.
Correctness
check-package.mjs validates the closed archive format before extraction, compares the native tar listing with parsed paths, verifies the extracted tree and sizes, and cleans up in finally. Scanning complete headers retains metadata coverage, while PNGs remain restricted to the known digest instead of arbitrary text interpretation. The Brotli helper checks decompression consumption, so trailing data is not silently ignored.
Passing the already-read archive on stdin avoids Windows drive-letter interpretation and a separate path reread. Keeping the caller's working directory also avoids accidentally selecting a relative-PATH executable from beside the archive. The --ignore-zeros use is acceptable here specifically because the preceding parser proves the remainder is zero padding; it should not be copied to an unconstrained archive reader.
Simplification and necessity
The semantic scanner is the essential fix. The extra parser/extractor agreement is defensible only as validation of this package's controlled plain-ustar contract—not as a general tar library. Preserve that narrow scope. An npm pack-format change should cause one explicit compatibility update, not accumulate ad hoc support for every extension.
There are three native tar passes plus the in-memory parser and filesystem walk. I would avoid adding further independent interpretations. If this becomes costly to maintain, evaluate a single maintained archive reader with equivalent path/type/metadata guarantees; do not simply remove checks while retaining native extraction. The existing expanded-size bound is unchanged by this PR and is not a newly introduced scan-input cap.
Verification
Ran the five focused package helper suites: 25 passed, 0 failed, 72 assertions, including binary-marker false positives, decompressed content, tar forms/listing, provenance, and timeout helpers. Linux with Bun 1.3.14 / Node 22.13.1 and cached dependencies. I did not independently rebuild the full npm archive, run installed-package smoke, or execute native Windows/macOS packaging, so the author's broader artifact claims are not my verification results.
Summary
The package disclosure check decoded the complete npm tar stream as UTF-8. Valid compressed binary metadata could therefore resemble an internal reference even when every publishable path, text file, and decompressed payload was clean.
Scan the semantic contents that would actually be published. The checker now validates the package's canonical plain-ustar contract, extracts it with the local tar implementation into a private temporary directory, and scans and hashes the resulting regular files. Raw compressed bytes and tar padding are no longer treated as text.
Changes
Testing
�Go/1sequence failed the old whole-tar scan even though its decompressed payload was empty; the semantic scan accepts it.6d0bc657, both hosted Windows verification jobs failed because GNU tar interpreted the drive-letter archive path as remote-host syntax. Tar now receives only stdin.PATHbegan with a relative entry. Keeping the caller working directory prevents the archive directory from participating in executable resolution.EPIPE. Central--ignore-zerosnow drains only padding that the strict parser has already proved is all zero; short listing, verbose listing, and extraction all complete.--noEmit, package build, and Node syntax checks passed.da76cfe405b5ff3c45ac3e356461c09b742367503d739fd18d471683ae96e531.Risk and rollout
The publishable package contents do not change. The checker intentionally accepts only the plain-ustar shape emitted by the current package build; unsupported tar metadata fails closed instead of being interpreted by a second custom tar implementation. The current artifact uses 265 regular type-
0entries with a maximum path length of 87 bytes and requires no compatibility exception.The semantic scan preserves internal-reference coverage for paths, complete ustar headers, normal text files, and decompressed Brotli payloads. PNG files remain digest-allowlisted, and all extracted regular-file bytes remain subject to the existing cumulative bound. The temporary extraction tree is private and removed on success or failure. The validation-stage tar subprocesses never receive the archive path: Node reads the archive bytes, and tar receives those bytes on stdin plus an absolute extraction destination.
Public disclosure review