Commit 990d767
chore: scope cookies to local, staging and default for prod for better auth
* fix(app): sanitize HTML in markdown renderer to prevent stored XSS
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): deny legacy API keys with empty scopes and add SSRF protection
- API keys with empty scopes now throw ForbiddenException instead of granting full access
- Added URL safety validator to Browserbase endpoints blocking private IPs and metadata
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): prevent policy publishing when approval is pending
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): add magic-byte file content validation to prevent MIME spoofing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): keep legacy API keys working with warning log for migration tracking
Legacy keys (empty scopes) continue to have full access but now log a
warning on every use for migration tracking. This avoids breaking 188
existing production keys while giving visibility into which need migration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): enforce scopes on new API keys and set April 20 deprecation for legacy keys
- New API keys must have at least one scope (no more empty-scope keys)
- Frontend "Full Access" preset now sends all scopes explicitly
- Legacy keys with empty scopes continue working until April 20, 2026
- After April 20, legacy keys will be blocked with a clear error message
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(app): show scope details popover on API key badge click
Clicking the scope badge on an API key now shows a popover with all
permissions grouped by resource.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(app): remove unsupported className on PopoverContent
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): exclude better-auth internal 'ac' resource from API key scopes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(app): add missing labels for app, trust, pentest, training, portal scopes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): use generic error message for file validation to avoid leaking detection logic
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): use generic error messages to avoid leaking security implementation details
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): add Origin header validation middleware for CSRF protection
CORS only blocks fetch-based CSRF (JSON content-type triggers preflight).
HTML form submissions with application/x-www-form-urlencoded bypass CORS
entirely since they're "simple requests" that don't trigger preflight.
This middleware validates the Origin header on all state-changing requests
(POST/PUT/PATCH/DELETE) and rejects requests from untrusted origins.
Requests without an Origin header (API keys, service tokens, webhooks)
are allowed through — they're authenticated by other means.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): prevent task approval workflow bypass via direct status change
Block two bypass vectors in the generic PATCH /tasks/:id endpoint:
1. Cannot change status when task is in_review (must use approve/reject)
2. Cannot set status to done when an approver is assigned (must submit for review first)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(app): fix nested button hydration error in scope popover trigger
PopoverTrigger with asChild renders its own button element, so the
inner element must not be a button. Changed to span with role=button.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(app): add security headers to prevent clickjacking and other attacks
Adds X-Frame-Options: DENY, CSP frame-ancestors: none, X-Content-Type-Options,
and Referrer-Policy headers to all frontend responses. This prevents the app
from being embedded in iframes on attacker-controlled pages (clickjacking).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): address bugbot review findings
- SSRF: block IPv4-mapped IPv6 addresses (::ffff:169.254.169.254)
- SSRF: fix [::1] bracket handling in URL hostname check
- File validation: skip text pattern scan for binary files that passed magic bytes
- File validation: use specific event handler names instead of broad on\w+ regex
- API keys: fix create button enabled before scopes load
- API keys: remove dead code in scope validation
- API keys: restore ac resource (used by roles controller), add "Roles" label
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(app): remove unsupported asChild prop from PopoverTrigger
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): enforce approval workflow in bulk task status update endpoint
The bulk PATCH /v1/tasks/bulk/status endpoint bypassed the approval
workflow guards added to the single-task update. Now excludes tasks
that are in_review and tasks with an approver when setting status to done.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): add cookie prefix for staging to prevent collision with production
Staging cookies now use 'staging' prefix (e.g. __Secure-staging.session_token)
instead of the default 'better-auth' prefix. This prevents cookie conflicts
when developers visit both staging and production on *.trycomp.ai.
Production is unchanged — keeps the default 'better-auth' prefix.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* revert: remove cookie prefix change — breaks hardcoded cookie name references
The proxy.ts middleware checks for cookies by hardcoded name
(better-auth.session_token). Changing the prefix breaks auth flow.
The staging/production cookie collision is a pre-existing issue
caused by .trycomp.ai parent domain cookies overlapping with
.staging.trycomp.ai — not caused by our security changes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): add staging cookie prefix with proxy.ts support
Staging API uses 'staging' cookie prefix to avoid collision with
production cookies on .trycomp.ai parent domain. Updated proxy.ts
to check for both prefixes. Production and localhost unchanged.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(api): add environment-specific cookie prefixes to prevent collisions
Local dev uses 'local' prefix, staging uses 'staging', production
keeps default 'better-auth' (unchanged). Proxy.ts checks all prefixes
to determine authentication state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>1 parent 6c6d569 commit 990d767
2 files changed
Lines changed: 15 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
150 | 150 | | |
151 | 151 | | |
152 | 152 | | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
153 | 161 | | |
154 | 162 | | |
155 | 163 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| |||
0 commit comments