fix(security): 20 additional bugs found via sqry semantic code graph (round 2)#806
Open
mr-k-man wants to merge 16 commits intogarrytan:mainfrom
Open
fix(security): 20 additional bugs found via sqry semantic code graph (round 2)#806mr-k-man wants to merge 16 commits intogarrytan:mainfrom
mr-k-man wants to merge 16 commits intogarrytan:mainfrom
Conversation
…ymlink traversal Both meta-commands.ts and write-commands.ts validateOutputPath previously used path.resolve which resolves paths logically without following symlinks. A symlink at /tmp/safe pointing to /etc would pass the safe-directory check. Switched to fs.realpathSync (matching the existing validateReadPath pattern in read-commands.ts): - Resolve the full real path for existing files - Resolve the parent directory for new files (ENOENT case) - Also resolve SAFE_DIRECTORIES themselves through realpathSync (handles macOS /tmp → /private/tmp) Added browse/test/security-audit-r2.test.ts with source-level checks and behavioral tests including symlink-to-/etc attack verification.
Block data exfiltration via url(), expression(), @import, javascript:, and data: patterns in write-commands style handler, cdp-inspector modifyStyle, extension injectCSS (also validates id format), and extension toggleClass (validates className format). Adds source-level regression tests for all four injection points.
Replace direct bash variable interpolation into JS string literals with environment variable passing. Values are now passed via GSTACK_FILTER_* env vars and read with process.env inside the bun -e block, eliminating the shell injection vector where single quotes in --query/--type/--slug could break out of JS string literals and execute arbitrary code. Adds browse/test/learnings-injection.test.ts with source-level and behavioral tests to prevent regression.
…ions Add isValidQueueEntry() validator to sidebar-agent.ts that checks all 8 QueueEntry fields (prompt required, args array, cwd path traversal, typed optional fields). Invalid entries are skipped with console.warn. Queue directory and file permissions hardened to 0o700/0o600 in all three writers: server.ts, sidebar-agent.ts, and cli.ts. Tests added to security-audit-r2.test.ts.
- applyStyle in extension/inspector.js now validates CSS values with the same DANGEROUS_CSS pattern as injectCSS (blocks url(), expression(), @import, javascript:, data: exfiltration vectors) - snapshot.ts annotated screenshot path validation now uses realpathSync to resolve symlinks before checking against safe directories - cookie-import in write-commands.ts replaces inline path.resolve+isPathWithin with realpathSync-based validation consistent with validateOutputPath - isValidQueueEntry in sidebar-agent.ts now checks stateFile for '..' path traversal sequences in addition to type validation - Adds source-level regression tests for all four fixes in security-audit-r2.test.ts
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
Second security audit of gstack's browse subsystem, Chrome extension, and CLI scripts — all findings beyond the 10 already reported in PR #664 and issues #665-#675.
Findings by severity
How we found them
Cross-validation with other community reports
7 of our original 10 findings from PR #664 were independently rediscovered by stedfn (#712-#717) and Gonzih (#741-#758). Several of these round 2 findings overlap with seanomich's audit (#783) but target different specific vectors.
Test results
Security regression tests (119/119 pass)
```
119 pass, 0 fail, 182 expect() calls
Ran 119 tests across 5 files [47ms]
```
E2E evals (33 pass, 0 regressions)
Ran in `gstack-ci` Docker image (Ubuntu 24.04 + Chromium 145/Playwright 1.58.2 + `--cap-add SYS_ADMIN`):
All previously-failing browse tests now pass:
1 unrelated failure (`qa-bootstrap` — test infrastructure, not our code).
Test plan