This is an inventory, not a claim. Each row says what a generated application does without configuration, where you change it, and which test holds it. A row with no test says so.
| Measure | Default | Change it with | Since | Held by |
|---|---|---|---|---|
Security headers: CSP | On, on every routed response. No inline script, | Not a config key: build your own stack with | 1.0.0; CSP without |
|
CSRF token on state-changing web routes | On in a new app’s dev and test profiles. The framework default is off, so an upgrade cannot break an app, and the boot warns while it is. An enabled check with no secret refuses to boot. |
| 1.0.0 |
|
Session cookie: | On. |
| 1.0.0 |
|
Session tokens stored hashed | On. The database holds a hash, never the token. | — | 1.1.0 | |
Password hashing | bcrypt+SHA-512 (buddy-hashers), work factor 12, for passwords and MFA backup codes. | Not a config key: the constant | 1.0.0 | |
Login lockout | On: 5 failed attempts lock the account for 15 minutes, counted atomically. |
| 1.1.0 |
|
HTTP rate limiting | On in a new app’s dev profile, off in test. Enabled in production with no |
| 1.0.0 | |
MFA (TOTP); turning it off needs the password or a code | Opt-in per user. The secret is encrypted at rest, backup codes are hashed, wrong proofs count toward the lockout. | A | 1.1.0 |
|
Login response carries no secret | No password hash, MFA secret or backup code in any login response. | — | 1.1.0 | |
JWT secret | A missing secret, or one under 32 characters, refuses to boot. The algorithm is pinned to HS256. |
| 1.0.0 | |
Every route needs a signed-in user | On, unless the route says | Route data | 1.0.0 | |
Authorization rules enforced |
|
| 1.1.0 |
|
Open redirects refused | A | — | 1.0.0 |
|
HTML output escaped | Hiccup escapes every string unless you mark it raw. | — | 1.0.0 | |
SQL parameterised | Queries go through HoneySQL with bound parameters. | — | 1.0.0 |
|
Errors leak no internals | A 500 answers | — | 1.0.0 | |
Personal data redacted in logs and error reports | On. Sentry redacts even without a | Sentry | 1.1.0 |
|
Tenant isolation | A schema per tenant, on PostgreSQL only: other databases refuse to boot with tenancy on, H2 unless |
| 1.0.0 | The tenancy registry: every library that carries a tenant id names its test. |
Secrets outside config files |
|
| 1.1.0 | |
Known vulnerabilities in dependencies | Scanned weekly, on every change to a |
| 1.1.0; release gate: unreleased |
Tests tagged :security also run as their own required job on every code
change; the others run in their library’s job.
TLS. Wagoe sets HSTS and Secure cookies; something in front of it has to
terminate HTTPS.
CSRF and rate limiting. Keep both on in the profile you deploy; rate limiting there needs an active :wagoe/cache.
Secrets. Keep them in your platform’s secret store and read them with
#secret or #env.
Backups, OS and JVM patches, database access. Outside the framework.
Wagoe has had no external audit and no penetration test. It has one maintainer.
See Security fixes.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |