Security review: John's answers on F36, F37 and F9
Hosted droplets have a restrictive cloud firewall (F36 re-rated low); standalone PostgreSQL trust accepted (F37); default SuperUser password is deliberate for trials, but the licensed-mode change is enforced by the client only (F9 note). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -209,9 +209,9 @@ Status: *candidate* (seen in code, not yet confirmed), *confirmed*, *fixed in ca
|
||||
| F32 | Medium | confirmed (code) | A real-looking SMTP account and password are in the DEBUG defaults in `raven` and `sockeye` source |
|
||||
| F34 | Medium | confirmed | Shipped client libraries behind on security fixes: DOMPurify 2.3.8 (wiki sanitiser), Vuetify 2.6.6 |
|
||||
| F6 | Medium | confirmed | No lockout or rate limit on login or the 2FA step; no password rules |
|
||||
| F9 | Medium | confirmed | Default SuperUser password, and an anonymous route that says whether it is still set |
|
||||
| F36 | Medium | confirmed (code) | AyaNova listens on all interfaces on plain HTTP port 7575 in every template, hosted droplets included, and the setup script adds no firewall |
|
||||
| F37 | Medium | confirmed (code) | Standalone PostgreSQL accepts any local connection without a password (`trust`) |
|
||||
| F9 | Medium | confirmed | Default SuperUser password (by design for trials), and an anonymous route that says whether it is still set |
|
||||
| F36 | Low | confirmed (code) | AyaNova listens on all interfaces on plain HTTP port 7575 in every template; hosted droplets are protected by a cloud firewall |
|
||||
| F37 | Low | accepted (John) | Standalone PostgreSQL accepts any local connection without a password (`trust`) |
|
||||
| F2 | Medium | confirmed (code) | Windows installers give all local users modify rights on the program and data folders, `config.json` included |
|
||||
| F7 | Low | confirmed | Password change or reset does not end existing sessions, and makes the download key non-expiring |
|
||||
| F8 | Low | confirmed | Latest-token check skipped for any URL ending in `/auth` or `notify/hello` |
|
||||
@@ -326,7 +326,7 @@ A new database has SuperUser `superuser` / `l3tm3in` (`PrimeData.cs`). Anonymous
|
||||
`GET notify/hello` returns `sudf: true` while that is still the password, and the login form
|
||||
then fills it in. Anyone can therefore check an internet-facing server for it in one request
|
||||
and log in as SuperUser. Each call also runs a PBKDF2 hash, a cheap way to load the server.
|
||||
Whether hosted droplets set their own SuperUser password at setup: to check in pass 10. **Pass 10:** they do not. The setup script generates the database password and JWT secret but not a SuperUser password, so every new hosted droplet starts internet-facing with `l3tm3in` until someone changes it. Fix in the script: generate one, set it once with `AYANOVA_SET_SUPERUSER_PW`, and write it to `/root/ayanova-secrets.txt` with the others.
|
||||
Whether hosted droplets set their own SuperUser password at setup: to check in pass 10. **Pass 10:** they do not. The setup script generates the database password and JWT secret but not a SuperUser password, so every new hosted droplet starts internet-facing with `l3tm3in` until someone changes it. Fix in the script: generate one, set it once with `AYANOVA_SET_SUPERUSER_PW`, and write it to `/root/ayanova-secrets.txt` with the others. **John, 2026-10-23:** the published password is deliberate while a server is in trial mode, for easy evaluation; once licensed for production it must be changed on first login. Checked: that rule is enforced by the client only (`api/initialize.js` sends the user to the password page when `knownPassword` and the licence status is ActivePurchased); the server still accepts `superuser`/`l3tm3in` on a licensed server (API logins, or a user who navigates away) and `notify/hello` keeps reporting it. Fix that keeps the trial design: on a purchased licence, have the server refuse a login with the default SuperUser credentials (or allow it only to change the password), and stop returning `sudf` outside trial mode.
|
||||
Fix options: only return `sudf` from local or LAN addresses, or force a password change on
|
||||
first SuperUser login; at least warn in the UI and the manual.
|
||||
|
||||
@@ -717,8 +717,9 @@ consider Swagger UI for logged-in users only.
|
||||
Every `config.json` template (`lan-install-config.json`, `linux-server`, `linux-desktop`, the
|
||||
standalone launcher's) sets `AYANOVA_USE_URLS` to `http://*:7575`. On hosted droplets nginx
|
||||
proxies HTTPS to `127.0.0.1:7575`, but Kestrel also listens on the public address, and the setup
|
||||
script configures no host firewall. Unless a DigitalOcean cloud firewall blocks it (**John to
|
||||
check**), anyone can reach AyaNova directly on port 7575 over plain HTTP, without TLS and
|
||||
script configures no host firewall. Unless a DigitalOcean cloud firewall blocks it (**John, 2026-10-23: every droplet has a restrictive
|
||||
cloud firewall**, the same settings confirmed for the Sockeye migration, so hosted droplets are
|
||||
not exposed; re-rated Low), anyone can reach AyaNova directly on port 7575 over plain HTTP, without TLS and
|
||||
without nginx's headers, and logins sent there travel in clear. The standalone (single-PC)
|
||||
install also accepts connections from the whole network. Fix: hosted and Linux server
|
||||
templates bind `http://127.0.0.1:7575` when behind a proxy; the setup script enables `ufw`
|
||||
@@ -733,7 +734,9 @@ database user, the `postgres` superuser included, without a password. Standalone
|
||||
single-PC (mostly evaluation) install, so the exposure is local only; with F2 the database
|
||||
files are writable by every local user anyway. Fix: `scram-sha-256` with a password generated
|
||||
at install and written to the launcher's `config.json`; or accept it for evaluation installs
|
||||
(John's decision).
|
||||
(John's decision). **John, 2026-10-23: accepted** for standalone unless the fix is very short and
|
||||
low-risk; the scram change needs a generated password in the installer, the launcher config and a
|
||||
prepared database, so it is not that short: accepted.
|
||||
|
||||
### F38 Linux hardening (pass 10, from code)
|
||||
|
||||
@@ -833,4 +836,4 @@ roles that should not see the schedule (pass 7).
|
||||
| 2026-10-23 | 7 Staff roles | Went through the remaining logged-in routes without a role check, the restricted-role filtering in `WorkOrderBiz`, and user and contact administration in `UserBiz`. Tested on the local dev server, read-only: **F27 confirmed** (`SubContractorRestricted` through `report/data`). F28 from code (live test not done). New: F29. The rest of the list found OK (see "Pass 7: routes ... found OK") |
|
||||
| 2026-10-23 | 8 Email and notifications | Code reading only, nothing sent. Read `NotifyController` (direct SMTP and message), `Mailer`, `GlobalOpsNotificationSettings` controller, biz and model, `NotifyEventHelper`, `CoreJobNotify`, `CoreJobCustomerNotify`, `NotifySubscriptionBiz`. F3 and F4 confirmed by code; F17 confirmed and re-rated Medium (names and links, no reports). New: F30, F31, F32. **Action for John: rotate the FastMail app password in F32** |
|
||||
| 2026-10-23 | 9 Client, headers, CORS, Swagger | Code reading of every `v-html` use in `raven-client` and its data source; `npm audit` read-only against the lockfile (no install, no change), triaged to shipped packages; server and nginx headers, CORS, Swagger. New: F33, F34 (needs John's decision on two front-end packages), F35; F14 extended (`unit/customerunit`) |
|
||||
| 2026-10-23 | 10 Deployment | Code reading: `lan.iss`, `standalone.iss`, the four `config.json` templates, the standalone PostgreSQL configuration, the hosted setup script in `sockeye-client` (secrets, permissions, systemd unit, nginx, certbot), `dist/docker`. F2 confirmed and extended (`config.json` readable by all users); F9 extended (hosted droplets start with the default SuperUser password). New: F36, F37, F38. **John to check:** whether a DigitalOcean cloud firewall blocks port 7575 on hosted droplets |
|
||||
| 2026-10-23 | 10 Deployment | Code reading: `lan.iss`, `standalone.iss`, the four `config.json` templates, the standalone PostgreSQL configuration, the hosted setup script in `sockeye-client` (secrets, permissions, systemd unit, nginx, certbot), `dist/docker`. F2 confirmed and extended (`config.json` readable by all users); F9 extended (hosted droplets start with the default SuperUser password). New: F36, F37, F38. John then confirmed hosted droplets have a restrictive cloud firewall (F36 re-rated Low), accepted F37, and explained the trial default password (F9 note added) |
|
||||
|
||||
Reference in New Issue
Block a user