You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit ec60a10
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: doc/05-vendored.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -167,7 +167,7 @@ Revert/restore/unwind code in the non-npm backends totals **about 3,540 lines**:
167
167
168
168
### 5.5 Security: zip inflate on committed artifacts (fixed, #587)
169
169
170
-
`zip_bytes_match_after_hashes` now streams each member through the Git SHA-256 reader with an 8 KiB buffer and checks the declared length against the bytes read; it no longer inflates members into a `Vec` sized by the archive's own header (#587). The maintainer ruled that this data is trusted not to be too big, so the fix streams instead of capping. {{C01}} Agent-mode jar verification still buffers each member. {{C51}}
170
+
`zip_bytes_match_after_hashes` now streams each member through the Git SHA-256 reader with an 8 KiB buffer and checks the declared length against the bytes read; it no longer inflates members into a `Vec` sized by the archive's own header (#587). The maintainer ruled that this data is trusted not to be too big, so the fix streams instead of capping. {{C01}} Agent-mode jar verification streams through the same hasher since #1253 (`hash::git_sha256::zip_member_git_sha256`); this function still runs its own lookup-and-hash loop. {{C51}}
171
171
172
172
It runs on:
173
173
- committed, tamperable artifacts (the NuGet hot path, `nuget_feed.rs:266`; the committed Maven jar, `maven_repo.rs:736` and `:1464`);
Copy file name to clipboardExpand all lines: doc/07-infra-agent.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -164,7 +164,7 @@ Added on 2026-10-07 by the October 7 reconciliation; owned by `audit-core`. Thes
164
164
|**Writes stay inside the project**| Every vendored and hosted write under `.socket/`, and every agent write, must stay inside the tree it was found in; links are refused, not followed. | One helper, `utils::containment`, now lstats every level from the project root: vendored writes, reverts and ledgers refuse a linked `.socket` (`vendor_dir_symlink_unsupported`), `get` hash-checks and stages inline blobs (#726), and agent writes that resolve outside the package are refused as `OutsideInstallTree` (#1042). #887 is closed as fixed by #1042. Remaining: agent-mode manifest and blob writes still follow a linked `.socket` (a known gap #1042 names), and rollback of an overwritten new file needs a pre-image store. {{C60}} |
165
165
|**Bytes are verified before they are trusted**| Patched content is hash-checked before any write; downloaded and inline blobs are checked against their name. | Agent apply verifies before writing; the inline-blob writer did not (fixed in PR #1042). Hosted rollback re-pins integrity from the registry (trust-on-rollback, E33/E45). |
166
166
|**No planted binaries**| Tools are resolved with `resolve_tool`, never by bare name in the scanned repo. | Fixed (#617). {{C04}} |
167
-
|**Untrusted archives are streamed**| Committed and service archives are hashed by streaming, never inflated into memory by their own header. | Vendored verify streams (#587); agent-mode jar verification still buffers (C51). {{C01}} |
167
+
|**Untrusted archives are streamed**| Committed and service archives are hashed by streaming, never inflated into memory by their own header. | Vendored verify streams (#587); agent-mode jar verification streams too since #1253 (C51). {{C01}} |
168
168
|**Updates are authentic**| Self-update and `install.sh` should verify a signature or attestation, not only a same-origin checksum. | Only a same-origin `SHA256SUMS`; immutable releases stop swaps of a published release, not a malicious new one. {{C72}} |
169
169
|**Tests never reach production**| Test children must not send telemetry or call production endpoints. | The workspace `[env]` table, `hermetic::command` and every workflow env block set `SOCKET_TELEMETRY_DISABLED`, and a test keeps the workflow copies in step (#1046). {{C66}} |
170
170
@@ -178,7 +178,7 @@ Added on 2026-10-07 by the October 7 reconciliation; owned by `audit-core`. Thes
178
178
- {{C26}} The vendored group-commit journal is replayed only inside `apply_lock::acquire`, so the lock-free readers never see a pending commit: after a crash past the journal, `vendor --check` fails every patch with `vendor_ledger_missing` (whose documented remedy is restoring `state.json` by hand) and pnpm `vex` omits the packages, while one locked command rolls the commit forward to the uninterrupted result (proved twice with `group_commit_file@1`).
179
179
- {{C49}} Registry downloads (`build_registry_client`, `maven_repo::fetch_registry_bytes`) now share `ApiTimeouts`' 10 s connect + 60 s idle bound instead of a 60 s total deadline, so a slow but progressing artifact download completes (#876).
180
180
- {{C50}} Artifact GC has two retention policies. `ArtifactReferences::after_removal` (rollback, remove) keeps every active patch's beforeHash blobs so offline rollback keeps working (#600), while `for_apply` (repair, `scan --prune`) keeps only afterHash blobs. On `9c43dfc`, `repair --offline` deleted an active patch's original, and `rollback --offline` then exited 1 (twice), telling the user to run `repair`, which only ever downloads afterHash blobs. `cleanup_unused_blobs`/`_archives` and `format_cleanup_result` have no production caller.
181
-
- {{C51}} Agent-mode jar verification (`jvm_jar::verify_member_bytes`, used by `apply`, `rollback` and `vex` for Maven/Gradle member records) inflates each patched member into a `Vec` before hashing, while its vendored twin `zip_bytes_match_after_hashes` streams since #587. On `9c43dfc`, a jar with one deflated 1 GiB member peaked at 1,067 MiB RSS through the agent routine and 26 MiB through the vendored one (twice). One streaming member-hash helper replaces both.
181
+
- {{C51}} Agent-mode jar verification (`jvm_jar::verify_member_bytes`, used by `apply`, `rollback` and `vex` for Maven/Gradle member records) streams each patched member through `hash::git_sha256::zip_member_git_sha256`since #1253 (302 → 30 MiB peak RSS on a 256 MiB member). The vendored twin `zip_bytes_match_after_hashes` still has its own lookup-and-hash loop; moving it onto the helper is the remaining slice.
182
182
- {{C48}} Child processes share one deadline: `utils::process::output_within` bounds the crawler probe runners (`run_resolved`, `PROBE_TIMEOUT` 10 s), `pipenv`, `hatch`, the self-update `sanity_exec` (#886) and the PDM site probe (#1106), so a `gem` shim that never answers no longer hangs a local `scan`. Only the `git check-ignore` exchange in `vendor/npm_dir.rs` still hand-rolls its timeout (#1067).
183
183
- {{C77}} The OpenVEX document (`vex --output` and the embedded `--vex` of `apply`/`vendor`/`scan`) is the one CLI write outside `utils::fs`: `generate_vex` calls `tokio::fs::write`, which truncates in place, so a failed write (ENOSPC on `823810a`) leaves a truncated document that starts with an OpenVEX header, and the stale-document cleanup, which removes only a parseable document, keeps it. That breaks the documented failure contract and `durability.rs`'s claim that every write is staged.
184
184
- {{C78}} The hosted upstream restore (`rollback`/`remove` of hosted pins, the hosted → vendored takeover and eject) re-resolves every pin from the public registry with an unbounded `join_all` in five formats (npm/vlt, PyPI, cargo, Go, Composer), while `utils::concurrent::registry_concurrency()` (cap 4; 1 under a tight fd limit), added for public registries in #1039, has no caller. On `f3c6313`, 40 npm pins put 40 requests in flight (twice); the registry client has no 429 handling.
[agent] 2026-10-09: architecture refactor run (merge record)
2
+
3
+
- main: `e9be7462`. #1253 (C51, agent-mode jar members streamed through `hash::git_sha256::zip_member_git_sha256`) merged.
4
+
- Register: C51 → partly fixed (#1253); the `vendor/common.rs::zip_bytes_match_after_hashes` caller remains (now free: #1227 merged). Doc passages rewritten: 07 "Untrusted archives are streamed" row and the C51 bullet; 05 #587 paragraph.
5
+
- Follow-up for the #914 remainder: the final reviewer asked for a committed test of a member whose declared size disagrees with its stream (`NotFound`), alongside the vendored one near `vendor/common.rs:1154`.
| C48 | 2 | Child processes had no shared deadline; crawler probes called `output()` unbounded, so a hung `gem` shim hung `scan`. | new finding |#845, #1067| partly fixed (#886, #1106); the `npm_dir` git exchange keeps a hand-rolled deadline (#1067) |
50
50
| C49 | 2 | Registry downloads used a 60 s total deadline. | new finding |#872| fixed (#876) |
51
51
| C50 | 2 | Artifact GC has two retention policies: `after_removal` (rollback, remove) keeps active patches' beforeHash blobs for offline rollback, `for_apply` (repair, `scan --prune`) drops them; offline rollback then fails and names `repair`, which never fetches beforeHash blobs. `cleanup_unused_blobs`/`_archives` are dead. | new finding |#893| filed #893|
52
-
| C51 | 3 | Agent-mode jar verification (`jvm_jar::verify_member_bytes`; apply, rollback, vex) buffers each patched member before hashing, while vendored `zip_bytes_match_after_hashes` streams since #587: 1,067 MiB vs 26 MiB peak RSS on a 1 GiB member. | new finding |#914| filed #914; in PR #1253|
52
+
| C51 | 3 | Agent-mode jar verification (`jvm_jar::verify_member_bytes`; apply, rollback, vex) buffers each patched member before hashing, while vendored `zip_bytes_match_after_hashes` streams since #587: 1,067 MiB vs 26 MiB peak RSS on a 1 GiB member. | new finding |#914| filed #914; partly fixed (#1253, agent mode); `vendor/common.rs` caller open|
53
53
| C54 | 3 | The contract documents `status: paidRequired` and errorCode `paid_required` for get and scan, but `get` emits legacy `status: "paid_required"` (two hand-written blocks) and `scan` reports only `paidPatches`; `Status::PaidRequired` is never constructed. | new finding |#982| filed #982|
54
54
| C55 | 3 | Decide: the future of agent mode. Only Deno and `--global` installs need it. | §5; §6 Q2 |#1000| rejected; #1000 kept agent mode for every ecosystem |
55
55
| C56 | 2 |`apply`, `apply --check` and `vendor` treat any stat error on `.socket/manifest.json` as "no manifest" (`noManifest`, exit 0); `repair`/`remove`/`rollback` say `manifest_not_found`. Five `metadata().is_err()` probes bypass `read_manifest`'s NotFound rule. | new finding |#998| filed #998|
-[#1264](https://github.com/SocketDev/socket-patch/pull/1264): Gradle (vendored + hosted) and the Maven reactor pick inserted-line terminators through `line_endings::terminator`; `gradle/eol.rs` deleted (`eol_eq` and `respell` in `line_endings`). #815 slice 3 (E16). +67/−97 prod, +67/−37 tests. `state: ready`.
8
8
-[#1262](https://github.com/SocketDev/socket-patch/pull/1262): the OpenVEX document is written through `utils::fs::write_user_output` (stage + rename; links through, devices in place). #1144 (C77). +57/−1 prod, +185 tests; CI green, Bugbot clean. `state: ready`.
9
9
-[#1258](https://github.com/SocketDev/socket-patch/pull/1258): 40 more CLI test files import `tests/common`'s `binary()` / `git_sha256` (31 + 25 copies deleted). #824 children 2–3 slice 2 (C30). +142/−401 tests, 0 prod. `state: ready`.
10
-
-[#1253](https://github.com/SocketDev/socket-patch/pull/1253): agent-mode `jvm_jar::verify_member_bytes` streams members through `hash::git_sha256::zip_member_git_sha256` (302 → 30 MiB peak on a 256 MiB member). #914 slice (C51); `vendor/common.rs` caller is free since #1227 merged; it needs #1253's helper. +17/−11 prod, +85 tests. `state: ready`.
11
10
-[#1245](https://github.com/SocketDev/socket-patch/pull/1245): `vendor::revert::finish` + `KeepPolicy` (`OnDrift`, `OnDriftWhileReferenced`, `NpmFamily`); gem, composer, Maven legacy, NuGet and pnpm finish through it. #989 item 1 slice (E24). +133/−157 prod (helper 90), +271 tests. `state: ready`.
12
11
-[#1239](https://github.com/SocketDev/socket-patch/pull/1239): NuGet crawler `find_by_purls` looks up the global folder and legacy `<Id>.<Version>/` folders by the normalized version (`1.0.0.0` = `1.0.0`) through `normalize_nuget_version`. #1202 crawler slice (E93). +47/−19 prod, +116/−4 tests. `state: ready`.
13
12
-[#1188](https://github.com/SocketDev/socket-patch/pull/1188): one `Pipfile.lock` writer (`formats::pipenv::splice_entry`, `formats::json`). Issue #1128 (E14). +303/−235 production. `redirect/mod.rs` wrapper `pipenv_reserialized_around_reference` left for when that file is free. `state: ready`.
**Merged:**#1227 (E16 slice 2), #1221 (E19 hosted gem), #1230 (E93 `PurlKey`), #1217/#1209/#1205/#1183 (E05 Deno, Go, cargo, NuGet crawls); 32 earlier PRs (#572 … #1191, see `entries/refactor/`). Leftovers: `blob_hash_matches` (#1163), dead `eco == "maven2"` arm in `commands/vendor.rs` (#1015).
16
+
**Merged:**#1253 (C51 agent-mode jar streaming; `vendor/common.rs` caller and a size-mismatch test remain), #1227 (E16 slice 2), #1221 (E19 hosted gem), #1230 (E93 `PurlKey`), #1217/#1209/#1205/#1183 (E05 Deno, Go, cargo, NuGet crawls); 32 earlier PRs (#572 … #1191, see `entries/refactor/`). Leftovers: `blob_hash_matches` (#1163), dead `eco == "maven2"` arm in `commands/vendor.rs` (#1015).
18
17
19
18
**Queue** (score = 3B + 2U + 2D + S − risk). Standalone refactor issues closed `not_planned` live on as tracker checklist items; rank the tracker's next item.
0 commit comments