Frontend Security
Table of Contents Show Hide
Browser security controls
The GoSmarter web application is a single-page application (SPA) and we apply several layers of browser-level security to protect you whilst you use it.
Content Security Policy (CSP)
We enforce a Content Security Policy that restricts what the browser can load and execute:
| Directive | Policy | What it means |
|---|---|---|
default-src | https: | Only HTTPS resources allowed by default |
script-src | 'self' + Supademo, Frill, Clerk, Cloudflare Turnstile, and Stripe.js | Only our own scripts plus the specific third-party scripts required for authentication (Clerk), bot protection (Cloudflare Turnstile), billing (Stripe.js), product guidance (Supademo), and feedback (Frill) can execute |
frame-src | 'self' + blob: + the same Clerk, Cloudflare Turnstile, Stripe, Frill and Supademo origins | Only our own site, local blob frames, and the named third-party embeds above can render |
style-src | https: 'unsafe-inline' | Styles from HTTPS sources (inline styles required by the UI framework) |
worker-src | 'self' + blob: | Service workers restricted to our own origin and local blob workers |
object-src | blob: | Embedded content restricted to local blob URLs (used by the PDF viewer); no third-party plugins |
img-src | https: + blob: + data: | Images from HTTPS sources, local blobs, and inline data URIs |
font-src | 'self' + data: + Frill’s CDN (frill-prod-app.b-cdn.net) | Fonts from our own origin, inlined as data URIs, or served by the Frill feedback widget |
frame-ancestors | 'none' | The application cannot be embedded in an iframe on another site (clickjacking protection) |
The allowlisted third-party origins are:
- Clerk (
*.clerk.accounts.dev,*.clerk.com) for authentication - Cloudflare Turnstile (
challenges.cloudflare.com) for bot protection during sign-up - Stripe (
js.stripe.com,hooks.stripe.com) for billing and checkout - Supademo (
script.supademo.com,app.supademo.com) for interactive in-app guides - Frill (
widget.frill.co) for product feedback and communication widgets
No advertising scripts are loaded from the frontend shell.
Token storage
Authentication is handled by Clerk. The session token is stored in an HTTP cookie (__session, plus a companion __client_uat cookie used to track session state), not in browser localStorage or sessionStorage:
SameSite=Laxis set on Clerk’s cookies- Clerk’s client SDK does not log PII to the browser console by default, and exposes no equivalent to a verbose PII-logging toggle
Source maps
Production builds do not include source maps. This prevents exposing application structure and logic through browser developer tools.
API route protection
The GoSmarter API is served separately from the frontend, behind the Zuplo API gateway, which validates Clerk session tokens at the edge before any customer-facing request reaches the backend. A response override redirects a 401 from the frontend shell back to the sign-in page. See Access Control for the full authentication and authorisation architecture, including the small set of provider webhook endpoints that sit outside the gateway by design.
Supply chain security
- Dependency scanning: Dependabot monitors all frontend dependencies for known vulnerabilities
- Dependency review: Pull requests are automatically checked for high/critical CVEs and copyleft license violations
- No hardcoded secrets: No API keys, tokens, or credentials in the frontend source code
Key points for your security team
- CSP enforced: Strict Content Security Policy limiting script execution to self + named vendors
- Named script/frame allowlist: Clerk (authentication), Cloudflare Turnstile (bot protection), Stripe (billing), Supademo, and Frill — no others
- Cookie-based tokens: Session tokens stored in an HTTP cookie (
SameSite=Lax) by Clerk’s client SDK, not in browser localStorage or sessionStorage - No PII logging: Clerk’s client SDK does not log PII to the console by default
- No source maps in production: Application internals not exposed
- Authenticated API routes: Enforced at the Static Web App platform level
- Automated dependency scanning: Dependabot + dependency review on every PR
- CORS policy: API cross-origin access is restricted to configured origins
- HSTS: HSTS headers are set to enforce HTTPS connections to the frontend