Repository navigation
fix(security): resolve 6 confirmed vulnerabilities (#273) - #274
rahmaniramin550-ai wants to merge 1 commit into
Conversation
- src/utils/image.ts: prevent SSRF on remote image URLs and enforce bounded chunk streaming against memory exhaustion - src/commands/speech/synthesize.ts: validate subtitle_file URL against SSRF before download - src/files/download.ts: add SSRF validation rejecting private/loopback/cloud metadata destinations and secure temp file creation - src/config/loader.ts: generate unpredictable temp files and write with mode 0o600 and flag 'wx' to prevent symlink overwrites - src/update/self-update.ts: isolate updates in private mkdtemp directory and write with flag 'wx' without unlinking existing files - src/client/endpoints.ts: URL-encode taskId and fileId parameters to prevent authenticated query/path parameter injection - add comprehensive unit and regression tests for all 6 vulnerabilities
|
Thanks for putting work into this — the private-range checks and the I'm the author of #273, and there are a few gaps here that keep the SSRF findings reachable, so I'd rather they get closed before this is considered a full fix: Redirects. DNS rebinding.
No timeouts. The hardened fetches never get an abort signal, so a deliberately slow target can still hang the CLI for as long as it likes, even with the streaming size cap in place. I have a local patch covering all seven affected files plus regression tests, which I've kept private for the disclosure — happy to hand it to the maintainers directly if that's useful. Not trying to gatekeep the fix, I just don't want #273 closed with the SSRFs half-addressed. |
Summary of Security Remediations
Closes #273
This PR resolves all 6 confirmed security vulnerabilities reported in #273:
Vision Image SSRF & Excessive Buffering (
src/utils/image.ts)validateSafeUrlto reject private IPv4/IPv6, loopback (127.0.0.0/8,::1), link-local / cloud metadata (169.254.169.254), and internal hostnames.res.arrayBuffer()buffering with streaming chunk reading that aborts and throwsCLIErrorimmediately if size exceedsMAX_IMAGE_SIZE_BYTES(50 MB), preventing denial of service / memory exhaustion.Speech Subtitle SSRF (
src/commands/speech/synthesize.ts)response.data.subtitle_filewithvalidateSafeUrlbefore attempting download, preventing internal network access if an API response is spoofed or compromised.Media Download SSRF & Safe File Creation (
src/files/download.ts)flags: 'wx'andmode: 0o600to prevent symlink following and TOCTOU file hijacking.Config Temp-File Symlink Race (
src/config/loader.ts)config.json.tmppath with unique, cryptographically random temporary filename.flag: 'wx'(O_CREAT | O_EXCL) and mode0o600so pre-existing symlinks cannot be overwritten.Self-Update Temporary Symlink Overwrite (
src/update/self-update.ts)mkdtempSyncwith0o700user-only permissions.wxwithmode: 0o700.EEXIST.finallyblock.Authenticated Query & Path Parameter Injection (
src/client/endpoints.ts)encodeURIComponenttotaskIdinvideoTaskEndpointandvideoTaskV2Endpoint.encodeURIComponenttofileIdinfileRetrieveEndpoint.Verification & Tests
test/utils/network.test.ts(16 passing tests)test/utils/image-security.test.ts(7 passing tests)test/files/download-ssrf.test.ts(5 passing tests)test/commands/speech/synthesize-security.test.ts(1 passing test)test/config/loader-security.test.ts(2 passing tests)test/update/self-update-security.test.ts(1 passing test)test/client/endpoints.test.ts(9 passing tests)tsc --noEmitpasses with 0 type errors.eslintpasses with 0 errors.Payout Address (USDC / Solana):
BuMURy7R5mkCUtasaAWwvXZReZYmCCANMyUXrRy6CZzoNeed help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.