Security¶
Reporting a vulnerability¶
Report security issues privately to ap@strawly.app. Include the affected component, a reproduction path, and the impact you observed. Do not open a public issue for an unpatched vulnerability.
Platform controls¶
These controls are built into the services and need no configuration beyond the environment variables described in Environment Variables:
- Authentication uses JWTs signed with HS256 and delivered in an
httpOnly,SameSite=Strictcookie. The verifier pins the algorithm and checks a revocation list, and a password change invalidates older tokens. - Passwords are hashed with bcrypt at cost factor 12. The login path runs a dummy comparison for unknown emails so response timing does not reveal whether an account exists.
- Every backend endpoint sits behind a per-route permission check. Module services accept only requests carrying the internal token and are meant to be reached through the backend proxy.
- Cloud credentials are encrypted with AES-256-GCM before they reach the database.
- Request logs redact the
Authorizationheader and cookies. - The frontend sends a per-request nonce-based Content-Security-Policy plus
X-Frame-Options: DENY,Strict-Transport-Security, andX-Content-Type-Options: nosniff. The HSTS header assumes the app is served over TLS; terminate TLS at your reverse proxy.
Accepted risks¶
These are known and deliberate; listed so operators do not rediscover them:
| Item | Reason |
|---|---|
Frontend CSP allows 'unsafe-inline' for styles |
Inline styles are used throughout the UI. Scripts stay nonce-locked, which is where injection does real damage |
GET /api/themes on the frontend is unauthenticated |
It returns static theme JSON from a fixed directory and takes no user input |
| Module services skip rate limiting for requests carrying the internal token | Those requests already passed the backend's JWT checks and rate limits; limiting them again causes 429s during long collector runs |
| Website CSP violation reporting is disabled | No report collector is deployed. Enable the commented report-to lines in the website _headers file once one exists |
Follow-ups¶
- CI is not set up in any repository. When a Forgejo Actions runner is registered, add per-repository workflows that run
npm ci,npm run lint, andnpm test, plus a non-blockingnpm audit. - The demo seed creates accounts with publicly documented passwords (
admin123and similar). It refuses to run withNODE_ENV=productionand is excluded from production images; never run it on an instance that is reachable from outside your network.