fix(growth): security hardening — bun -e interpolation, pkill race, input validation#3294
Merged
louisgv merged 1 commit intoOpenRouterTeam:mainfrom Apr 14, 2026
Merged
Conversation
…nput validation
Closes a batch of real security findings filed against growth.sh and reddit-fetch.ts.
growth.sh:
- Switch all four `bun -e "...${VAR}..."` sites to env-var passing
(_VAR="..." bun -e 'process.env._VAR'), per .claude/rules/shell-scripts.md.
Closes OpenRouterTeam#3188, OpenRouterTeam#3221, OpenRouterTeam#3223.
- Spawn claude under `setsid` so it owns its own process group, and kill the
group via `kill -SIG -PGID` instead of racing with pkill -P. Adds a numeric
guard on CLAUDE_PID. Closes OpenRouterTeam#3193, OpenRouterTeam#3205.
- POST to SPA with Authorization header loaded from a 0600 temp config file
(-K) and body from a 0600 temp file instead of here-string, so
SPA_TRIGGER_SECRET never appears in ps/cmdline. Closes OpenRouterTeam#3224.
- Drop dead REDDIT_JSON=$(cat ...) line.
- Extend cleanup trap to also remove CLAUDE_OUTPUT_FILE, SPA_AUTH_FILE, SPA_BODY_FILE.
reddit-fetch.ts:
- Validate REDDIT_CLIENT_ID / REDDIT_CLIENT_SECRET don't contain ':' or CRLF
(prevents Basic-auth corruption and header injection). Closes OpenRouterTeam#3198.
- Validate REDDIT_USERNAME against Reddit's charset before interpolating into
the User-Agent header (prevents CRLF injection). Closes OpenRouterTeam#3207.
- Validate Reddit-API-returned author names against the same charset and
encodeURIComponent them before interpolating into the /user/ API path
(prevents path traversal from a hostile Reddit username). Closes OpenRouterTeam#3202.
This was referenced Apr 13, 2026
This was referenced Apr 13, 2026
louisgv
approved these changes
Apr 14, 2026
Member
louisgv
left a comment
There was a problem hiding this comment.
Security Review
Verdict: APPROVED
Commit: 80aca08
Findings
No security issues found. All changes are security hardening improvements:
growth.sh:
- ✅
bun -einterpolation fixed (lines 68, 148-163, 180) — data passed via env vars per shell-scripts.md - ✅ Process group killing (lines 110, 124, 126) — atomic
setsid+kill -PGIDreplaces race-pronepkill -P - ✅ CLAUDE_PID validation (lines 118-120) — guards against empty/non-numeric PID
- ✅ SPA secret protection (lines 203-214) — passed via curl
-Kconfig file, never on command line - ✅ Temp file cleanup (line 37) — auth/body files added to cleanup trap
reddit-fetch.ts:
- ✅ Credential validation (lines 26-28) — rejects
:and newlines, prevents Basic-auth corruption and header injection - ✅ Username validation (lines 33-37) — CRLF injection prevention in User-Agent header
- ✅ Author field sanitization (lines 222-223) — prevents path traversal, encodeURIComponent as defense-in-depth
Tests
- bash -n: PASS
- bun test: PASS (2104 pass, 0 fail)
- curl|bash: N/A (no install script changes)
- macOS compat: OK (uses env vars, no bash 4+ features)
-- security/pr-reviewer
6 tasks
This was referenced Apr 14, 2026
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.
Summary
Batch security hardening for
growth.shandreddit-fetch.ts, resolving 9 real findings from the security scanner. Separately, I'll leave comments on 5 stale/hallucinated issues recommending they be closed, and 1 out-of-scope one (valibot refactor) for a follow-up PR.growth.sh
bun -estring interpolation → env-var passing, per.claude/rules/shell-scripts.md. All four sites fixed (POST_COUNT, prompt template injection, stream-json extractor, candidate extractor). Closes security: [HIGH] Command injection via unsafe variable interpolation in growth.sh #3188, security: Command injection via unquoted temp file path in growth.sh bun -e #3221, security: Command injection via unquoted variable in growth.sh line 67 #3223.setsid claude ...so claude owns its own process group, thenkill -SIG -PGIDinstead of racingpkill -P. Adds a numeric regex guard onCLAUDE_PID. Closes security: [MEDIUM] Race condition in pkill usage in growth.sh #3193, security: [HIGH] Unsafe pkill with potentially empty PID variable in growth.sh #3205.SPA_TRIGGER_SECRETvisible inps/cmdline→ Authorization header written to a 0600curl -Kconfig file; body written to a 0600 temp file instead of here-string. Closes security: Potential secret leak via unquoted SPA_TRIGGER_SECRET in process list #3224.REDDIT_JSON=$(cat ...)line; extend the cleanup trap to also removeCLAUDE_OUTPUT_FILE,SPA_AUTH_FILE,SPA_BODY_FILE.reddit-fetch.ts
CLIENT_ID/CLIENT_SECRET→ validate no:or CRLF on startup. Closes security: [HIGH] Missing input validation on Reddit credentials #3198.User-AgentviaREDDIT_USERNAME→ validate against/^[A-Za-z0-9_-]{1,64}$/on startup. Closes security: Header injection via unvalidated Reddit username in reddit-fetch.ts #3207./user/${author}/commentsvia a hostile Reddit post author → same regex validation +encodeURIComponentas defense in depth. Closes security: [HIGH] Path traversal in Reddit username URL construction in reddit-fetch.ts #3202.Closes
#3188, #3193, #3198, #3202, #3205, #3207, #3221, #3223, #3224
Not touched by this PR
setup-spa/helpers.ts,setup-spa/main.ts, andreddit-fetch.ts. Should be its own PR.X_DATA_FILEdoesn't exist,safe_substitute()was already refactored away, etc.). I'll leave a comment on each recommending closure.Test plan
bash -n growth.sh— syntax cleanbunx biome check src/— 0 errors on 184 filesbun test— 2043/2043 pass