DEV Community

Cover image for Getting Started with eslint-plugin-jwt
Ofri Peretz
Ofri Peretz

Posted on

Getting Started with eslint-plugin-jwt

13 JWT security rules. Algorithm attacks. Token validation. Secret management.

Quick Install

npm install --save-dev eslint-plugin-jwt
Enter fullscreen mode Exit fullscreen mode

Flat Config

// eslint.config.js
import jwt from 'eslint-plugin-jwt';

export default [jwt.configs.recommended];
Enter fullscreen mode Exit fullscreen mode

Run ESLint

npx eslint .
Enter fullscreen mode Exit fullscreen mode

You'll see output like:

src/auth.ts
  15:3  error  πŸ”’ CWE-347 CVSS:9.8 | JWT algorithm 'none' is allowed
               Fix: Remove 'none' from algorithms: ['HS256']

src/verify.ts
  28:5  error  πŸ”’ CWE-613 | JWT missing expiration
               Fix: Add expiresIn: '1h' or exp claim
Enter fullscreen mode Exit fullscreen mode

Rule Overview

Rule CWE What it catches
no-algorithm-none CWE-347 Algorithm 'none' bypass
no-algorithm-confusion CWE-327 RS256/HS256 confusion
no-weak-secret CWE-326 Brute-forceable secrets
no-hardcoded-secret CWE-798 Secrets in source code
no-sensitive-payload CWE-312 PII in token payload
require-expiration CWE-613 Missing exp claim
require-algorithm-whitelist CWE-327 No explicit algorithms
require-issuer-validation CWE-345 Missing iss check
require-audience-validation CWE-345 Missing aud check
no-decode-without-verify CWE-347 jwt.decode() misuse
require-issued-at CWE-613 Missing iat claim
require-max-age CWE-613 No maxAge in verify
no-timestamp-manipulation CWE-345 Clock skew exploits

Quick Wins

Before

// ❌ Algorithm none allowed
jwt.verify(token, secret, {
  algorithms: ['HS256', 'none'],
});
Enter fullscreen mode Exit fullscreen mode

After

// βœ… Explicit safe algorithm
jwt.verify(token, secret, {
  algorithms: ['HS256'],
});
Enter fullscreen mode Exit fullscreen mode

Before

// ❌ No expiration
jwt.sign({ userId: 123 }, secret);
Enter fullscreen mode Exit fullscreen mode

After

// βœ… Short-lived token
jwt.sign({ userId: 123 }, secret, {
  expiresIn: '1h',
});
Enter fullscreen mode Exit fullscreen mode

Complete Secure Pattern

// Signing
const token = jwt.sign({ userId: 123 }, process.env.JWT_SECRET, {
  expiresIn: '1h',
  algorithm: 'HS256',
  issuer: 'your-app',
  audience: 'your-api',
});

// Verifying
const payload = jwt.verify(token, process.env.JWT_SECRET, {
  algorithms: ['HS256'],
  issuer: 'your-app',
  audience: 'your-api',
  maxAge: '1h',
});
Enter fullscreen mode Exit fullscreen mode

Available Presets

// Security-focused configuration
jwt.configs.recommended;

// All rules enabled
jwt.configs.all;
Enter fullscreen mode Exit fullscreen mode

Quick Reference

# Install
npm install --save-dev eslint-plugin-jwt

# Config (eslint.config.js)
import jwt from 'eslint-plugin-jwt';
export default [jwt.configs.recommended];

# Run
npx eslint .
Enter fullscreen mode Exit fullscreen mode

πŸ“¦ npm: eslint-plugin-jwt
πŸ“– Full Rule List

⭐ Star on GitHub


πŸš€ Got JWT? Run the linter!

GitHub | LinkedIn | Dev.to

Top comments (0)