chore(SEC-11589): security upgrades for sandbox#38
chore(SEC-11589): security upgrades for sandbox#38phantom-autopilot[bot] wants to merge 1 commit into
Conversation
Adds Yarn `resolutions` and npm `overrides` to force patched versions of vulnerable transitive dependencies pulled in via react-scripts@4.0.3. Addresses 11 CRITICAL advisories: - form-data 3.0.1 -> 3.0.4 (GHSA-fjxv-7rqg-78g4) - sha.js 2.4.11 -> 2.4.12 (GHSA-95m3-7q98-8xr5) - pbkdf2 3.1.2 -> 3.1.5 (GHSA-h7cp-r72f-jxh6, GHSA-v62p-rq8g-8h59) - elliptic 6.5.4 -> 6.6.1 (GHSA-vjh7-7g9h-fjfh) - cipher-base 1.0.4 -> 1.0.7 (GHSA-cpq7-6gpm-g9rc) - immer 8.0.1 -> 9.0.21 (GHSA-33f9-j839-rf8h) - @babel/traverse 7.20.0 -> 7.29.7 (GHSA-67hx-6x53-jw92) - loader-utils 1.2.3 -> 2.0.4 (GHSA-76p3-8jx3-jpfq) - shell-quote 1.7.2 -> 1.8.4 (GHSA-g4rg-993r-mgx7) - ejs 2.7.4 -> 3.1.10 (GHSA-phwq-j96m-2c2q)
|
PR opened by agent Execution log |
|
Task created — intent: multi-review, workspace provisioning started. https://autopilot-orchestrator.tools.phantom.dev/tasks/8eb92932-2853-5874-9ab3-fb00b9f5fb08 |
📝 WalkthroughWalkthroughThe PR updates ChangesTransitive Dependency Resolution
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@package.json`:
- Around line 45-68: The package.json "resolutions" and "overrides" entries use
caret ranges which can drift; update each entry in both the "resolutions" and
"overrides" objects to pin the exact patched version (remove the ^ and set the
specific version that your lockfile already resolves to, e.g. set pbkdf2 to
3.1.5, cipher-base to 1.0.7, immer to 9.0.21, `@babel/traverse` to 7.29.7,
shell-quote to 1.8.4, and keep form-data, sha.js, loader-utils, ejs as the exact
resolved versions) so the remediation targets cannot be loosened by a lock
refresh.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b48c273e-0abd-4583-befe-530c5f13d5a9
⛔ Files ignored due to path filters (2)
package-lock.jsonis excluded by!**/package-lock.jsonyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (1)
package.json
| "resolutions": { | ||
| "form-data": "^3.0.4", | ||
| "sha.js": "^2.4.12", | ||
| "pbkdf2": "^3.1.3", | ||
| "elliptic": "^6.6.1", | ||
| "cipher-base": "^1.0.5", | ||
| "immer": "^9.0.6", | ||
| "@babel/traverse": "^7.23.2", | ||
| "loader-utils": "^2.0.4", | ||
| "shell-quote": "^1.7.3", | ||
| "ejs": "^3.1.7" | ||
| }, | ||
| "overrides": { | ||
| "form-data": "^3.0.4", | ||
| "sha.js": "^2.4.12", | ||
| "pbkdf2": "^3.1.3", | ||
| "elliptic": "^6.6.1", | ||
| "cipher-base": "^1.0.5", | ||
| "immer": "^9.0.6", | ||
| "@babel/traverse": "^7.23.2", | ||
| "loader-utils": "^2.0.4", | ||
| "shell-quote": "^1.7.3", | ||
| "ejs": "^3.1.7" | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python - <<'PY'
import json, re
from pathlib import Path
secure = {
"form-data": "3.0.4",
"sha.js": "2.4.12",
"pbkdf2": "3.1.5",
"elliptic": "6.6.1",
"cipher-base": "1.0.7",
"immer": "9.0.21",
"`@babel/traverse`": "7.29.7",
"loader-utils": "2.0.4",
"shell-quote": "1.8.4",
"ejs": "3.1.10",
}
def parse(v):
return tuple(int(x) for x in re.findall(r'\d+', v)[:3])
pkg = json.loads(Path("package.json").read_text())
for section in ("resolutions", "overrides"):
print(f"\n[{section}]")
data = pkg.get(section, {})
for dep, minv in secure.items():
spec = data.get(dep)
if spec is None:
print(f" MISSING {dep}")
continue
clean = spec.lstrip("^~<>= ")
strict = not spec.startswith("^")
meets = parse(clean) >= parse(minv)
status = "OK" if strict and meets else "FAIL"
print(f" {status:4} {dep:16} spec={spec:10} required>={minv} strict={strict}")
print("\n[yarn.lock quick scan]")
yarn = Path("yarn.lock")
if yarn.exists():
text = yarn.read_text()
for dep in secure:
m = re.search(rf'^{re.escape(dep)}@.*?\n\s+version "(.*?)"', text, re.M | re.S)
print(f" {dep:16} {m.group(1) if m else 'NOT_FOUND'}")
else:
print(" yarn.lock not found")
print("\n[package-lock.json quick scan]")
pl = Path("package-lock.json")
if pl.exists():
lock = json.loads(pl.read_text())
pkgs = lock.get("packages", {})
for dep in secure:
found = []
needle = f"node_modules/{dep}"
for k,v in pkgs.items():
if k.endswith(needle) and isinstance(v, dict) and "version" in v:
found.append(v["version"])
found = sorted(set(found))
print(f" {dep:16} {', '.join(found) if found else 'NOT_FOUND'}")
else:
print(" package-lock.json not found")
PYRepository: phantom/sandbox
Length of output: 2042
🏁 Script executed:
#!/bin/bash
set -euo pipefail
if [ -f yarn.lock ]; then
echo "=== rg '`@babel/traverse`' yarn.lock (top matches) ==="
rg -n --fixed-strings "`@babel/traverse`" yarn.lock | head -n 50 || true
echo
echo "=== show nearby yarn.lock entries if any ==="
# Print a small window around each match
rg -n --fixed-strings "`@babel/traverse`" yarn.lock | head -n 20 | cut -d: -f1 | while read -r ln; do
start=$((ln-3)); end=$((ln+10));
sed -n "${start},${end}p" yarn.lock
echo "----"
done
else
echo "yarn.lock not found"
fi
if [ -f package-lock.json ]; then
echo
echo "=== package-lock.json versions for `@babel/traverse` ==="
node -e "const fs=require('fs');const lock=JSON.parse(fs.readFileSync('package-lock.json','utf8'));const pkgs=lock.packages||{};const keys=Object.keys(pkgs).filter(k=>k.endsWith('node_modules/@babel/traverse'));for (const k of keys) console.log(k, pkgs[k].version);"
fiRepository: phantom/sandbox
Length of output: 7149
Pin exact patched versions in package.json (avoid caret ranges for resolutions/overrides)
yarn.lock and package-lock.json currently resolve these packages to the intended patched minimums (e.g., pbkdf2 3.1.5, cipher-base 1.0.7, immer 9.0.21, @babel/traverse 7.29.7, shell-quote 1.8.4), but the resolutions/overrides entries use ^ ranges with lower minimums than the stated remediation targets, so a lock refresh could drift.
Suggested fix
"resolutions": {
- "form-data": "^3.0.4",
- "sha.js": "^2.4.12",
- "pbkdf2": "^3.1.3",
- "elliptic": "^6.6.1",
- "cipher-base": "^1.0.5",
- "immer": "^9.0.6",
- "`@babel/traverse`": "^7.23.2",
- "loader-utils": "^2.0.4",
- "shell-quote": "^1.7.3",
- "ejs": "^3.1.7"
+ "form-data": "3.0.4",
+ "sha.js": "2.4.12",
+ "pbkdf2": "3.1.5",
+ "elliptic": "6.6.1",
+ "cipher-base": "1.0.7",
+ "immer": "9.0.21",
+ "`@babel/traverse`": "7.29.7",
+ "loader-utils": "2.0.4",
+ "shell-quote": "1.8.4",
+ "ejs": "3.1.10"
},
"overrides": {
- "form-data": "^3.0.4",
- "sha.js": "^2.4.12",
- "pbkdf2": "^3.1.3",
- "elliptic": "^6.6.1",
- "cipher-base": "^1.0.5",
- "immer": "^9.0.6",
- "`@babel/traverse`": "^7.23.2",
- "loader-utils": "^2.0.4",
- "shell-quote": "^1.7.3",
- "ejs": "^3.1.7"
+ "form-data": "3.0.4",
+ "sha.js": "2.4.12",
+ "pbkdf2": "3.1.5",
+ "elliptic": "6.6.1",
+ "cipher-base": "1.0.7",
+ "immer": "9.0.21",
+ "`@babel/traverse`": "7.29.7",
+ "loader-utils": "2.0.4",
+ "shell-quote": "1.8.4",
+ "ejs": "3.1.10"
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "resolutions": { | |
| "form-data": "^3.0.4", | |
| "sha.js": "^2.4.12", | |
| "pbkdf2": "^3.1.3", | |
| "elliptic": "^6.6.1", | |
| "cipher-base": "^1.0.5", | |
| "immer": "^9.0.6", | |
| "@babel/traverse": "^7.23.2", | |
| "loader-utils": "^2.0.4", | |
| "shell-quote": "^1.7.3", | |
| "ejs": "^3.1.7" | |
| }, | |
| "overrides": { | |
| "form-data": "^3.0.4", | |
| "sha.js": "^2.4.12", | |
| "pbkdf2": "^3.1.3", | |
| "elliptic": "^6.6.1", | |
| "cipher-base": "^1.0.5", | |
| "immer": "^9.0.6", | |
| "@babel/traverse": "^7.23.2", | |
| "loader-utils": "^2.0.4", | |
| "shell-quote": "^1.7.3", | |
| "ejs": "^3.1.7" | |
| } | |
| "resolutions": { | |
| "form-data": "3.0.4", | |
| "sha.js": "2.4.12", | |
| "pbkdf2": "3.1.5", | |
| "elliptic": "6.6.1", | |
| "cipher-base": "1.0.7", | |
| "immer": "9.0.21", | |
| "`@babel/traverse`": "7.29.7", | |
| "loader-utils": "2.0.4", | |
| "shell-quote": "1.8.4", | |
| "ejs": "3.1.10" | |
| }, | |
| "overrides": { | |
| "form-data": "3.0.4", | |
| "sha.js": "2.4.12", | |
| "pbkdf2": "3.1.5", | |
| "elliptic": "6.6.1", | |
| "cipher-base": "1.0.7", | |
| "immer": "9.0.21", | |
| "`@babel/traverse`": "7.29.7", | |
| "loader-utils": "2.0.4", | |
| "shell-quote": "1.8.4", | |
| "ejs": "3.1.10" | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@package.json` around lines 45 - 68, The package.json "resolutions" and
"overrides" entries use caret ranges which can drift; update each entry in both
the "resolutions" and "overrides" objects to pin the exact patched version
(remove the ^ and set the specific version that your lockfile already resolves
to, e.g. set pbkdf2 to 3.1.5, cipher-base to 1.0.7, immer to 9.0.21,
`@babel/traverse` to 7.29.7, shell-quote to 1.8.4, and keep form-data, sha.js,
loader-utils, ejs as the exact resolved versions) so the remediation targets
cannot be loosened by a lock refresh.
|
Task completed Execution logAgent "Security review of dependency upgrades" completed · 1m 37s |
|
Task completed Execution logAgent "API contracts review of major version bumps" completed · 2m 34s |
There was a problem hiding this comment.
Multi-Model Review — 3 findings (0 critical, 0 high, 2 medium, 1 low)
Large tier (LOC inflated by lockfile churn — only package.json has hand-written edits). Reviewed by Claude Opus (security, api-contracts, edge-cases) + Codex review + Codex adversarial + CodeRabbit (2 runs) + GPT-5 via pal MCP. Caret resolution minima all match advisory-patched versions and no source file in this repo directly imports the upgraded packages, so the 11 targeted advisories are correctly remediated; remaining findings are scope/coverage observations.
| @@ -9,10 +9,7 @@ | |||
| "version": "1.0.0", | |||
| "license": "MIT", | |||
| "dependencies": { | |||
There was a problem hiding this comment.
🟠 Medium — Lockfile regeneration removes react/react-dom/styled-components from the install tree
The regenerated package-lock.json drops react, react-dom, and styled-components from the root project's dependencies block (they were previously locked there) and only react is added to peerDependencies. After npm ci --legacy-peer-deps against this lockfile, require.resolve('react' | 'react-dom' | 'styled-components') all fail, so a clean local install can no longer start or build the sandbox — even though src/index.tsx and the components import them at runtime. The PR description notes that yarn build is "pre-existing failure" on main, but the prior lockfile did keep these resolved in the install tree, so this regeneration is a real behavioural regression for fresh checkouts.
Suggested fix
Either move react, react-dom, and styled-components from peerDependencies to dependencies in package.json (then regenerate both lockfiles), or document/automate the external provisioning step that the CodeSandbox environment used to fill in. If the intent is to keep them as peers, the README/contributing guide should call out the required install procedure.
| @@ -41,5 +41,29 @@ | |||
| "not dead", | |||
There was a problem hiding this comment.
🟠 Medium — Direct runtime dep @solana/web3.js@1.63.1 still flags high-severity audit findings
This PR remediates 11 transitive advisories pulled in via react-scripts, but leaves the only direct runtime dependency, @solana/web3.js@1.63.1, untouched. Running npm audit --omit=dev --audit-level=high against the branch still reports a high-severity advisory for @solana/web3.js itself plus vulnerable transitives it pulls in (bigint-buffer, ws, lodash, base-x). Because this is the only production dependency, the sandbox still exposes known runtime vulnerabilities even after this PR merges — the security posture promised by the PR title is partly cosmetic.
Suggested fix
Out of scope for SEC-11589 (which is explicitly the 11 react-scripts transitives), but worth a follow-up ticket. Either bump @solana/web3.js to a current 1.x release (latest patches its bigint-buffer/ws/base-x chains) or add @solana/web3.js-chain entries to the resolutions/overrides block. Whatever the chosen scope, gating future merges on npm audit --omit=dev --audit-level=high (or the repo's chosen equivalent) prevents this gap from recurring.
| "not op_mini all" | ||
| ] | ||
| ], | ||
| "resolutions": { |
There was a problem hiding this comment.
🟡 Low — Other react-scripts@4 CRITICAL transitives not covered by this set
The 11 advisories targeted by this PR are correct, but the react-scripts@^4.0.3 dep tree is known to carry several additional CRITICAL-rated advisories that are commonly flagged alongside the ones here — for example ansi-html (XSS/RCE via webpack-dev-server overlay; fixed by switching to ansi-html-community), serialize-javascript (XSS in older versions used by terser-webpack-plugin), and postcss 7.x (multiple ReDoS advisories). They're not part of SEC-11589 by scope, but they will keep appearing in audits until addressed.
Suggested fix
Non-blocking. Either expand resolutions/overrides to also pin these (verify each against npm audit output before adding) or open a follow-up ticket so the next sweep can pick them up together.
Summary
Resolves SEC-11589 — 11 CRITICAL security advisories affecting transitive dependencies pulled in via
react-scripts@^4.0.3.All vulnerable packages are transitive deps, so this PR forces patched versions through Yarn
resolutionsand npmoverridesinpackage.json, and regeneratesyarn.lockandpackage-lock.jsonto match.Advisories resolved
loader-utilswas bumped to^2.0.4(instead of^1.4.1) because the dependency tree already pulls inloader-utils@2.xpaths;2.0.4covers both 1.x and 2.x advisory ranges.immerandejsare major-version bumps required by their advisories (8 → 9 and 2 → 3, respectively).Test plan
yarn installsucceeds;yarn.lockregenerated.npm install --package-lock-onlysucceeds;package-lock.jsonregenerated.yarn tscpasses.yarn build— pre-existing failure unrelated to this change. The same failure (Cannot find module: 'react', followed by the well-known Node 17+/webpack 4ERR_OSSL_EVP_UNSUPPORTED) reproduces onmainbecausereactis declared only inpeerDependenciesand the project relies on its sandbox environment to provide it. Per the autopilot rules, pre-existing failures are not addressed here.yarn.lockandpackage-lock.json.🤖 Generated with Claude Code
Summary by CodeRabbit