
CVE-2026-4444용 PoC로, 신뢰할 수 없는 kid 주입을 통한 JWT 알고리즘 혼동을 시연하며, 취약한 Node.js 서버와 토큰 위조 및 권한 상승을 위한 Python 익스플로잇을 포함합니다.
// jwt_server.js - Vulnerable JWT verification server
const express = require('express');
const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');
const axios = require('axios');
const app = express();
app.use(express.json());
// Normally fetches public key from a JWKS endpoint, but vulnerable kid handling
async function getPublicKey(kid) {
// Attacker can inject a kid that points to their own URL
if (kid.startsWith('http://') || kid.startsWith('https://')) {
// Fetch the key from attacker-controlled URL (INSECURE!)
const response = await axios.get(kid);
return response.data.publicKey; // expects PEM
}
// Otherwise use local JWKS (simulated)
return `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCYZM5rPY4
...
-----END PUBLIC KEY-----`;
}
app.post('/api/verify', async (req, res) => {
const token = req.body.token;
const decoded = jwt.decode(token, { complete: true });
const kid = decoded.header.kid;
try {
const publicKey = await getPublicKey(kid);
const payload = jwt.verify(token, publicKey, { algorithms: ['RS256','HS256'] });
res.json({ status: 'authenticated', user: payload.sub });
} catch (e) {
res.status(401).json({ error: e.message });
}
});
app.listen(3000, () => console.log('JWT server on :3000'));
JWT 검증 서비스가 공개 키를 찾기 위해 kid 헤더를 맹목적으로 신뢰하여, 공격자가 자신의 키를 가리키는 URL을 제공할 수 있습니다. 이로 인해 완전한 토큰 위조와 권한 상승이 발생합니다.
kid URI에서 공개 키를 가져옵니다.node jwt_server.js
python exploit_jwt_kid.py