Skip to content

BETA Threat Model: 0xj4f/genesis  #50

@0xj4f

Description

@0xj4f

Final Validation - Threat Model

Executive Summary (validated)

The Genesis IAM service contains several concrete security weaknesses that are validated against the source code.
The most critical issues are:

  • Static, hard‑coded JWT secret and debug print() statements that leak tokens (C1, C4, C7).
  • No revocation or replay protection for JWTs (C2).
  • Wildcard CORS that lets any origin make authenticated requests (C6).
  • No rate‑limiting or payload‑size checks, exposing the token endpoint and profile endpoints to brute‑force and DoS attacks (C8, C9).
  • Missing audit / security logging for authentication and data‑modifying actions (C5).
  • Database credentials are hard‑coded defaults (dev_project / SECURE_PASSWORD), making the DB accessible if the environment is not overridden (C3‑new T13).
  • Client‑side storage of JWTs in localStorage creates a clear XSS‑theft vector (new T12).

All other catalogued items (C10, C11) were found not applicable to the current implementation.


Consolidated Threat List (validated)

ID STRIDE Validation Result Evidence (file / snippet)
C1 Spoofing PARTIAL – the JWT signing secret is hard‑coded and printed, but user passwords are never stored in clear text. app/auth/auth.pySECRET_KEY = os.getenv("OAUTH_SECRET_KEY","0f2883…")
app/auth/auth.pyprint(f"token: {token}")
C2 Spoofing VALID – JWTs contain a jti claim but no store‑or‑check mechanism; replay is possible. app/auth/auth.py "jti": str(uuid.uuid4()), (no later lookup)
C3 Tampering PARTIAL – default MySQL credentials are hard‑coded; an attacker who obtains them could modify the DB. No raw SQL injection path. app/database/session.pyDATABASE_USER = os.getenv("MYSQL_DEV_USER","dev_project")
DATABASE_PASSWORD = os.getenv("MYSQL_DEV_PASSWORD","SECURE_PASSWORD")
C4 Tampering VALID – static secret enables an attacker who reads the source to forge arbitrary JWTs. Same evidence as C1 (hard‑coded secret).
C5 Repudiation VALID – the application logs only table‑creation events; authentication, token issuance, and profile changes are never recorded. app/main.pylogger.info("Creating tables...") (no other security‑relevant logs).
C6 Information Disclosure VALID – CORS is configured with a wildcard origin while allowing credentials. app/main.pyorigins = ["*"] and allow_credentials=True.
C7 Information Disclosure VALID – tokens (and usernames) are printed to stdout in the auth flow, potentially ending up in logs. app/auth/auth.pyprint(f"token: {token}") and print(username).
C8 Denial‑of‑Service VALID – no rate‑limiting is applied to the /token endpoint, permitting credential‑stuffing or brute‑force attacks. app/routes/auth.py/token route has no limiter middleware.
C9 Denial‑of‑Service VALID – profile CRUD endpoints accept unbounded JSON payloads; no size or request‑rate constraints are enforced. app/routes/profiles.pycreate_profile, update_own_profile, delete_own_profile accept any request body without checks.
C10 Elevation of Privilege INVALID – every protected request re‑validates the user record and aborts if user.disabled is true, so a disabled account cannot use an existing token. app/auth/auth.pyif user.disabled: raise HTTPException(status_code=400, detail="User is deactivated").
C11 Elevation of Privilege INVALID – the API currently has no privileged (admin) endpoints; lack of role claims does not constitute an actual risk today. No role‑related code in the repository.
T12 (new) Spoofing / Information Disclosure VALID – JWTs are stored in browser localStorage, which is readable by any script and thus vulnerable to XSS token theft. web/src/components/LoginForm.vuelocalStorage.setItem('access_token', result.access_token);
web/src/store/index.jslocalStorage.setItem('access_token', result.access_token); (same logic in the legacy component).
T13 (new) Tampering VALID – default MySQL credentials (dev_project / SECURE_PASSWORD) are compiled into the code; if the environment does not override them, the database is exposed with a known password. Same evidence as C3 (session.py defaults).

Recommendations (high‑level)

  1. Move the JWT secret out of source – load it exclusively from a secret manager or protected environment variable; remove the fallback hard‑coded value.
  2. Eliminate debug prints of tokens/user data.
  3. Adopt asymmetric JWT signing (RS256) with key rotation; expose a JWKS endpoint and include kid in the header.
  4. Persist jti values (e.g., Redis) and reject replayed tokens; provide a revocation list for logout/revoke.
  5. Shorten access‑token TTL (5 min) and rely on refresh tokens; enforce refresh‑token revocation on password change or disable.
  6. Implement structured audit logging for all auth events, token issuance, and CRUD operations; forward logs to a SIEM.
  7. Restrict CORS to an explicit allow‑list of trusted origins.
  8. Add rate‑limiting (e.g., slowapi or custom middleware) on /token, /refresh_token, and profile routes; lock accounts after repeated failures.
  9. Enforce request‑size limits (e.g., max_content_length=1 MiB) on profile endpoints.
  10. Remove hard‑coded DB defaults; require credentials via environment or secret store and give the DB user only needed privileges.
  11. Replace localStorage token storage with httpOnly/Secure cookies or a protected IndexedDB store; mitigate XSS exposure.

Addressing the validated findings will substantially raise the security posture of the Genesis IAM service.


audit trail: adaptive-npr-tmp-4-threat-model
https://adaptive-npr-tmp-4-threat-model.s3.eu-west-1.amazonaws.com/genesis%2F2026-01-27_04-35-17-4ae971e77d6dff934cbd7b1734e8fd5ceca1ef43

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions