fix(compile): close F0 secret-exfil channels (env strip + error sanitization)#14
Draft
AchillesWasonga wants to merge 1 commit into
Draft
fix(compile): close F0 secret-exfil channels (env strip + error sanitization)#14AchillesWasonga wants to merge 1 commit into
AchillesWasonga wants to merge 1 commit into
Conversation
…losing F0 exfil channels
✅ Deploy Preview for illustrious-sunshine-4ce83e ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
F0 — Pre-auth secret exfiltration via
/api/compileWhat the vulnerability is
POST /api/compileexecutes user-supplied Python on the server. Before thischange, two channels leaked server secrets to any unauthenticated caller:
process.env, so injected code could read every provider key(ANTHROPIC / OPENAI / NVIDIA / GEMINI / OPENROUTER / DATABRICKS) from
os.environ.stderrwas returned in the 422 responsebody, so output (including dumped secrets) flowed straight back to the caller.
Evidence — BEFORE (unpatched, commit b7d3650)
Request. Run this before you merge to see(Run studio locally:
curl -sS -X POST http://localhost:3000/api/compile -H 'Content-Type: application/json'
-d '{"code":"import os,sys; sys.stderr.write("LEAK:"+",".join(k+"="+v for k,v in os.environ.items() if "KEY" in k or "TOKEN" in k)); sys.exit(1)"}'
Response (all six keys returned, fake sentinels used for safety): I made a fake .env.local to test but you can use the real one if you want. Here it is:
ANTHROPIC_API_KEY=sk-ant-FAKE-POC-SENTINEL-001, OPENAI_API_KEY=sk-proj-FAKE-POC-002, NVIDIA_API_KEY=nvapi-FAKE-POC-003, GOOGLE_GEMINI_API_KEY=AIzaFAKE-POC-004, OPENROUTER_API_KEY=sk-or-v1-FAKE-POC-005, DATABRICKS_TOKEN=dapiFAKE-POC-006, PYTHON_PATH=$(which python3)
Direct command execution also confirmed (
subprocess.check_output(["id"])returned
uid=501(...) ... 80(admin) ...anduname -a— i.e. arbitrary OScommands run as the server user).
Evidence — AFTER (this branch)
Same two attacks, now. After I fixed them:
{"error":"Compilation failed","requestId":"3ea6e5bd-6175-48cc-96da-ff604c97e30c"}
{"error":"Compilation failed","requestId":"942d40db-6b3d-4c21-b1be-c54b03f4c929"}
No keys, no command output. Regression — a legitimate model still compiles:
{"code":"from build123d import *\nresult = Box(10, 10, 10)"}→ HTTP 200,valid 684-byte STL.
What this change does
buildMinimalEnv()and passes only PATH/LANG/PYTHONDONTWRITEBYTECODE tothe child at both exec sites (primary + auto-heal) instead of the full env.
stderr/err.messageto the client at every error path; logsdetail server-side with a
requestIdand returns a generic error.Arbitrary code execution still occurs — the child still runs attacker
Python (it can burn CPU, touch the filesystem). This PR only closes the two
secret-exfiltration channels. The execution sink itself is addressed by the
follow-up sandbox work (AST allowlist + process isolation), and F1 (no auth
on any
/api/*route) must land so the endpoint isn't anonymously reachable.I will fix F1 and then you can check and merge both.