# Authentication Analysis Report ## 1. Executive Summary - **Analysis Status:** Complete - **Key Outcome:** Critical authentication flaws were identified in the passwordless authentication system, including a hardcoded backdoor authentication code, missing rate limiting across all authentication endpoints, lack of session rotation, and insufficient cache control on sensitive responses. - **Purpose of this Document:** This report provides the strategic context on the application's authentication mechanisms, dominant flaw patterns, and key architectural details necessary to effectively exploit the vulnerabilities listed in the exploitation queue. **Overall Security Posture:** The Inou health portal implements a passwordless email-based authentication system with solid cryptographic foundations (secure token generation, proper OAuth 2.0 implementation), but suffers from critical implementation gaps that make it vulnerable to brute-force attacks, session hijacking, and authentication bypass. The most severe finding is a hardcoded backdoor authentication code that allows complete authentication bypass for any account. **Critical Findings Summary:** - **1 CRITICAL** backdoor authentication vulnerability enabling universal account access - **6 HIGH** severity vulnerabilities related to brute-force defenses and session management - **4 MEDIUM** severity issues in transport security and OAuth flows - **Multiple SAFE** implementations including OAuth token validation and redirect URI handling ## 2. Dominant Vulnerability Patterns ### Pattern 1: Missing Brute-Force Defenses (CRITICAL) - **Description:** All five authentication endpoints (POST /send-code, POST /verify, POST /api/v1/auth/send, POST /api/v1/auth/verify, POST /oauth/token) completely lack rate limiting, CAPTCHA, account lockout, and failed attempt tracking. This creates a systematic vulnerability allowing unlimited authentication attempts. - **Implication:** Attackers can execute brute-force attacks against 6-digit verification codes (000000-999999) with no throttling. At 100 requests/second, an attacker can compromise any account in approximately 83 minutes on average. Email flooding attacks are also possible, allowing denial-of-service against victim email addresses. - **Representative Findings:** `AUTH-VULN-01` (brute-force verification bypass), `AUTH-VULN-02` (email flooding DoS), `AUTH-VULN-03` (OAuth token endpoint brute-force). - **Code Location:** No rate limiting middleware exists in `/repos/inou-portal/portal/defense.go`. Authentication handlers at `/repos/inou-portal/portal/main.go:540-590` and `/repos/inou-portal/portal/api_mobile.go:55-149` perform no attempt tracking. ### Pattern 2: Session Management Vulnerabilities (HIGH) - **Description:** The session management system exhibits multiple critical flaws: (1) session identifiers are never rotated on login, enabling session fixation attacks; (2) logout only clears client-side cookies without server-side invalidation, allowing stolen sessions to persist indefinitely; (3) no idle or absolute timeouts for web and mobile sessions; (4) sessions are not bound to IP addresses or user agents. - **Implication:** Once an attacker obtains a session cookie (through XSS, network interception, or physical access), they can maintain persistent access even after the victim logs out. Session fixation attacks are trivial to execute. Mobile session tokens never expire, providing unlimited access once obtained. - **Representative Findings:** `AUTH-VULN-04` (session fixation), `AUTH-VULN-05` (logout doesn't invalidate sessions), `AUTH-VULN-06` (mobile tokens never expire). - **Code Locations:** - Session cookie creation: `/repos/inou-portal/portal/main.go:311-313` (always uses same dossierID) - Verification handler: `/repos/inou-portal/portal/main.go:560-590` (returns same ID each login) - Logout handler: `/repos/inou-portal/portal/main.go:638-641` (only clears client cookie) - Mobile token generation: `/repos/inou-portal/portal/api_mobile.go:136-141` (reuses existing tokens) ### Pattern 3: Hardcoded Backdoor Credentials (CRITICAL) - **Description:** A hardcoded verification code `250365` exists in the code that bypasses all authentication checks and grants access to any email address without requiring the actual verification code sent via email. - **Implication:** Any attacker who discovers this code can authenticate as any user in the system by entering any email address and the backdoor code. This completely undermines the authentication system and represents a catastrophic security failure for a healthcare application handling PHI. - **Representative Findings:** `AUTH-VULN-07` (hardcoded backdoor authentication code). - **Code Locations:** - Web portal verification: `/repos/inou-portal/lib/dbcore.go:347` - `if code != 250365 && storedCode != ...` - Mobile API verification: `/repos/inou-portal/portal/api_mobile.go:127-128` - `if code != 250365 && (d.AuthCode != code || ...)` ### Pattern 4: Missing Transport Security Controls (MEDIUM) - **Description:** Critical authentication responses lack proper cache control headers, and the application runs on HTTP without enforcing HTTPS at the application layer or setting HSTS headers. - **Implication:** Session tokens and authentication responses could be cached by browsers, proxy servers, or CDNs, exposing them to unauthorized access. The lack of HTTPS enforcement and HSTS headers leaves the application vulnerable to SSL stripping and man-in-the-middle attacks. - **Representative Findings:** `AUTH-VULN-08` (missing cache control on token responses), `AUTH-VULN-09` (no HSTS headers). - **Code Locations:** - Mobile API response helpers: `/repos/inou-portal/portal/api_mobile.go:256-265` (no Cache-Control headers) - Server configuration: `/repos/inou-portal/portal/main.go:1963-1964` (HTTP only on port 1080) - Render function: `/repos/inou-portal/portal/main.go:502-513` (no security headers) ## 3. Strategic Intelligence for Exploitation ### Authentication System Architecture **Primary Authentication Method:** Passwordless email-based verification using 6-digit codes - Code generation uses cryptographically secure random (crypto/rand) - Codes expire after 10 minutes - Codes are single-use (cleared from database after successful verification) - Backdoor code `250365` bypasses all checks **Session Management:** - **Web Portal:** Cookie named `login` containing raw dossierID (16-character hex) - **Mobile API:** Bearer token with 64-character hex SessionToken stored in Dossier.SessionToken field - **OAuth:** Encrypted AES-GCM access tokens (15-minute expiry) + refresh tokens (30-day expiry) **Token Properties:** - All tokens generated using crypto/rand with sufficient entropy (64-256 bits) - DossierID: 16-character hex (64 bits entropy) - SessionToken: 64-character hex (256 bits entropy) - OAuth tokens: AES-256-GCM encrypted JSON payloads ### Key Defensive Gaps 1. **No Rate Limiting:** Zero throttling on any authentication endpoint. The only delay is a trivial nonce check requiring client-side 2-second wait. 2. **No Session Rotation:** The same dossierID is used as the session identifier across all logins. Once you have a valid dossierID, it remains valid indefinitely unless manually changed in the database. 3. **No Server-Side Session Store:** Sessions are stateless - the dossierID in the cookie IS the authentication. No server-side session tracking or invalidation mechanism exists. 4. **Cookie Flags:** While HttpOnly and Secure flags are properly set, these protections are undermined by: - Running on HTTP (port 1080) making Secure flag ineffective - No HSTS to force HTTPS - No session binding to IP/User-Agent 5. **OAuth Implementation:** Generally secure with proper PKCE, redirect URI validation, and token encryption. Weakness: state parameter not enforced (CSRF risk). ### Exploitation Methodology Recommendations **For Brute-Force Attacks:** 1. Target POST /verify or POST /api/v1/auth/verify 2. Use the backdoor code `250365` for instant access (if known) 3. Or systematically try all 1,000,000 possible codes without throttling 4. No lockout will occur - unlimited attempts allowed **For Session Hijacking:** 1. Obtain a valid session cookie through any means (XSS, network sniffing, physical access) 2. Cookie remains valid indefinitely - no expiration checking 3. Even if victim logs out, stolen cookie continues working 4. No IP or User-Agent binding to detect usage from different location **For Email Flooding DoS:** 1. Call POST /send-code or POST /api/v1/auth/send repeatedly with victim's email 2. No rate limiting prevents unlimited code generation 3. Victim's inbox floods with verification codes 4. Legitimate login becomes impossible ### Credential Handling Details **Backdoor Code Discovery Path:** - Code appears in two locations with identical logic - Likely intended as development/testing feature - Comment suggests removal before production: "TODO: Remove backdoor" - Pattern: `if code != 250365 && ...` makes 250365 always succeed **Verification Code Generation:** ```go // Generates 6-digit code (000000-999999) func generateCode() int { code := 0 for i := 0; i < 6; i++ { n, _ := rand.Int(rand.Reader, big.NewInt(10)) code = code*10 + int(n.Int64()) } return code } ``` - Cryptographically random but only 10^6 possibilities - Without rate limiting, brute force is trivial ## 4. Secure by Design: Validated Components These components were analyzed and found to have robust defenses. They are low-priority for further testing. | Component/Flow | Endpoint/File Location | Defense Mechanism Implemented | Verdict | |---|---|---|---| | Token Generation Entropy | `/repos/inou-portal/lib/dbcore.go:61-67` | Uses crypto/rand for all tokens (64-256 bits entropy) | SAFE | | OAuth Redirect URI Validation | `/repos/inou-portal/lib/db_queries.go:803-810` | Exact string matching, no wildcards or prefix matching | SAFE | | OAuth Token Encryption | `/repos/inou-portal/lib/crypto.go:174-207` | AES-256-GCM authenticated encryption with expiration validation | SAFE | | OAuth Access Token Expiration | `/repos/inou-portal/portal/oauth.go:28` | 15-minute expiry enforced on every token validation | SAFE | | OAuth Refresh Token Rotation | `/repos/inou-portal/portal/oauth.go:279` | New refresh token issued and old one invalidated on each use | SAFE | | OAuth PKCE Verification | `/repos/inou-portal/lib/db_queries.go:862-875` | SHA256(code_verifier) validated against stored code_challenge | SAFE | | OAuth User Identification | Token payload structure | Uses immutable DossierID as subject, not mutable email | SAFE (nOAuth immune) | | Session Cookie Flags | `/repos/inou-portal/portal/main.go:311-313` | HttpOnly=true, Secure=true, SameSite=Lax properly configured | SAFE | | Verification Code Entropy | `/repos/inou-portal/lib/dbcore.go:363-371` | Crypto/rand with proper big.Int to avoid modulo bias | SAFE | | Code Expiration | `/repos/inou-portal/portal/api_mobile.go:85` | 10-minute TTL enforced on verification codes | SAFE | | Single-Use Codes | `/repos/inou-portal/lib/dbcore.go:350` | Code cleared from database after successful verification | SAFE | | OAuth Client Secret Storage | `/repos/inou-portal/lib/db_queries.go:750` | Bcrypt hashing with proper comparison | SAFE | | SQL Injection Protection | All database queries | Parameterized queries used throughout (no string concatenation) | SAFE | | Template Injection Protection | `/repos/inou-portal/portal/main.go:230` | Templates preloaded, user data passed as structured objects | SAFE | ### Additional Secure Implementations **Passwordless Architecture:** - System is truly passwordless - no password fields exist anywhere - Eliminates entire class of password-related vulnerabilities - No password storage, no bcrypt complexity, no password reset vulnerabilities **OAuth 2.0 Implementation:** - Follows RFC 6749 (OAuth 2.0) and RFC 7636 (PKCE) specifications - Encrypted tokens prevent tampering (AES-GCM authenticated encryption) - Authorization codes are single-use with 10-minute expiry - Refresh tokens properly expire after 30 days **Error Message Handling:** - Generic error messages prevent username enumeration via error responses - "Invalid or expired code" does not distinguish between wrong code vs expired - Same HTTP status codes regardless of failure reason **Bot Protection:** - Minimal nonce-based timing check requires 2000ms client-side delay - Limited effectiveness but shows awareness of automated attacks - Located at `/repos/inou-portal/portal/main.go:542` ## 5. Detailed Vulnerability Analysis ### AUTH-VULN-01: Brute-Force Verification Code Attack (HIGH) **Vulnerability Type:** Abuse_Defenses_Missing **Externally Exploitable:** Yes **Source Endpoint:** POST /verify, POST /api/v1/auth/verify **Technical Analysis:** The verification code validation logic accepts 6-digit codes (000000-999999) without any rate limiting, account lockout, or attempt tracking. An attacker can systematically try all 1,000,000 possible codes for any email address. **Code Flow:** 1. POST /verify handler at `/repos/inou-portal/portal/main.go:560-590` 2. Calls `lib.DossierVerify(email, code)` at `/repos/inou-portal/lib/dbcore.go:330-353` 3. No attempt tracking before or after validation 4. Failed attempts return generic error with no side effects **Missing Defense:** Per-IP and per-account rate limiting on verification attempts. No exponential backoff. No account lockout after N failed attempts. No CAPTCHA trigger. **Exploitation Hypothesis:** An attacker can successfully authenticate to any account by iterating through all possible 6-digit verification codes. With no rate limiting, this takes approximately 83 minutes at 100 requests/second (500,000 average attempts). **Confidence:** High - Code review confirms complete absence of rate limiting. Attack is deterministic. --- ### AUTH-VULN-02: Email Flooding Denial of Service (HIGH) **Vulnerability Type:** Abuse_Defenses_Missing **Externally Exploitable:** Yes **Source Endpoint:** POST /send-code, POST /api/v1/auth/send **Technical Analysis:** The code generation endpoints accept email addresses and generate verification codes without any rate limiting per email address or per IP. An attacker can flood any victim's email inbox with unlimited verification codes. **Code Flow:** 1. POST /send-code handler at `/repos/inou-portal/portal/main.go:540-557` 2. Only validation is 2-second nonce check (trivially bypassable) 3. Calls `lib.DossierLogin(email)` which generates new code 4. Sends email via SMTP without throttling **Missing Defense:** Per-email rate limiting (max N codes per email per hour). Per-IP rate limiting. CAPTCHA after repeated requests from same IP. **Exploitation Hypothesis:** An attacker can deny service to any user by flooding their email with verification codes, making legitimate login impossible and overwhelming the victim's inbox. Attack continues indefinitely without intervention. **Confidence:** High - No rate limiting exists. Attack requires only email address knowledge (often public). --- ### AUTH-VULN-03: OAuth Token Endpoint Brute-Force (MEDIUM) **Vulnerability Type:** Abuse_Defenses_Missing **Externally Exploitable:** Yes **Source Endpoint:** POST /oauth/token **Technical Analysis:** The OAuth token endpoint validates client secrets and authorization codes without rate limiting. While bcrypt adds computational cost, an attacker can still attempt credential stuffing or brute-force attacks on leaked client IDs. **Code Flow:** 1. POST /oauth/token handler at `/repos/inou-portal/portal/oauth.go:144-296` 2. Client secret validated via bcrypt at line 198 3. No tracking of failed authentication attempts 4. No rate limiting per client_id **Missing Defense:** Rate limiting on failed client_secret attempts. Monitoring and alerting for credential stuffing. Account lockout for clients after N failures. **Exploitation Hypothesis:** An attacker who obtains a valid client_id (through config leaks or reconnaissance) can attempt to brute-force or credential-stuff the client_secret without throttling, eventually gaining OAuth access tokens. **Confidence:** Medium - Bcrypt slows attacks but doesn't prevent them. Success depends on obtaining valid client_id first. --- ### AUTH-VULN-04: Session Fixation Vulnerability (HIGH) **Vulnerability Type:** Login_Flow_Logic **Externally Exploitable:** Yes **Source Endpoint:** POST /verify (login flow) **Technical Analysis:** Session identifiers (dossierID values) are never rotated on login. The same dossierID is returned for every login by the same user. This enables classic session fixation attacks where an attacker can force a victim to use a known session identifier. **Code Flow:** 1. POST /verify calls `lib.DossierVerify(email, code)` at `/repos/inou-portal/lib/dbcore.go:330-353` 2. Returns existing `entryID` (dossierID) without generating new identifier 3. `setLoginCookie(w, id)` at `/repos/inou-portal/portal/main.go:311-313` sets cookie to same ID 4. No session ID rotation mechanism exists **Vulnerable Code:** ```go // /repos/inou-portal/lib/dbcore.go:351 return entryID, true // Always returns same ID for same email ``` **Missing Defense:** Session ID rotation on authentication. New session identifier should be generated for each successful login, invalidating any pre-existing sessions. **Exploitation Hypothesis:** An attacker can obtain a victim's dossierID (through social engineering or other means), set that as the victim's cookie value, then wait for the victim to authenticate. After authentication, the attacker's pre-set session becomes authenticated. **Confidence:** High - Code confirms no session rotation. Attack pattern is well-established. --- ### AUTH-VULN-05: Logout Does Not Invalidate Sessions (CRITICAL) **Vulnerability Type:** Session_Management_Flaw **Externally Exploitable:** Yes **Source Endpoint:** GET /logout **Technical Analysis:** The logout function only clears the client-side cookie without any server-side session invalidation. Stolen session cookies remain valid indefinitely even after the victim logs out. **Code Flow:** 1. GET /logout handler at `/repos/inou-portal/portal/main.go:638-641` 2. Calls `clearLoginCookie(w)` which sets MaxAge=-1 3. No database UPDATE to invalidate session 4. No server-side session tracking to revoke **Vulnerable Code:** ```go // /repos/inou-portal/portal/main.go:638-641 func handleLogout(w http.ResponseWriter, r *http.Request) { clearLoginCookie(w) // Only clears client cookie http.Redirect(w, r, "/", http.StatusSeeOther) } ``` **Missing Defense:** Server-side session invalidation. Database field to track session validity. Session revocation API. Clear SessionToken from Dossier record on logout. **Exploitation Hypothesis:** An attacker who obtains a valid session cookie (through XSS, network interception, or physical access to device) maintains full account access even after the victim explicitly logs out. The stolen session persists indefinitely. **Confidence:** High - Logout implementation confirmed to be client-side only. No server-side invalidation mechanism exists. --- ### AUTH-VULN-06: Mobile Session Tokens Never Expire (HIGH) **Vulnerability Type:** Token_Management_Issue **Externally Exploitable:** Yes **Source Endpoint:** POST /api/v1/auth/verify **Technical Analysis:** Mobile session tokens (Dossier.SessionToken field) are generated once and reused indefinitely with no expiration timestamp or validation. Once generated, they provide permanent API access. **Code Flow:** 1. POST /api/v1/auth/verify generates token at `/repos/inou-portal/portal/api_mobile.go:136-141` 2. Token stored in database without expiration field 3. Token lookup at `/repos/inou-portal/lib/dbcore.go:356-364` has no expiration check 4. No invalidation mechanism exists **Vulnerable Code:** ```go // /repos/inou-portal/portal/api_mobile.go:136-141 token := d.SessionToken if token == "" { token = generateSessionToken() // Generated once lib.DossierSetSessionToken(d.DossierID, token) } ``` **Missing Defense:** Expiration timestamp for SessionToken field. Token validation checking expiry. Token rotation on re-authentication. Logout endpoint for mobile API. **Exploitation Hypothesis:** An attacker who obtains a mobile SessionToken through any means (traffic interception, device compromise, leaked backups) gains permanent API access. No expiration or revocation mechanism exists. **Confidence:** High - Database schema and validation code confirm no expiration checking. --- ### AUTH-VULN-07: Hardcoded Backdoor Authentication Code (CRITICAL) **Vulnerability Type:** Login_Flow_Logic **Externally Exploitable:** Yes **Source Endpoint:** POST /api/v1/auth/verify, POST /verify **Technical Analysis:** A hardcoded verification code `250365` exists in the authentication logic that bypasses all verification checks. This code works for any email address without requiring the actual emailed code. **Code Flow:** 1. Web verification: `/repos/inou-portal/lib/dbcore.go:347` 2. Mobile verification: `/repos/inou-portal/portal/api_mobile.go:127-128` 3. Both check `if code != 250365 && ...` making 250365 always succeed 4. No additional validation or logging for backdoor usage **Vulnerable Code:** ```go // /repos/inou-portal/lib/dbcore.go:347 if code != 250365 && storedCode != fmt.Sprintf("%06d", code) { return "", false } ``` **Missing Defense:** Removal of backdoor code. If needed for testing, restrict to development environment only. Add logging and alerting for backdoor usage attempts. **Exploitation Hypothesis:** An attacker who discovers code `250365` can authenticate as any user by entering any email address and the backdoor code. This provides complete authentication bypass for the entire application. **Confidence:** High - Hardcoded value confirmed in source code. Attack is deterministic and requires no preconditions. **Severity Justification:** CRITICAL - This is a complete authentication bypass affecting all accounts. For a healthcare application handling PHI, this represents a catastrophic security failure with severe HIPAA and GDPR implications. --- ### AUTH-VULN-08: Missing Cache-Control on Token Responses (MEDIUM) **Vulnerability Type:** Transport_Exposure **Externally Exploitable:** Yes **Source Endpoint:** POST /api/v1/auth/verify, POST /send-code, POST /verify **Technical Analysis:** Authentication responses that contain session tokens or verification codes do not set `Cache-Control: no-store` headers, allowing these sensitive responses to be cached by browsers, CDNs, or proxy servers. **Code Flow:** 1. Mobile API uses `jsonOK()` helper at `/repos/inou-portal/portal/api_mobile.go:256-259` 2. Helper sets Content-Type but no Cache-Control header 3. Session token returned in response at line 148 without cache prevention 4. Web auth uses `render()` function which also lacks cache headers **Vulnerable Code:** ```go // /repos/inou-portal/portal/api_mobile.go:256-259 func jsonOK(w http.ResponseWriter, data interface{}) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(data) // No Cache-Control set } ``` **Missing Defense:** Set `Cache-Control: no-store, no-cache, must-revalidate` and `Pragma: no-cache` headers on all authentication responses. **Exploitation Hypothesis:** An attacker with access to browser cache, proxy logs, or CDN caches can retrieve previously issued session tokens, gaining unauthorized access to accounts without needing to authenticate. **Confidence:** High - Missing headers confirmed in code. Browser caching behavior is well-documented. --- ### AUTH-VULN-09: No HTTPS Enforcement or HSTS (MEDIUM) **Vulnerability Type:** Transport_Exposure **Externally Exploitable:** Yes **Source Endpoint:** All endpoints **Technical Analysis:** The application currently runs on HTTP (port 1080) without HTTPS enforcement at the application level. No HSTS headers are set to instruct browsers to always use HTTPS. While a reverse proxy may handle TLS termination, no application-level verification exists. **Code Flow:** 1. Server starts on HTTP port 1080 at `/repos/inou-portal/portal/main.go:1963-1964` 2. No middleware checks X-Forwarded-Proto header 3. No HSTS headers set in defense middleware 4. Cookies set with Secure flag will fail over HTTP **Vulnerable Configuration:** ```go // /repos/inou-portal/portal/main.go:1963-1964 fmt.Println("Portal starting on :1080") if err := http.ListenAndServe(":1080", setupMux()); err != nil { ``` **Missing Defense:** Application-level HTTPS enforcement (redirect HTTP to HTTPS or reject HTTP requests). HSTS header with appropriate max-age. Verification that reverse proxy is properly configured. **Exploitation Hypothesis:** An attacker can execute SSL stripping attacks to downgrade connections to HTTP, intercepting session cookies and authentication tokens in transit. Without HSTS, users' browsers will not enforce HTTPS. **Confidence:** Medium - Assumes production deployment lacks proper TLS termination. If reverse proxy properly handles HTTPS, impact is reduced but application-level defense is still missing. --- ### AUTH-VULN-10: OAuth State Parameter Not Enforced (MEDIUM) **Vulnerability Type:** OAuth_Flow_Issue **Externally Exploitable:** Yes **Source Endpoint:** GET /oauth/authorize **Technical Analysis:** The OAuth authorization endpoint accepts but does not enforce the `state` parameter. The state value is stored and returned but not validated as required. This creates CSRF vulnerability in the OAuth flow. **Code Flow:** 1. GET /oauth/authorize at `/repos/inou-portal/portal/oauth.go:52-140` 2. State parameter extracted at line 62: `state := r.URL.Query().Get("state")` 3. State stored in authorization code record but not validated 4. No minimum length requirement or randomness check **Missing Defense:** Require state parameter (return error if missing). Validate state is sufficiently random (min 16 characters). Enforce state validation at token exchange. **Exploitation Hypothesis:** An attacker can craft a malicious OAuth authorization URL without a state parameter and trick a victim into clicking it. The victim's authorization will be issued to the attacker's redirect_uri without CSRF protection. **Confidence:** Medium - State parameter is accepted but not required. CSRF attack requires social engineering but is feasible.