add test cases

This commit is contained in:
amammad
2023-08-29 21:34:02 +10:00
parent 65b97745c2
commit 4f04dc8f6e
18 changed files with 330 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
function getSecret() {
return "secret"
}
const DoValidate = false
module.exports = {getSecret, DoValidate}

View File

@@ -0,0 +1,14 @@
const expressjwt = require("express-jwt");
var {getSecret} = require('./Config.js');
app.get(
"/protected",
expressjwt.expressjwt({secret: getSecret(), algorithms: ["HS256"]}),
function (req, res) {
if (!req.auth.admin) return res.sendStatus(401);
res.sendStatus(200);
}
);
expressjwt.expressjwt({
secret: Buffer.from(getSecret(), "base64"),
algorithms: ["RS256"],
});

View File

@@ -0,0 +1,109 @@
nodes
| Config.js:2:12:2:19 | "secret" |
| Config.js:2:12:2:19 | "secret" |
| ExpressJWT.js:5:36:5:46 | getSecret() |
| ExpressJWT.js:5:36:5:46 | getSecret() |
| ExpressJWT.js:12:13:12:46 | Buffer. ... ase64") |
| ExpressJWT.js:12:13:12:46 | Buffer. ... ase64") |
| ExpressJWT.js:12:25:12:35 | getSecret() |
| jwtConstantKey.js:5:46:5:56 | getSecret() |
| jwtConstantKey.js:5:46:5:56 | getSecret() |
| jwtConstantKey.js:6:43:6:53 | getSecret() |
| jwtConstantKey.js:6:43:6:53 | getSecret() |
| jwtConstantKey.js:12:68:12:104 | new Tex ... cret()) |
| jwtConstantKey.js:12:68:12:104 | new Tex ... cret()) |
| jwtConstantKey.js:12:93:12:103 | getSecret() |
| jwtConstantKey.js:21:7:29:25 | spki |
| jwtConstantKey.js:21:14:29:25 | `-----B ... Y-----` |
| jwtConstantKey.js:21:14:29:25 | `-----B ... Y-----` |
| jwtConstantKey.js:34:9:34:52 | publicKey |
| jwtConstantKey.js:34:21:34:52 | await j ... i, alg) |
| jwtConstantKey.js:34:43:34:46 | spki |
| jwtConstantKey.js:35:65:35:73 | publicKey |
| jwtConstantKey.js:35:65:35:73 | publicKey |
| jwtConstantKey.js:51:42:51:52 | getSecret() |
| jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" |
| jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" |
| jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" |
| jwtConstantKey.js:51:56:51:59 | "fj" |
| jwtConstantKey.js:51:56:51:59 | "fj" |
| jwtNoVerification.js:5:46:5:56 | getSecret() |
| jwtNoVerification.js:5:46:5:56 | getSecret() |
| jwtNoVerification.js:19:26:19:36 | getSecret() |
| jwtNoVerification.js:19:26:19:36 | getSecret() |
| koaJWT.js:29:22:29:32 | getSecret() |
| koaJWT.js:29:22:29:32 | getSecret() |
| netxAuth.js:10:13:10:23 | getSecret() |
| netxAuth.js:10:13:10:23 | getSecret() |
| passportJWT.js:6:20:6:30 | getSecret() |
| passportJWT.js:6:20:6:30 | getSecret() |
edges
| Config.js:2:12:2:19 | "secret" | ExpressJWT.js:5:36:5:46 | getSecret() |
| Config.js:2:12:2:19 | "secret" | ExpressJWT.js:5:36:5:46 | getSecret() |
| Config.js:2:12:2:19 | "secret" | ExpressJWT.js:5:36:5:46 | getSecret() |
| Config.js:2:12:2:19 | "secret" | ExpressJWT.js:5:36:5:46 | getSecret() |
| Config.js:2:12:2:19 | "secret" | ExpressJWT.js:12:25:12:35 | getSecret() |
| Config.js:2:12:2:19 | "secret" | ExpressJWT.js:12:25:12:35 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:5:46:5:56 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:5:46:5:56 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:5:46:5:56 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:5:46:5:56 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:6:43:6:53 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:6:43:6:53 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:6:43:6:53 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:6:43:6:53 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:12:93:12:103 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:12:93:12:103 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:51:42:51:52 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:51:42:51:52 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtNoVerification.js:5:46:5:56 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtNoVerification.js:5:46:5:56 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtNoVerification.js:5:46:5:56 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtNoVerification.js:5:46:5:56 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtNoVerification.js:19:26:19:36 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtNoVerification.js:19:26:19:36 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtNoVerification.js:19:26:19:36 | getSecret() |
| Config.js:2:12:2:19 | "secret" | jwtNoVerification.js:19:26:19:36 | getSecret() |
| Config.js:2:12:2:19 | "secret" | koaJWT.js:29:22:29:32 | getSecret() |
| Config.js:2:12:2:19 | "secret" | koaJWT.js:29:22:29:32 | getSecret() |
| Config.js:2:12:2:19 | "secret" | koaJWT.js:29:22:29:32 | getSecret() |
| Config.js:2:12:2:19 | "secret" | koaJWT.js:29:22:29:32 | getSecret() |
| Config.js:2:12:2:19 | "secret" | netxAuth.js:10:13:10:23 | getSecret() |
| Config.js:2:12:2:19 | "secret" | netxAuth.js:10:13:10:23 | getSecret() |
| Config.js:2:12:2:19 | "secret" | netxAuth.js:10:13:10:23 | getSecret() |
| Config.js:2:12:2:19 | "secret" | netxAuth.js:10:13:10:23 | getSecret() |
| Config.js:2:12:2:19 | "secret" | passportJWT.js:6:20:6:30 | getSecret() |
| Config.js:2:12:2:19 | "secret" | passportJWT.js:6:20:6:30 | getSecret() |
| Config.js:2:12:2:19 | "secret" | passportJWT.js:6:20:6:30 | getSecret() |
| Config.js:2:12:2:19 | "secret" | passportJWT.js:6:20:6:30 | getSecret() |
| ExpressJWT.js:12:25:12:35 | getSecret() | ExpressJWT.js:12:13:12:46 | Buffer. ... ase64") |
| ExpressJWT.js:12:25:12:35 | getSecret() | ExpressJWT.js:12:13:12:46 | Buffer. ... ase64") |
| jwtConstantKey.js:12:93:12:103 | getSecret() | jwtConstantKey.js:12:68:12:104 | new Tex ... cret()) |
| jwtConstantKey.js:12:93:12:103 | getSecret() | jwtConstantKey.js:12:68:12:104 | new Tex ... cret()) |
| jwtConstantKey.js:21:7:29:25 | spki | jwtConstantKey.js:34:43:34:46 | spki |
| jwtConstantKey.js:21:14:29:25 | `-----B ... Y-----` | jwtConstantKey.js:21:7:29:25 | spki |
| jwtConstantKey.js:21:14:29:25 | `-----B ... Y-----` | jwtConstantKey.js:21:7:29:25 | spki |
| jwtConstantKey.js:34:9:34:52 | publicKey | jwtConstantKey.js:35:65:35:73 | publicKey |
| jwtConstantKey.js:34:9:34:52 | publicKey | jwtConstantKey.js:35:65:35:73 | publicKey |
| jwtConstantKey.js:34:21:34:52 | await j ... i, alg) | jwtConstantKey.js:34:9:34:52 | publicKey |
| jwtConstantKey.js:34:43:34:46 | spki | jwtConstantKey.js:34:21:34:52 | await j ... i, alg) |
| jwtConstantKey.js:51:42:51:52 | getSecret() | jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" |
| jwtConstantKey.js:51:42:51:52 | getSecret() | jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" |
| jwtConstantKey.js:51:56:51:59 | "fj" | jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" |
| jwtConstantKey.js:51:56:51:59 | "fj" | jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" |
| jwtConstantKey.js:51:56:51:59 | "fj" | jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" |
| jwtConstantKey.js:51:56:51:59 | "fj" | jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" |
#select
| ExpressJWT.js:5:36:5:46 | getSecret() | Config.js:2:12:2:19 | "secret" | ExpressJWT.js:5:36:5:46 | getSecret() | this $@. is used as a secret key | Config.js:2:12:2:19 | "secret" | Constant |
| ExpressJWT.js:12:13:12:46 | Buffer. ... ase64") | Config.js:2:12:2:19 | "secret" | ExpressJWT.js:12:13:12:46 | Buffer. ... ase64") | this $@. is used as a secret key | Config.js:2:12:2:19 | "secret" | Constant |
| jwtConstantKey.js:5:46:5:56 | getSecret() | Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:5:46:5:56 | getSecret() | this $@. is used as a secret key | Config.js:2:12:2:19 | "secret" | Constant |
| jwtConstantKey.js:6:43:6:53 | getSecret() | Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:6:43:6:53 | getSecret() | this $@. is used as a secret key | Config.js:2:12:2:19 | "secret" | Constant |
| jwtConstantKey.js:12:68:12:104 | new Tex ... cret()) | Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:12:68:12:104 | new Tex ... cret()) | this $@. is used as a secret key | Config.js:2:12:2:19 | "secret" | Constant |
| jwtConstantKey.js:35:65:35:73 | publicKey | jwtConstantKey.js:21:14:29:25 | `-----B ... Y-----` | jwtConstantKey.js:35:65:35:73 | publicKey | this $@. is used as a secret key | jwtConstantKey.js:21:14:29:25 | `-----B ... Y-----` | Constant |
| jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" | Config.js:2:12:2:19 | "secret" | jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" | this $@. is used as a secret key | Config.js:2:12:2:19 | "secret" | Constant |
| jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" | jwtConstantKey.js:51:56:51:59 | "fj" | jwtConstantKey.js:51:42:51:59 | getSecret() + "fj" | this $@. is used as a secret key | jwtConstantKey.js:51:56:51:59 | "fj" | Constant |
| jwtNoVerification.js:5:46:5:56 | getSecret() | Config.js:2:12:2:19 | "secret" | jwtNoVerification.js:5:46:5:56 | getSecret() | this $@. is used as a secret key | Config.js:2:12:2:19 | "secret" | Constant |
| jwtNoVerification.js:19:26:19:36 | getSecret() | Config.js:2:12:2:19 | "secret" | jwtNoVerification.js:19:26:19:36 | getSecret() | this $@. is used as a secret key | Config.js:2:12:2:19 | "secret" | Constant |
| koaJWT.js:29:22:29:32 | getSecret() | Config.js:2:12:2:19 | "secret" | koaJWT.js:29:22:29:32 | getSecret() | this $@. is used as a secret key | Config.js:2:12:2:19 | "secret" | Constant |
| netxAuth.js:10:13:10:23 | getSecret() | Config.js:2:12:2:19 | "secret" | netxAuth.js:10:13:10:23 | getSecret() | this $@. is used as a secret key | Config.js:2:12:2:19 | "secret" | Constant |
| passportJWT.js:6:20:6:30 | getSecret() | Config.js:2:12:2:19 | "secret" | passportJWT.js:6:20:6:30 | getSecret() | this $@. is used as a secret key | Config.js:2:12:2:19 | "secret" | Constant |

View File

@@ -0,0 +1,52 @@
// jsonwebtoken
const jwtJsonwebtoken = require('jsonwebtoken');
const {getSecret} = require('./Config.js');
const payloads = {foo: 'bar'}
const token = jwtJsonwebtoken.sign(payloads, getSecret());
console.log(jwtJsonwebtoken.verify(token, getSecret()))
// jose
const jose = require('jose')
async function startSymmetric() {
const {payload, protectedHeader} = await jose.jwtVerify(token, new TextEncoder().encode(getSecret()))
return {
payload, protectedHeader
}
}
startSymmetric().then(result => console.log(result))
const alg = 'RS256'
const spki = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwhYOFK2Ocbbpb/zVypi9
SeKiNUqKQH0zTKN1+6fpCTu6ZalGI82s7XK3tan4dJt90ptUPKD2zvxqTzFNfx4H
HHsrYCf2+FMLn1VTJfQazA2BvJqAwcpW1bqRUEty8tS/Yv4hRvWfQPcc2Gc3+/fQ
OOW57zVy+rNoJc744kb30NjQxdGp03J2S3GLQu7oKtSDDPooQHD38PEMNnITf0pj
+KgDPjymkMGoJlO3aKppsjfbt/AH6GGdRghYRLOUwQU+h+ofWHR3lbYiKtXPn5dN
24kiHy61e3VAQ9/YAZlwXC/99GGtw/NpghFAuM4P1JDn0DppJldy3PGFC0GfBCZA
SwIDAQAB
-----END PUBLIC KEY-----`
const jwt2 =
'eyJhbGciOiJSUzI1NiJ9.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZSwiaWF0IjoxNjY5MDU2NDg4LCJpc3MiOiJ1cm46ZXhhbXBsZTppc3N1ZXIiLCJhdWQiOiJ1cm46ZXhhbXBsZTphdWRpZW5jZSJ9.gXrPZ3yM_60dMXGE69dusbpzYASNA-XIOwsb5D5xYnSxyj6_D6OR_uR_1vqhUm4AxZxcrH1_-XJAve9HCw8az_QzHcN-nETt-v6stCsYrn6Bv1YOc-mSJRZ8ll57KVqLbCIbjKwerNX5r2_Qg2TwmJzQdRs-AQDhy-s_DlJd8ql6wR4n-kDZpar-pwIvz4fFIN0Fj57SXpAbLrV6Eo4Byzl0xFD8qEYEpBwjrMMfxCZXTlAVhAq6KCoGlDTwWuExps342-0UErEtyIqDnDGcrfNWiUsoo8j-29IpKd-w9-C388u-ChCxoHz--H8WmMSZzx3zTXsZ5lXLZ9IKfanDKg'
async function startRSA() {
var publicKey = await jose.importSPKI(spki, alg)
var {payload, protectedHeader} = await jose.jwtVerify(jwt2, publicKey, {
issuer: 'urn:example:issuer',
audience: 'urn:example:audience',
})
console.log(protectedHeader)
console.log(payload)
}
startRSA()
// additional step
console.log("jose.base64url.decode()", Buffer.from(jose.base64url.decode(token), "base64").toString())
// jwt-simple
const jwt_simple = require('jwt-simple');
// var secret = Buffer.from('fe1a1915a379f3be5394b64d14794932', 'hex')
// decode
const decoded = jwt_simple.decode(token, getSecret() + "fj");
console.log("jwt_simple:", decoded); //=> { foo: 'bar' }

View File

@@ -0,0 +1 @@
Security/CWE-321-HardCodedKey/jwtConstantKey.ql

View File

@@ -0,0 +1,19 @@
// jsonwebtoken
const jwtJsonwebtoken = require('jsonwebtoken');
const {getSecret} = require('./Config.js');
const payloads = {foo: 'bar'}
const token = jwtJsonwebtoken.sign(payloads, getSecret());
// BAD: no verification
jwtJsonwebtoken.decode(token)
// jwt-decode
// BAD: no verification
const jwt_decode = require('jwt-decode');
jwt_decode(token)
// jose
const jose = require('jose')
// BAD: no verification
jose.decodeJwt(token)
// jwt-simple
const jwt_simple = require('jwt-simple');
// no verification
jwt_simple.decode(token, getSecret(), false);

View File

@@ -0,0 +1,38 @@
var Koa = require('koa');
var jwt = require('koa-jwt');
var {getSecret} = require('./Config.js');
var app = new Koa();
// Custom 401 handling if you don't want to expose koa-jwt errors to users
app.use(function (ctx, next) {
return next().catch((err) => {
if (401 === err.status) {
ctx.status = 401;
ctx.body = 'Protected resource, use Authorization header to get access\n';
} else {
throw err;
}
});
});
// Unprotected middleware
app.use(function (ctx, next) {
if (ctx.url.match(/^\/public/)) {
ctx.body = 'unprotected\n';
} else {
return next();
}
});
// Middleware below this line is only reached if JWT token is valid
app.use(jwt({secret: getSecret()}));
// Protected middleware
app.use(function (ctx) {
if (ctx.url.match(/^\/api/)) {
ctx.body = 'protected\n';
}
});
app.listen(3000);

View File

@@ -0,0 +1,26 @@
// pages/api/auth/[...nextauth].js
import NextAuth from "next-auth"
import AppleProvider from "next-auth/providers/apple"
import GoogleProvider from "next-auth/providers/google"
import EmailProvider from "next-auth/providers/email"
var {getSecret} = require('./Config.js');
NextAuth({
secret: getSecret(),
providers: [
AppleProvider({
clientId: process.env.APPLE_ID,
clientSecret: process.env.APPLE_SECRET,
}),
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
}),
// Sign in with passwordless email link
EmailProvider({
server: process.env.MAIL_SERVER,
from: "<no-reply@example.com>",
}),
],
})

View File

@@ -0,0 +1,13 @@
var JwtStrategy = require('passport-jwt').Strategy,
ExtractJwt = require('passport-jwt').ExtractJwt;
var {getSecret} = require('./Config.js');
var opts = {}
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = getSecret();
opts.issuer = 'accounts.examplesoft.com';
opts.audience = 'yoursite.net';
const newPassportUse = new JwtStrategy(opts, function (jwt_payload, done) {
return done(null, false);
})

View File

@@ -0,0 +1,46 @@
const express = require('express')
const app = express()
const jwtJsonwebtoken = require('jsonwebtoken');
const {getSecret} = require('./Config.js');
const jwt_decode = require('jwt-decode');
const jwt_simple = require('jwt-simple');
const jose = require('jose')
const port = 3000
async function startSymmetric(token) {
const {payload, protectedHeader} = await jose.jwtVerify(token, new TextEncoder().encode(getSecret()))
return {
payload, protectedHeader
}
}
app.get('/', (req, res) => {
const UserToken = req.headers.authorization;
// BAD: no verification
jwtJsonwebtoken.decode(UserToken)
jwtJsonwebtoken.verify(UserToken, false, {algorithms: ["HS256", "none"]})
// GOOD: use verify alone or use as a check,
// sometimes it seems some coders use both for same token
const UserToken2 = req.headers.authorization;
jwtJsonwebtoken.decode(UserToken2)
jwtJsonwebtoken.verify(UserToken2, getSecret())
// jwt-decode
// BAD: no verification
jwt_decode(UserToken)
// jose
// BAD: no verification
jose.decodeJwt(UserToken)
// GOOD
startSymmetric(UserToken).then(result => console.log(result))
// jwt-simple
// no verification
jwt_simple.decode(UserToken, getSecret(), true);
// GOOD
jwt_simple.decode(UserToken, getSecret(), false);
jwt_simple.decode(UserToken, getSecret());
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})

View File

@@ -0,0 +1,5 @@
| NoVerification.js:20:28:20:36 | UserToken | This Token is Decoded in without signature validatoin |
| NoVerification.js:25:28:25:37 | UserToken2 | This Token is Decoded in without signature validatoin |
| NoVerification.js:29:16:29:24 | UserToken | This Token is Decoded in without signature validatoin |
| NoVerification.js:32:20:32:28 | UserToken | This Token is Decoded in without signature validatoin |
| NoVerification.js:37:23:37:31 | UserToken | This Token is Decoded in without signature validatoin |

View File

@@ -0,0 +1 @@
Security/CWE-321-noVerification/jwtNoVerification.ql