26 KiB
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-590and/repos/inou-portal/portal/api_mobile.go:55-149perform 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)
- Session cookie creation:
Pattern 3: Hardcoded Backdoor Credentials (CRITICAL)
- Description: A hardcoded verification code
250365exists 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 || ...)
- Web portal verification:
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)
- Mobile API response helpers:
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
250365bypasses all checks
Session Management:
- Web Portal: Cookie named
logincontaining 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
-
No Rate Limiting: Zero throttling on any authentication endpoint. The only delay is a trivial nonce check requiring client-side 2-second wait.
-
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.
-
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.
-
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
-
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:
- Target POST /verify or POST /api/v1/auth/verify
- Use the backdoor code
250365for instant access (if known) - Or systematically try all 1,000,000 possible codes without throttling
- No lockout will occur - unlimited attempts allowed
For Session Hijacking:
- Obtain a valid session cookie through any means (XSS, network sniffing, physical access)
- Cookie remains valid indefinitely - no expiration checking
- Even if victim logs out, stolen cookie continues working
- No IP or User-Agent binding to detect usage from different location
For Email Flooding DoS:
- Call POST /send-code or POST /api/v1/auth/send repeatedly with victim's email
- No rate limiting prevents unlimited code generation
- Victim's inbox floods with verification codes
- 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:
// 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:
- POST /verify handler at
/repos/inou-portal/portal/main.go:560-590 - Calls
lib.DossierVerify(email, code)at/repos/inou-portal/lib/dbcore.go:330-353 - No attempt tracking before or after validation
- 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:
- POST /send-code handler at
/repos/inou-portal/portal/main.go:540-557 - Only validation is 2-second nonce check (trivially bypassable)
- Calls
lib.DossierLogin(email)which generates new code - 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:
- POST /oauth/token handler at
/repos/inou-portal/portal/oauth.go:144-296 - Client secret validated via bcrypt at line 198
- No tracking of failed authentication attempts
- 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:
- POST /verify calls
lib.DossierVerify(email, code)at/repos/inou-portal/lib/dbcore.go:330-353 - Returns existing
entryID(dossierID) without generating new identifier setLoginCookie(w, id)at/repos/inou-portal/portal/main.go:311-313sets cookie to same ID- No session ID rotation mechanism exists
Vulnerable Code:
// /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:
- GET /logout handler at
/repos/inou-portal/portal/main.go:638-641 - Calls
clearLoginCookie(w)which sets MaxAge=-1 - No database UPDATE to invalidate session
- No server-side session tracking to revoke
Vulnerable Code:
// /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:
- POST /api/v1/auth/verify generates token at
/repos/inou-portal/portal/api_mobile.go:136-141 - Token stored in database without expiration field
- Token lookup at
/repos/inou-portal/lib/dbcore.go:356-364has no expiration check - No invalidation mechanism exists
Vulnerable Code:
// /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:
- Web verification:
/repos/inou-portal/lib/dbcore.go:347 - Mobile verification:
/repos/inou-portal/portal/api_mobile.go:127-128 - Both check
if code != 250365 && ...making 250365 always succeed - No additional validation or logging for backdoor usage
Vulnerable Code:
// /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:
- Mobile API uses
jsonOK()helper at/repos/inou-portal/portal/api_mobile.go:256-259 - Helper sets Content-Type but no Cache-Control header
- Session token returned in response at line 148 without cache prevention
- Web auth uses
render()function which also lacks cache headers
Vulnerable Code:
// /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:
- Server starts on HTTP port 1080 at
/repos/inou-portal/portal/main.go:1963-1964 - No middleware checks X-Forwarded-Proto header
- No HSTS headers set in defense middleware
- Cookies set with Secure flag will fail over HTTP
Vulnerable Configuration:
// /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:
- GET /oauth/authorize at
/repos/inou-portal/portal/oauth.go:52-140 - State parameter extracted at line 62:
state := r.URL.Query().Get("state") - State stored in authorization code record but not validated
- 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.