mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-11-06 06:57:50 +00:00
fix(guards): refuse a .npmrc beside a portal manifest, like bunfig.toml
Bun reads .npmrc too, so a registry line beside a borrowed portal's manifest fetches every dependency from a server the portal's author picked - the same door bunfig.toml opens, which the installer and guard check 3 already refuse. Both now reject either file. The #718 integration test, which pointed Bun at its offline registry through a .npmrc, passes the registry through NPM_CONFIG_REGISTRY instead; it still proves the hook stays off, because the hooked package only exists on that server. Follows GHSA-wq7j-x5jq-pjrw; this case is ours, not the report's. Guard tests for the workspaces and bunfig.toml refusals, which the previous commit added without them, come along. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
0bcfd75e60
commit
83c788d779
9 files changed
+67
-28
No files matched your search
+1
-1
@@ -31,7 +31,7 @@ Every grant the template ships, where it lives, how long it lasts, and what chec
|
||||
| Hooks (`.claude/settings.json` `hooks`, skill and command frontmatter `hooks`, !`command` lines) | None. The template ships no hooks: a hook runs with no prompt the moment its event fires, which is the vector the Shai-Hulud worm used in August 2026. A !`command` line in a skill or command runs when it loads, the same way. | - | Any of them fails CI |
|
||||
| Every other `settings.json` key | None. `permissions` (with `allow`, `ask`, `deny`) and `hooks` are the whole file: `env` would reach every pre-approved `python tools/*.py` run, `apiKeyHelper` and a `statusLine` command run a program with no prompt, and `permissions.defaultMode` or `additionalDirectories` would widen what the lists above scope. | - | Any other top-level or `permissions` key fails CI (`ALLOWED_SETTINGS_KEYS`, `ALLOWED_PERMISSIONS_KEYS`) |
|
||||
| Compiling (`lualatex`, `xelatex`, a custom template's command) | Not pre-approved: a `lualatex:*` grant would also approve `-shell-escape`. In default mode each compile prompts. Answering "don't ask again" would persist exactly that `lualatex` rule to your `settings.local.json`, so answer per call. | - | - |
|
||||
| Portal CLI manifests (`.agents/**/package.json`) | No lifecycle scripts (`preinstall`, `postinstall`, ...), no `trustedDependencies`, no `workspaces` (whose packages bring their own scripts) and no `bunfig.toml` beside the manifest (which reconfigures the install), so `bun install` runs no code; the installer passes `--ignore-scripts` as well | - | Fails CI; `tools/install_portal_clis.py` also skips a manifest that carries one |
|
||||
| Portal CLI manifests (`.agents/**/package.json`) | No lifecycle scripts (`preinstall`, `postinstall`, ...), no `trustedDependencies`, no `workspaces` (whose packages bring their own scripts) and no `bunfig.toml` or `.npmrc` beside the manifest (either can point every dependency at another registry), so `bun install` runs no code from a source the template did not review; the installer passes `--ignore-scripts` as well | - | Fails CI; `tools/install_portal_clis.py` also skips a manifest that carries one |
|
||||
| Personal-data ignore rules (`.gitignore`) | Every rule in `REQUIRED_IGNORE_RULES` present, read as git reads them (leading whitespace is part of the pattern); no negation outside `ALLOWED_IGNORE_NEGATIONS`, in the root file or in any subdirectory `.gitignore`, which outranks it | - | Fails CI |
|
||||
| The browser-header retry (`tools/fetch_page.py`) | A GET with a fixed argv, http(s) only, 45 s / 5 redirects / 10 MB, `robots.txt` enforced before each redirect target with no bypass flag, output refused inside the repo | - | Pinned by `tests/test_fetch_page.py`; the grant names the script, not `curl` |
|
||||
|
||||
|
||||
Reference in new issue
Block a user