Platform Security Findings — Consolidated Register¶
Compiled 2026-05-22. Amalgamates the seven per-repo
security.mddocuments into one navigable worklist for remediation.This is an index, not the source of truth for fixes. Every finding below links to its per-repo
security.md(and, forsomeli-apiauth, toauthentication.md), where the full evidence,file:linecitations, and step-by-step Fix blocks live. When you action an item, edit the per-repo doc — keep this register as the cross-cutting map. Severities are taken verbatim from the source docs (ranges are placed at the higher tier); "clean / not-a-finding / correctness-only" items are excluded.
Source documents¶
| Repo | Role | Findings doc |
|---|---|---|
someli-api |
Main backend (Express + MySQL) | someli-api/security.md + someli-api/authentication.md |
someli-platform |
Customer SPA (Nuxt 2) | someli-platform/web-client/security.md |
designer-api |
Designer backend (Express + MySQL) | designer-api/security.md |
Someli-admin-api |
Admin backend (Express + MySQL) | Someli-admin-api/security.md |
someli-dashboard-be |
Standalone dashboard service | someli-dashboard-be/security.md |
admin_console_R |
Admin SPA (Vite + React + TS) | admin_console_R/security.md |
Someli-Designer |
Designer SPA (Nuxt 2 + Polotno) | Someli-Designer/security.md |
1. Severity rollup¶
Counts as tallied from the per-repo docs (≈; ranges placed at the higher tier).
| Repo | 🔴 Critical | 🟠 High | 🟡 Medium | ⚪ Low | Total |
|---|---|---|---|---|---|
someli-api |
2 | 5 | 7 | 1 | 15 |
someli-platform (web client) |
1 | 7 | 5 | 5 | 18 |
designer-api |
0 | 5 | 5 | 3 | 13 |
Someli-admin-api |
0 | 3 | 5 | 2 | 10 |
someli-dashboard-be |
0 | 0 | 1 | 4 | 5 |
admin_console_R |
0 | 0 | 4 | 7 | 11 |
Someli-Designer |
0 | 1 | 4 | 5 | 10 |
| Total | 3 | 21 | 31 | 27 | 82 |
The two backends forked from someli-api (designer-api, Someli-admin-api) and the two Nuxt SPAs (someli-platform, Someli-Designer) repeat most of each other's findings — see CODE-OVERLAP-MATRIX.md. That is why the themes below matter more than the per-repo lists: one fix pattern usually clears several rows.
2. Cross-repo themes (fix once, apply everywhere)¶
T1 — SQL injection from string-interpolated queries¶
Raw ${…} interpolation of request data into SQL.
- someli-api: Critical, unauthenticated, in the login endpoints /webauthenticate & /authenticate (leaks password hashes via UNION). detail
- designer-api: confirmed live, routes/routes.js F-7. detail
- Someli-admin-api: dynamic filter queries, F-8. detail
- someli-dashboard-be: analytics queries interpolate auth-set numerics (limited today). detail
Shared fix: replace interpolation with ? placeholders + bound-value arrays (mysql2); whitelist ORDER BY columns; coerce IN (...) lists to integers. A repo-wide Semgrep rule banning interpolated query strings prevents regressions.
T2 — Hardcoded / committed secrets¶
Credentials living in source or baked into images.
- someli-platform: AWS access key + secret (Critical, in git since 2022-08-01), WC-SEC-1; Polotno key + telemetry IDs WC-SEC-11.
- designer-api: Slack token F-1, Unsplash key F-2, committed conf/credentials.json Google OAuth secret F-6, Polotno key F-9, .env baked into Docker image F-13.
- Someli-admin-api: session secret F-1, Slack token F-2, committed conf/credentials.json F-10.
- someli-api: Slack token, Polotno key, hardcoded express-session secret.
- someli-dashboard-be: fallback session secret "change-me" F-1.
Shared fix: rotate every exposed secret first (assume compromised), move to process.env/secrets manager, remove from Dockerfile COPY, scrub git history (git-filter-repo/bfg), add gitleaks to CI. See the rotation checklist in §4 Phase 0a.
T3 — Authentication & session-token weaknesses¶
someli-api: social-login auth bypass (Critical), pass-the-hash plaintext fallback, plaintext/auth/logintoken format, plaintext password storage/compare, credential logging, forgeableBearer+sidtoken, in-memory revocation.someli-platformWC-AUTH-2,admin_console_RF-1,Someli-DesignerF-2: session token in browser-readable storage (localStorage / non-HttpOnly cookie) → XSS = account takeover.Someli-admin-apiF-3/F-4: in-memory revocation, token never expires.Someli-DesignerF-3 /admin_console_RF-11: no server-side logout / no 401→logout.someli-dashboard-beF-2/F-3: auth-by-convention, deployable mock auth.
Shared fix: server-set HttpOnly + Secure + SameSite cookies (stop returning tokens in JSON for the SPA to store); add token expiry + a persistent revocation store; route social login only through the OAuth/Passport callback; bcrypt-only comparison.
T4 — Broken access control / client-side authorization¶
Role/permission gating not enforced server-side per request.
- someli-platform WC-AUTH-4 (user-editable roleType cookie), Someli-Designer F-4 (UI-only gating), Someli-admin-api F-7 (gating in SQL only), someli-dashboard-be F-2.
Shared fix: authorize every request on the backend from the authenticated identity; treat all client-supplied role/account values as untrusted.
T5 — Missing HTTP hardening (headers, CSP, SRI, rate limiting, CORS, body limits)¶
Near-universal across the platform.
- No helmet/security headers: someli-api, designer-api F-11, someli-dashboard-be F-4.
- No CSP: someli-platform WC-SEC-2, admin_console_R F-4, Someli-Designer F-6.
- No SRI on CDN scripts: someli-platform WC-SEC-3, admin_console_R F-5, Someli-Designer F-5.
- No rate limiting: someli-api, designer-api F-10, Someli-admin-api, someli-dashboard-be.
- CORS wildcard: someli-api, designer-api F-4, Someli-admin-api F-5 (+ someli-platform WC-SEC-15 verify).
- Oversized body limits (50–150 MB): someli-api, designer-api F-5, Someli-admin-api F-9.
- Missing nginx headers / TLS 1.0-1.1 / version disclosure / clickjacking: someli-platform WC-SEC-7/13/16/17/18, Someli-Designer F-6.
Shared fix: baseline helmet() + express-rate-limit + CORS allow-list + sane body limits in each Express server.js; nginx add_header (CSP, HSTS, X-Frame-Options/frame-ancestors, X-Content-Type-Options) + ssl_protocols TLSv1.2 TLSv1.3 for the SPAs; SRI hashes on all CDN <script>/<link>.
T6 — Outdated stack & dependency hygiene¶
- EOL Vue 2 / Nuxt 2 / Webpack 4:
someli-platformWC-SEC-5,Someli-Designer(cross-cutting). - No automated dependency updates:
someli-platformWC-SEC-6 (no Dependabot/Renovate). - 3rd-party runtime script in prod (
cdn.gpteng.co):admin_console_RF-3. - Spurious / deprecated deps:
someli-dashboard-beF-5; three lockfiles inadmin_console_R.
Shared fix: enable Dependabot security PRs everywhere; remove unused/deprecated deps; plan the Vue 2→3 / Nuxt 2→3 migration; drop or SRI-pin the Lovable.dev script.
T7 — Clickjacking / external report¶
someli-platformWC-SEC-13/16: the app is framable; an external researcher reported it (2026-05-22). The genuine kernel (missingframe-ancestors/X-Frame-Options) overlaps T5; the report's escalation claims were unsubstantiated. The serious issue uncovered while verifying it was thesomeli-apiauth bypass (T3). triage
3. Master findings index¶
Grouped by severity, then repo. "Fix (one line)" is a pointer — full steps are in the linked doc.
🔴 Critical¶
| Repo | Finding | Theme | Fix (one line) | Detail |
|---|---|---|---|---|
| someli-api | Login auth bypass — webauthenticate social:true mints a token for any social account by email alone |
T3 | Delete the social:true grant branch; verify social login via OAuth callback only |
authentication.md §Web Login |
| someli-api | Unauthenticated SQL injection in /webauthenticate & /authenticate |
T1 | Parameterize email/sid with ? placeholders |
authentication.md F1–F5 |
| someli-platform | WC-SEC-1 — AWS access key + secret hardcoded (in git since 2022-08-01) | T2 | Rotate now, delete file, scrub git history, add gitleaks | web-client |
🟠 High¶
| Repo | Finding | Theme | Fix (one line) | Detail |
|---|---|---|---|---|
| someli-api | Plaintext password storage (/register) |
T3 | Hash with bcrypt at registration | authentication.md |
| someli-api | Pass-the-hash plaintext password fallback (password == hash) |
T3 | Remove the == fallback; bcrypt.compare only |
authentication.md F3 |
| someli-api | /auth/login plaintext token id_ts_id (forgeable) |
T3 | Issue AES encryptData token instead |
security.md |
| someli-api | Hardcoded secrets (Slack token, Polotno key, session secret) | T2 | Rotate + move to conf.js/env |
security.md §Secrets |
| someli-api | No rate limiting on auth endpoints (brute force) | T5 | express-rate-limit on login routes |
security.md §Rate Limiting |
| someli-platform | WC-AUTH-2 — token in browser-readable cookie (XSS→ATO) | T3 | Server-set HttpOnly cookie | web-client |
| someli-platform | WC-SEC-2 — no CSP; unsafe-inline via disabled sanitizers |
T5 | Add nginx CSP, phase out inline | web-client |
| someli-platform | WC-SEC-3 — no SRI on 14 CDN scripts | T5/T2 | Add integrity=sha384-… |
web-client |
| someli-platform | WC-SEC-4 — 9 v-html sinks (Chatbot AI output) |
T5 | DOMPurify on all v-html |
web-client |
| someli-platform | WC-SEC-5 — EOL Vue 2 / Nuxt 2 / Webpack 4 | T6 | Plan Vue 3 / Nuxt 3 migration | web-client |
| someli-platform | WC-SEC-6 — no Dependabot/Renovate | T6 | Enable Dependabot security PRs | web-client |
| someli-platform | WC-AUTH-4 — frontend-trusted roleType cookie (Med–High) |
T4 | Enforce roles server-side | web-client |
| designer-api | F-1 — hardcoded Slack bot token | T2 | Rotate + env | designer-api |
| designer-api | F-2 — hardcoded Unsplash access key | T2 | Rotate + env | designer-api |
| designer-api | F-3 — no middlewares/auth.js (auth posture unclear) |
T3 | Add/verify auth middleware on routes | designer-api |
| designer-api | F-6 — committed conf/credentials.json (Google OAuth secret) |
T2 | Rotate, gitignore, scrub history | designer-api |
| designer-api | F-13 — .env baked into Docker image |
T2 | Remove from COPY, inject at runtime, rotate |
designer-api |
| Someli-admin-api | F-1 — hardcoded session secret | T2 | Rotate + env | admin-api |
| Someli-admin-api | F-2 — hardcoded Slack bot token | T2 | Rotate + env | admin-api |
| Someli-admin-api | F-10 — committed conf/credentials.json |
T2 | Rotate, gitignore, scrub history | admin-api |
| Someli-Designer | F-1 — auth-redirect may be missing (HIGH if true — VERIFY) | T3 | Confirm route guard; enforce auth | designer-fe |
🟡 Medium¶
| Repo | Finding | Theme | Fix (one line) | Detail |
|---|---|---|---|---|
| someli-api | Credentials/PII logged at login (console.log(req.body)) |
T3 | Strip credential logs | authentication.md F4 |
| someli-api | Forgeable stored auth_token = 'Bearer '+sid |
T3 | Use unguessable token; don't persist sid | authentication.md F5 |
| someli-api | CORS wildcard (cors() no options) |
T5 | Origin allow-list | security.md §CORS |
| someli-api | Helmet not loaded (no security headers) | T5 | app.use(helmet()) (already a dep) |
security.md §Helmet |
| someli-api | 150 MB JSON body limit | T5 | Lower per-route | security.md |
| someli-api | Input validation on 1 route only | T5 | Validator chains at route boundaries | security.md |
| someli-api | In-memory token revocation (lost on restart) | T3 | Persist revocations (DB/Redis) | authentication.md |
| someli-platform | WC-SEC-7 — missing nginx security headers | T5 | Add header block | web-client |
| someli-platform | WC-SEC-15 — CORS (verify backend allow-list) | T5 | Confirm strict origin | web-client |
| someli-platform | WC-SEC-16 — clickjacking (external report) | T7 | frame-ancestors 'none' + XFO |
web-client |
| someli-platform | WC-SEC-17 — TLS 1.0/1.1 enabled (PCI) | T5 | ssl_protocols TLSv1.2 TLSv1.3 |
web-client |
| someli-platform | WC-SEC-14b — ad-blockers break payment SDKs (operational) | — | Load on demand + detect/instrument | web-client |
| designer-api | F-4 — CORS wildcard + malformed credentials header | T5 | Allow-list + fix header | designer-api |
| designer-api | F-5 — 50 MB body limit | T5 | Lower per-route | designer-api |
| designer-api | F-7 — SQL injection in interpolated queries | T1 | Parameterize | designer-api |
| designer-api | F-8 — forEach over async work (correctness) |
— | Use for…of/Promise.all |
designer-api |
| designer-api | F-10 — no request rate limiting | T5 | express-rate-limit |
designer-api |
| Someli-admin-api | F-3 — in-memory token revocation | T3 | Persist revocations | admin-api |
| Someli-admin-api | F-4 — token has no expiry | T3 | Set expiresIn; add JWT_EXPIRES_IN |
admin-api |
| Someli-admin-api | F-5 — CORS wildcard | T5 | Origin allow-list | admin-api |
| Someli-admin-api | F-7 — role gating in SQL only | T4 | Enforce in app layer too | admin-api |
| Someli-admin-api | F-8 — SQLi via unparameterised filters | T1 | Parameterize | admin-api |
| someli-dashboard-be | F-2 — auth-by-convention (res.userId assumed set) |
T3/T4 | Add in-router auth guard | dashboard-be |
| admin_console_R | F-1 — auth token in localStorage |
T3 | Move to HttpOnly cookie | admin-console |
| admin_console_R | F-3 — Lovable.dev script in production HTML | T2/T6 | Remove from prod or SRI-pin | admin-console |
| admin_console_R | F-4 — no CSP | T5 | Add CSP (meta/headers) | admin-console |
| admin_console_R | F-11 — no 401 → logout | T3 | Interceptor: 401 clears session | admin-console |
| Someli-Designer | F-2 — token in localStorage / userdetail cookie |
T3 | HttpOnly cookie | designer-fe |
| Someli-Designer | F-3 — no server-side logout | T3 | Add POST /logout invalidation |
designer-fe |
| Someli-Designer | F-4 — role gating UI-only | T4 | Enforce server-side | designer-fe |
| Someli-Designer | F-6 — no CSP | T5 | Add nginx CSP | designer-fe |
⚪ Low¶
| Repo | Finding | Theme | Fix (one line) | Detail |
|---|---|---|---|---|
| someli-api | Middleware order (CORS after session; no error handler/logger) | T5 | Reorder; add handler + logger | security.md |
| someli-platform | WC-SEC-8 — public env vars in bundle (verify no secrets) | — | Grep build; confirm no OAuth secrets | web-client |
| someli-platform | WC-SEC-10 — token in URL (verify) | T3 | Spot-check flows | web-client |
| someli-platform | WC-SEC-11 — hardcoded telemetry/license keys | T2 | Move to env where applicable | web-client |
| someli-platform | WC-SEC-12 — mixed content | T5 | upgrade-insecure-requests + audit |
web-client |
| someli-platform | WC-SEC-18 — nginx version disclosure | T5 | server_tokens off |
web-client |
| designer-api | F-9 — Polotno license key hardcoded | T2 | Env var; confirm terms | designer-api |
| designer-api | F-11 — no HTTPS/security headers at app layer | T5 | helmet + headers | designer-api |
| designer-api | F-12 — nginx.conf in repo not audited |
T5 | Audit + add headers | designer-api |
| Someli-admin-api | F-6 — webhook body-parser exemption, no handlers | — | Remove or implement + verify sigs | admin-api |
| Someli-admin-api | F-9 — 150 MB body limit | T5 | Lower per-route | admin-api |
| someli-dashboard-be | F-1 — fallback session secret "change-me" |
T2 | Remove unused session / fail-fast | dashboard-be |
| someli-dashboard-be | F-3 — mock auth deployable if NODE_ENV=development |
T3 | Gate behind explicit opt-in flag | dashboard-be |
| someli-dashboard-be | F-4 — no standalone hardening (helmet/CORS/rate-limit) | T5 | Add baseline middleware | dashboard-be |
| someli-dashboard-be | F-5 — spurious/deprecated dependencies | T6 | Prune unused deps | dashboard-be |
| admin_console_R | F-2 — hardcoded Apptype |
— | Move to env | admin-console |
| admin_console_R | F-5 — no SRI | T5/T2 | Add integrity |
admin-console |
| admin_console_R | F-6 — HMR overlay disabled (dev-only) | — | Re-enable in dev | admin-console |
| admin_console_R | F-7 — lovable-tagger dev plugin |
T6 | Ensure dev-only | admin-console |
| admin_console_R | F-8 — fs.deny minimal (dev-only) |
— | Tighten Vite fs.deny |
admin-console |
| admin_console_R | F-9 — no DOMPurify for dangerouslySetInnerHTML |
T5 | Sanitize / react/no-danger lint |
admin-console |
| admin_console_R | F-10 — localStorage["user_email"] |
— | Don't persist PII; clear on logout | admin-console |
| Someli-Designer | F-5 — CDN scripts without SRI | T5/T2 | Add integrity / self-host |
designer-fe |
| Someli-Designer | F-7 — Bootstrap-Vue v2 ↔ Bootstrap v5 mismatch (UX) | — | Align versions | designer-fe |
| Someli-Designer | F-8 — Polotno design persistence in localStorage |
— | Scope/clear | designer-fe |
| Someli-Designer | F-9 — bcryptjs in client deps (client-side hashing) |
— | Remove; hash server-side | designer-fe |
| Someli-Designer | F-10 — hot-loaded jQuery via Bootstrap bundle | T6 | Pin/self-host | designer-fe |
Cross-component items (in
Someli-admin-api's "out of scope" section) and thesomeli-dashboard-be↔someli-api/dashboard/drift are not double-counted here; see those docs.
4. Prioritized remediation worklist (cross-repo, phased)¶
Phase 0a — this week (Critical + secret exposure)¶
someli-apilogin handler (routes/routes.js:6522+): remove thesocial:truetoken-grant branch, parameterize/webauthenticate&/authenticate, drop thepassword == hashfallback, strip credential logs. steps- Rotate every committed/hardcoded secret — assume all are compromised:
someli-platformAWS access key + secret (WC-SEC-1)designer-apiSlack token (F-1), Unsplash key (F-2), Google OAuthcredentials.json(F-6), Polotno key (F-9)Someli-admin-apisession secret (F-1), Slack token (F-2),credentials.json(F-10)someli-apiSlack token, Polotno key, session secretsomeli-dashboard-besession secret fallback (F-1)designer-apiDocker: remove.envfrom the imageCOPY(F-13); rotate anything that was baked in.- Scrub git history for the above (
git-filter-repo/bfg), force-push, re-clone; addgitleaksto CI.
Phase 0 — months 0–3 (High + baseline hardening)¶
- HttpOnly server-set session cookies across
someli-platform(WC-AUTH-2),admin_console_R(F-1),Someli-Designer(F-2); add 401→logout and server-side logout. - Parameterize remaining interpolated SQL in
designer-api(F-7),Someli-admin-api(F-8),someli-dashboard-be; add the Semgrep guard (T1). - Baseline HTTP hardening in each Express
server.js:helmet(),express-rate-limit(esp. auth), CORS allow-lists, sane body limits —someli-api,designer-api,Someli-admin-api,someli-dashboard-be. - nginx headers for the SPAs (CSP, HSTS, X-Frame-Options/
frame-ancestors, X-Content-Type-Options,ssl_protocols TLSv1.2 TLSv1.3,server_tokens off) —someli-platform(WC-SEC-7/16/17/18),Someli-Designer(F-6). - SRI on all CDN scripts (
someli-platform,admin_console_R,Someli-Designer); DOMPurify forv-html/dangerouslySetInnerHTML. - bcrypt for password storage/compare everywhere (
someli-api); token expiry + persistent revocation (someli-api,Someli-admin-api). - Enable Dependabot security PRs across all repos.
Phase 1 — months 3–9 (server-side authz, cleanup)¶
- Server-side authorization per request — remove client-trusted role gating (
someli-platformWC-AUTH-4,Someli-DesignerF-4,Someli-admin-apiF-7,someli-dashboard-beF-2). - Unify the token model; remove plaintext
/auth/logintoken format. - Prune spurious deps; resolve
admin_console_Rtriple lockfile; drop/SRI-pin the Lovable.dev script (F-3). - Resolve the verify-markers (token-in-URL, public env-var bundle, CORS allow-lists, Polotno license terms).
Phase 2+ — months 9+¶
- Vue 2 → Vue 3 / Nuxt 2 → Nuxt 3 migration (
someli-platform,Someli-Designer) — fixes the EOL class (WC-SEC-5). - SOC 2 readiness (combined frontend + backend).
5. Maintenance¶
This register is generated from the per-repo security.md docs as of 2026-05-22. When you fix or re-triage a finding, update the per-repo doc (it holds the evidence and Fix steps) and reflect status here. Re-amalgamate after any batch of fixes or the next audit cycle. Related cross-repo context: CODE-OVERLAP-MATRIX.md, architecture-findings.md, PLATFORM-OVERVIEW.md.