jwt-none-algorithm-usage¶
Ensure JWT algorithm defined
The usage of the none
algorithm with JSON Web Token (JWT) is highly risky. And shall be avoided at all costs, because there is simply no way to verify the authenticity or assert the integrity of such tokens. The none
algorithm simply means that the payload of the token is NOT cryptographically signed in any way (the signature part of the JWT is simply omitted). Using such method, would trivially allow a malicious actor to forge a token that will be implicitely considered valid. Instead of using the none
algorithm, you should use an algorithm such as HS256
(HMAC with SHA256), RS256
(RSA with SHA256) or ECS56
(ECDSA using P-256 with SHA256).
Examples¶
Insecure Example
package main
import (
"time"
"github.com/dgrijalva/jwt-go"
)
func GenerateJWT(userId string) string {
claims := jwt.StandardClaims{
Issuer: "server",
Subject: userId,
ExpiresAt: time.Now().Unix() + 3600,
}
token := jwt.NewWithClaims(jwt.SigningMethodNone, claims)
tokenString, _ := token.SignedString(jwt.UnsafeAllowNoneSignatureType)
return tokenString
}
package com.bigcorp.jwt;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
public class App
{
private static String generateJWT(String userId) throws Exception {
// Algorithm.none() is not safe
String token = JWT.create()
.withIssuer("server")
.withSubject(userId)
.sign(Algorithm.none());
return token;
}
}
const jwt = require('jsonwebtoken')
const SECRET = process.env.JWT_SECRET_KEY
function generateJWT(userId) {
const payload = {
Issuer: "server",
Subject: userId,
}
// { algorithm: 'none' } is not safe
const token = jwt.sign(payload, SECRET, {algorithm: 'none'}));
return token
}
import datetime
import jwt
JWT_SECRET = os.getenv('JWT_SECRET')
def generateJWT(userId):
#Generate token
timeLimit= datetime.datetime.utcnow() + datetime.timedelta(minutes=30) #set limit for user
payload = {"user_id": userId ,"exp":timeLimit}
# algorithm='none' is not safe
return jwt.encode(payload, JWT_SECRET, algorithm='none')
require 'json/jwt'
jwtsecret = ENV['JWT_SECRET']
def generate_jwt(userid)
# setting the algorithm parameter to 'none' is not safe
return JSON::JWT.new(payload).sign(jwtsecret, 'none')
end
Secure Example
package main
import (
"time"
"os"
"github.com/dgrijalva/jwt-go"
)
func getSigningKey() []byte {
secret := os.Getenv("JWT_SECRET")
if (secret == "") {
panic("JWT_SECRET environment variable not found - aborting")
}
return []byte(secret)
}
func GenerateJWT(userId string) string {
claims := jwt.StandardClaims{
Issuer: "server",
Subject: userId,
ExpiresAt: time.Now().Unix() + 3600,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, _ := token.SignedString(getSigningKey())
return tokenString
}
package com.bigcorp.jwt;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
public class App
{
private static String generateJWT(String userId) throws Exception {
String secret = System.getenv("JWT_SECRET");
// HMAC256 is a safe algorithm choice
String token = JWT.create()
.withIssuer("server")
.withSubject(userId)
.sign(Algorithm.HMAC256(secret));
return token;
}
}
const jwt = require('jsonwebtoken')
const SECRET = process.env.JWT_SECRET_KEY
function generateJWT(userId) {
const payload = {
Issuer: "server",
Subject: userId,
}
// { algorithm: 'HS256' } is a safe algorithm choice
const token = jwt.sign(payload, SECRET, {algorithm: 'HS256'}));
return token
}
import datetime
import jwt
JWT_SECRET = os.getenv('JWT_SECRET')
def generateJWT(userId):
#Generate token
timeLimit= datetime.datetime.utcnow() + datetime.timedelta(minutes=30) #set limit for user
payload = {"user_id": userId ,"exp":timeLimit}
# jwt.encode sets the optional parameter `algorithm` to 'HS256' by default
# so the line below is safe. The same thing can be done more explicitly with
# `return jwt.encode(payload, JWT_SECRET, algorithm='HS256')
return jwt.encode(payload, JWT_SECRET)
require 'json/jwt'
jwtsecret = ENV['JWT_SECRET']
def generate_jwt(userid)
# HS256 is a safe algorithm choice
return JSON::JWT.new(payload).sign(jwtsecret, 'HS256')
end