You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* fix: DNS rebinding protection checks AAAA (IPv6) records too
Cherry-pick PR garrytan#744 by @Gonzih. Closes the IPv6-only DNS rebinding gap
by checking both A and AAAA records independently.
Co-Authored-By: Gonzih <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: validateOutputPath symlink bypass — resolve real path before safe-dir check
Cherry-pick PR garrytan#745 by @Gonzih. Adds a second pass using fs.realpathSync()
to resolve symlinks after lexical path validation.
Co-Authored-By: Gonzih <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: validate saved URLs before navigation in restoreState
Cherry-pick PR garrytan#751 by @Gonzih. Prevents navigation to cloud metadata
endpoints or file:// URIs embedded in user-writable state files.
Co-Authored-By: Gonzih <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: telemetry-ingest uses anon key instead of service role key
Cherry-pick PR garrytan#750 by @Gonzih. The service role key bypasses RLS and
grants unrestricted database access — anon key + RLS is the right model
for a public telemetry endpoint.
Co-Authored-By: Gonzih <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: killAgent() actually kills the sidebar claude subprocess
Cherry-pick PR garrytan#743 by @Gonzih. Implements cross-process kill signaling
via kill-file + polling pattern, tracks active processes per-tab.
Co-Authored-By: Gonzih <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix(design): bind server to localhost and validate reload paths
Cherry-pick PR garrytan#803 by @garagon. Adds hostname: '127.0.0.1' to Bun.serve()
and validates /api/reload paths are within cwd() or tmpdir(). Closes C1+C2
from security audit garrytan#783.
Co-Authored-By: garagon <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: add auth gate to /inspector/events SSE endpoint (C3)
The /inspector/events endpoint had no authentication, unlike /activity/stream
which validates tokens. Now requires the same Bearer header or ?token= query
param check. Closes C3 from security audit garrytan#783.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: sanitize design feedback with trust boundary markers (C4+H5)
Wrap user feedback in <user-feedback> XML markers with tag escaping to
prevent prompt injection via malicious feedback text. Cap accumulated
feedback to last 5 iterations to limit incremental poisoning.
Closes C4 and H5 from security audit garrytan#783.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: harden file/directory permissions to owner-only (C5+H9+M9+M10)
Add mode 0o700 to all mkdirSync calls for state/session directories.
Add mode 0o600 to all writeFileSync calls for session.json, chat.jsonl,
and log files. Add umask 077 to setup script. Prevents auth tokens, chat
history, and browser logs from being world-readable on multi-user systems.
Closes C5, H9, M9, M10 from security audit garrytan#783.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: TOCTOU race in setup symlink creation (C6)
Remove the existence check before mkdir -p (it's idempotent) and validate
the target isn't already a symlink before creating the link. Prevents a
local attacker from racing between the check and mkdir to redirect
SKILL.md writes. Closes C6 from security audit garrytan#783.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: remove CORS wildcard, restrict to localhost (H1)
Replace Access-Control-Allow-Origin: * with http://127.0.0.1 on sidebar
tab/chat endpoints. The Chrome extension uses manifest host_permissions
to bypass CORS entirely, so this only blocks malicious websites from
making cross-origin requests. Closes H1 from security audit garrytan#783.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: make cookie picker auth mandatory (H2)
Remove the conditional if(authToken) guard that skipped auth when
authToken was undefined. Now all cookie picker data/action routes
reject unauthenticated requests. Closes H2 from security audit garrytan#783.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: gate /health token on chrome-extension Origin header
Only return the auth token in /health response when the request Origin
starts with chrome-extension://. The Chrome extension always sends this
origin via manifest host_permissions. Regular HTTP requests (including
tunneled ones from ngrok/SSH) won't get the token. The extension also
has a fallback path through background.js that reads the token from the
state file directly.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* test: update server-auth test for chrome-extension Origin gating
The test previously checked for 'localhost-only' comment. Now checks for
'chrome-extension://' since the token is gated on Origin header.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* chore: bump version and changelog (v0.15.7.0)
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---------
Co-authored-by: Gonzih <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: garagon <[email protected]>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+21Lines changed: 21 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,26 @@
1
1
# Changelog
2
2
3
+
## [0.15.7.0] - 2026-04-05 — Security Wave 1
4
+
5
+
Fourteen fixes for the security audit (#783). Design server no longer binds all interfaces. Path traversal, auth bypass, CORS wildcard, world-readable files, prompt injection, and symlink race conditions all closed. Community PRs from @Gonzih and @garagon included.
6
+
7
+
### Fixed
8
+
9
+
-**Design server binds localhost only.** Previously bound 0.0.0.0, meaning anyone on your WiFi could access mockups and hit all endpoints. Now 127.0.0.1 only, matching the browse server.
10
+
-**Path traversal on /api/reload blocked.** Could previously read any file on disk (including ~/.ssh/id_rsa) by passing an arbitrary path in the JSON body. Now validates paths stay within cwd or tmpdir.
11
+
-**Auth gate on /inspector/events.** SSE endpoint was unauthenticated while /activity/stream required tokens. Now both require the same Bearer or ?token= check.
12
+
-**Prompt injection defense in design feedback.** User feedback is now wrapped in XML trust boundary markers with tag escaping. Accumulated feedback capped to last 5 iterations to limit poisoning.
13
+
-**File and directory permissions hardened.** All ~/.gstack/ dirs now created with mode 0o700, files with 0o600. Setup script sets umask 077. Auth tokens, chat history, and browser logs no longer world-readable.
14
+
-**TOCTOU race in setup symlink creation.** Removed existence check before mkdir -p (idempotent). Validates target isn't a symlink before creating the link.
15
+
-**CORS wildcard removed.** Browse server no longer sends Access-Control-Allow-Origin: *. Chrome extension uses manifest host_permissions and isn't affected. Blocks malicious websites from making cross-origin requests.
16
+
-**Cookie picker auth mandatory.** Previously skipped auth when authToken was undefined. Now always requires Bearer token for all data/action routes.
17
+
-**/health token gated on extension Origin.** Auth token only returned when request comes from chrome-extension:// origin. Prevents token leak when browse server is tunneled.
18
+
-**DNS rebinding protection checks IPv6.** AAAA records now validated alongside A records. Blocks fe80:: link-local addresses.
19
+
-**Symlink bypass in validateOutputPath.** Real path resolved after lexical validation to catch symlinks inside safe directories.
20
+
-**URL validation on restoreState.** Saved URLs validated before navigation to prevent state file tampering.
21
+
-**Telemetry endpoint uses anon key.** Service role key (bypasses RLS) replaced with anon key for the public telemetry endpoint.
Review skills now enforce that every section gets evaluated, regardless of plan type. No more "this is a strategy doc so implementation sections don't apply." If a section genuinely has nothing to flag, say so and move on, but you have to look.
0 commit comments