Skip to content

W4b: remove server-side remote code execution and circumvention paths - #4

Open
EgerDev wants to merge 14 commits into
hardening/w2-authfrom
hardening/w4b-remote-code
Open

EgerDev wants to merge 14 commits into
hardening/w2-authfrom
hardening/w4b-remote-code

Conversation

@EgerDev

@EgerDev EgerDev commented Sep 25, 2026

Copy link
Copy Markdown
Owner

W4b: No server-side execution of third-party code; circumvention paths removed (stacked on W2)

Plan: docs/superpowers/plans/2026-09-23-w4b-remove-remote-code-execution.md (Tasks 1–9; Task 10 is owner-only). This implements roadmap D7/C5, which closes audit P0 SEC-01 (remote JS ran in the server realm and could read every secret).

What changed

Removed code paths

  • PO-token/BotGuard minting, including its new Function evaluator and the global window swap.
  • YouTube player-script execution. youtubei.js now runs with retrieve_player: false and no evaluator.
  • /api/unlock and /api/bypass, which now answer 404, plus the same-hop layer.
  • The browser ladder's BotGuard, same-hop and public-relay legs.
  • The free SOCKS proxy pool (proxifly@main) and the public CORS relays (corsfix, allorigins).
  • The process-wide IPv4/dispatcher patch.

yt-dlp locked down (owner decision C5)

  • Kept: yt-dlp's own bundled solver, taken from the pinned install. --remote-components is gone.
  • Every yt-dlp, ffmpeg and solver child gets an allowlisted environment with no server secrets.
  • Removed: --impersonate, the runtime curl_cffi/PySocks installs, and --throttled-rate.
  • All three yt-dlp builders pass --ignore-config --no-plugin-dirs --no-remote-components, so config files or plugins can't bring these back.

Lint and dependencies

  • Lint bans eval, new Function/Function, implied eval, node:vm, and the known aliasing shapes, with a probe test for each.
  • Removed bgutils-js; jsdom is now a dev-only dependency.

Copy

  • UI, errors and README now describe features neutrally. A policy test keeps circumvention wording out.

Behaviour changes

Some formats and qualities are no longer available, and some downloads are slower (single connection, no throttle workaround). These losses are accepted under D7. The full list is in the plan's "Behaviour changes" section.

Testing (local)

typecheck/lint clean; npm test 0 failures (134 + 523/524); build ok; test:http 39/40 (1 Postgres-only skip). The built .output contains none of the removed flags or hosts.

Owner (Task 10)

  • Operator notice: VELO_SOCKS_PROXY/ALL_PROXY are no longer read.
  • Counsel questions for W9.

🤖 Generated with Claude Code

EgerDev and others added 14 commits September 24, 2026 20:02
…m the browser ladder

The browser no longer mints a PO token, races the same-hop bypass or calls
proxy.corsfix.com / api.allorigins.win: proxyFetch goes only to /api/relay,
and the hybrid race is yt-dlp on the server plus the Velo relay. A race with
no runnable leg now fails instead of hanging.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The server no longer downloads and runs YouTube's BotGuard interpreter with
new Function against a jsdom window bound onto globalThis (roadmap D7/C5,
audit M-04, SEC-01, SUP-01, SEC-12). InnerTube and yt-dlp run without a
PO token; /api/builder and /api/ytdlp no longer take one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Nothing imports bgutils-js after the PO-token minter went; jsdom is only
used by two unit tests. The Tools tab, the updater, Dependabot and the SSR
externals stop listing them, and the Invidious/Piped/Cobalt probe table goes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
/api/unlock ran player-script deciphering and a BotGuard mint per call;
/api/bypass relayed watch pages and media through corsfix/allorigins.
Both now answer 404, and /api/download no longer falls back to them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…node:vm

youtubei.js now runs with retrieve_player: false and no evaluator, so the
server never downloads or runs base.js; format URLs are used as sent, with
no nsig/signature deciphering, pot/ratebypass stamping or parallel range
lanes. Lint adds no-eval, no-new-func, no-implied-eval, the aliased forms
and a node:vm ban, pinned by a lint-probe test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Importing ipv4-bind.server.ts replaced dns.lookup, disabled Happy Eyeballs
and installed an HTTP/1-only undici dispatcher for the whole process, to
fix a Grok-sandbox IPv6/NAT mismatch for the paths W4b deleted. yt-dlp keeps
its own per-run --force-ipv4 (audit ARCH-12).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Guest yt-dlp runs no longer ride anonymous SOCKS5 hosts from the moving
proxifly/free-proxy-list@main, and /api/relay no longer falls back to
proxy.corsfix.com or api.allorigins.win. Egress is the operator's saved
proxy routes, then direct (audit M-14, SEC-04, SUP-05, SEC-14, ARCH-09).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…child env

yt-dlp no longer downloads its challenge solver from GitHub at run time
(--remote-components ejs:github). Only the yt-dlp child env is
allow-listed: children started by run()/runCapture() (yt-dlp and the
ffmpeg and node it forks) get CHILD_ENV_ALLOWLIST only, so the node child
that yt-dlp runs YouTube's player script in cannot read DATABASE_URL or
any other server secret. tool-updates.server.ts still passes the full env
to pip/npm until W4a deletes it.

Removes --impersonate and the runtime curl_cffi install (D7: bot-detection evasion is off).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Remove "BotGuard PO token rotation", "Anti-Throttle", "NSig & BotGuard
Bypass", "matching hop" and "CORS relay" from the UI, error hints and
README, and the "AI" chip on Transcript (audit UX-05, OSS-11). Legal notice
text waits for counsel (W9).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ote components

Ruling P10: --throttled-rate made yt-dlp re-extract when YouTube throttled,
which is throttle bypass (D7). It is gone from THROTTLE_FLAGS and the working
example.

All three yt-dlp argv builders (download, captions, -J formats) now start with
YTDLP_BASE_ARGV: -m yt_dlp --ignore-config --no-plugin-dirs
--no-remote-components --no-js-runtimes --js-runtimes node, so a user or system
yt-dlp.conf or plugin cannot re-enable remote components or anything else D7
turns off. The fetch_pot research row now reads use: "omit".

Tests: argv tests for all three builders (new ytdlp-meta.server.test.ts
captures the captions and -J argv); the remote-components policy regex now
bans only the enabling flag, --remote-components.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nd the child env allowlist

- hybrid-download: with fetch stubbed, itag 18 asks exactly /api/ytdlp and
  /api/relay?url=..., 137+140 asks exactly /api/relay, and when every leg
  fails the download rejects without trying any other URL.
- eslint: no-restricted-syntax now also bans any value reference to Function
  (alias, Reflect.construct, destructure), computed and template "Function"
  keys, .constructor(...) calls and constructions, any loader called with
  "vm"/"node:vm", import() of a non-literal specifier and new Worker(...,
  { eval: true }). eval-ban.test.mjs covers each shape plus window["eval"],
  const e = eval and require("vm"), and checks that the Function type,
  o.Function and { Function: 1 } still pass. eslint . stays at 0 problems.
- remote-code-policy: the source scan also bans cors.sh, jsdelivr.net/gh,
  VELO_SOCKS_PROXY and ALL_PROXY.
- proc-run: every ServerEnv key, HTTP(S)/ALL/NO proxy variables in both
  cases, NODE_OPTIONS and PYTHONPATH are dropped by childEnv().

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- youtube-copy: the "HLS fallback" row says what happens now: yt-dlp saves
  the itag 96 playlist when 137+140 and 137+251 are unavailable.
- youtube-client: decipher() with no player returns '' for a
  signatureCipher-only format and plainFormatUrl throws its fixed message;
  the library's evaluator error is an unreachable backstop.
- Comments: iso-bmff and auto-update-plan drop the "same hop" / "reverse the
  player" wording; ytdlp-auth's 1080p selector and working-example comments
  no longer claim a SOCKS-proved present, and read as dated test records.
- README: install yt-dlp[default]; name yt-dlp-ejs (the solver in the
  default extras), not curl_cffi.
- docs/architecture.md: no free SOCKS pool, public CORS relays,
  /api/unlock, /api/bypass, PO-token minting, --impersonate or
  --throttled-rate; the current ladder, argv (YTDLP_BASE_ARGV), ssr.external,
  subprocess table and egress hosts; the C5 yt-dlp solver exception and
  childEnv().

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Task 10 Step 2: the W9 counsel question covers only yt-dlp's own challenge
  solving; --impersonate (P1) and --throttled-rate (P10) were removed.
- Behaviour changes: 11 says only yt-dlp's children get the allowlisted
  environment (P8); 13 says the Tools tab shows two tools; new 15-19 cover
  --impersonate, run-time curl_cffi installs, the relay-only browser mux of
  video-only itags, --throttled-rate and yt-dlp ignoring config and plugins.
- Hand-off W4a: optionalModule/ensureImpersonate are already deleted; only
  tool-updates.server.ts's installers and full env remain.
- Hand-off W7: dead looksThrottled and the test-only yt-dlp research tables;
  architecture.md is current after the final fix wave.
- Hand-off W9: no --impersonate / --throttled-rate question.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant