From 6456f3430545e88a9859baaf3acaa348a4491cc8 Mon Sep 17 00:00:00 2001 From: Aryan Sharma Date: Wed, 1 Oct 2025 14:34:45 +0530 Subject: [PATCH] improved isJWT to decode Base64 strings and verify their types --- .gitignore | 1 + src/lib/isJWT.js | 32 ++++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 86aaedee1..382feba65 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ yarn.lock /index.js validator.js validator.min.js +.idea diff --git a/src/lib/isJWT.js b/src/lib/isJWT.js index 1d0ade5ee..5fd25393a 100644 --- a/src/lib/isJWT.js +++ b/src/lib/isJWT.js @@ -1,15 +1,35 @@ import assertString from './util/assertString'; -import isBase64 from './isBase64'; + +function decodeBase64Url(str) { + str = str.replace(/-/g, '+').replace(/_/g, '/'); + const pad = str.length % 4; + if (pad) str += '='.repeat(4 - pad); + + if (typeof Buffer !== 'undefined') { + // Node.js + return Buffer.from(str, 'base64').toString('utf8'); + } else if (typeof atob !== 'undefined') { + // Browser + return atob(str); + } + throw new Error('No base64 decoder available'); +} export default function isJWT(str) { assertString(str); - const dotSplit = str.split('.'); - const len = dotSplit.length; + const parts = str.split('.'); + if (parts.length !== 3) return false; + try { + const header = JSON.parse(decodeBase64Url(parts[0])); + const payload = JSON.parse(decodeBase64Url(parts[1])); + + if (typeof header !== 'object' || header === null) return false; + if (typeof payload !== 'object' || payload === null) return false; + if (typeof header.alg !== 'string') return false; - if (len !== 3) { + return true; + } catch (e) { return false; } - - return dotSplit.reduce((acc, currElem) => acc && isBase64(currElem, { urlSafe: true }), true); }