mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
remove hardcoded JWT secret-key query
This commit is contained in:
@@ -1,49 +0,0 @@
|
||||
const express = require('express')
|
||||
const jwtJsonwebtoken = require("jsonwebtoken");
|
||||
const jose = require("jose");
|
||||
const jwt_simple = require("jwt-simple");
|
||||
const app = express()
|
||||
const port = 3000
|
||||
|
||||
function getSecret() {
|
||||
return "secret"
|
||||
}
|
||||
|
||||
async function startSymmetric(token) {
|
||||
const {payload, protectedHeader} = await jose.jwtVerify(token, new TextEncoder().encode(getSecret()))
|
||||
return {
|
||||
payload, protectedHeader
|
||||
}
|
||||
}
|
||||
|
||||
async function startRSA(token) {
|
||||
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 publicKey = await jose.importSPKI(spki, 'RS256')
|
||||
const {payload, protectedHeader} = await jose.jwtVerify(token, publicKey, {
|
||||
issuer: 'urn:example:issuer',
|
||||
audience: 'urn:example:audience',
|
||||
})
|
||||
console.log(protectedHeader)
|
||||
console.log(payload)
|
||||
}
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
const UserToken = req.headers.authorization;
|
||||
startSymmetric(UserToken).then()
|
||||
startRSA(UserToken).then()
|
||||
jwt_simple.decode(UserToken, getSecret());
|
||||
jwtJsonwebtoken.verify(UserToken, getSecret())
|
||||
res.send('Hello World!')
|
||||
})
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Example app listening on port ${port}`)
|
||||
})
|
||||
@@ -1,29 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
A JSON Web Token (JWT) is used for authenticating and managing users in an application.
|
||||
</p>
|
||||
<p>
|
||||
Decoding JWTs with a Constant hardcoded secret key can lead to security vulnerabilities.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Generate seceret key in application startup with secure randome generators.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following code you can see an Example from a popular Library.
|
||||
</p>
|
||||
|
||||
<sample src="Example.js" />
|
||||
|
||||
</example>
|
||||
|
||||
</qhelp>
|
||||
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* @name Usage of Constant Secret key for decoding JWT
|
||||
* @description Hardcoded Secrets leakage can lead to authentication or authorization bypass
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id javascript/jwt-hardcoded-key
|
||||
* @tags security
|
||||
* experimental
|
||||
* external/cwe/CWE-321
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import DataFlow::PathGraph
|
||||
import DataFlow
|
||||
|
||||
class JWTDecodeConfig extends TaintTracking::Configuration {
|
||||
JWTDecodeConfig() { this = "JWTConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr() instanceof ConstantString and
|
||||
// following prevent custom secret key generators that exist in source code
|
||||
not source.asExpr().mayHaveStringValue(["", " ", any(string s | s.length() = 1)])
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
node.getFile()
|
||||
.getLocation()
|
||||
.hasLocationInfo(any(string s | s.matches(["%test%", "%demo%", "%example%", "%sample%"])),
|
||||
_, _, _, _)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
sink = API::moduleImport("jsonwebtoken").getMember(["sign", "verify"]).getParameter(1).asSink() or
|
||||
sink = API::moduleImport("jose").getMember("jwtVerify").getParameter(1).asSink() or
|
||||
sink = API::moduleImport("jwt-simple").getMember("decode").getParameter(1).asSink() or
|
||||
sink = API::moduleImport("next-auth").getParameter(0).getMember("secret").asSink() or
|
||||
sink = API::moduleImport("koa-jwt").getParameter(0).getMember("secret").asSink() or
|
||||
sink =
|
||||
API::moduleImport("express-jwt")
|
||||
.getMember("expressjwt")
|
||||
.getParameter(0)
|
||||
.getMember("secret")
|
||||
.asSink() or
|
||||
sink =
|
||||
API::moduleImport("passport-jwt")
|
||||
.getMember("Strategy")
|
||||
.getParameter(0)
|
||||
.getMember("secretOrKey")
|
||||
.asSink()
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(DataFlow::CallNode n, DataFlow::NewNode nn |
|
||||
n.getCalleeName() = "encode" and
|
||||
nn.flowsTo(n.getReceiver()) and
|
||||
nn.getCalleeName() = "TextEncoder"
|
||||
|
|
||||
pred = n.getArgument(0) and
|
||||
succ = n
|
||||
)
|
||||
or
|
||||
exists(API::Node n | n = API::moduleImport("jose").getMember("importSPKI") |
|
||||
pred = n.getACall().getArgument(0) and
|
||||
succ = n.getReturn().getPromised().asSource()
|
||||
)
|
||||
or
|
||||
exists(API::Node n | n = API::moduleImport("jose").getMember("base64url").getMember("decode") |
|
||||
pred = n.getACall().getArgument(0) and
|
||||
succ = n.getACall()
|
||||
)
|
||||
or
|
||||
exists(DataFlow::CallNode n | n = DataFlow::globalVarRef("Buffer").getAMemberCall("from") |
|
||||
pred = n.getArgument(0) and
|
||||
succ = [n, n.getAChainedMethodCall(["toString", "toJSON"])]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from JWTDecodeConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "this $@. is used as a secret key", source.getNode(),
|
||||
"Constant"
|
||||
@@ -1,6 +0,0 @@
|
||||
function getSecret() {
|
||||
return "secret"
|
||||
}
|
||||
|
||||
const DoValidate = false
|
||||
module.exports = {getSecret, DoValidate}
|
||||
@@ -1,14 +0,0 @@
|
||||
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"],
|
||||
});
|
||||
@@ -1,109 +0,0 @@
|
||||
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 |
|
||||
@@ -1,52 +0,0 @@
|
||||
// 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' }
|
||||
@@ -1 +0,0 @@
|
||||
Security/CWE-321-HardCodedKey/jwtConstantKey.ql
|
||||
@@ -1,19 +0,0 @@
|
||||
// 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);
|
||||
@@ -1,38 +0,0 @@
|
||||
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);
|
||||
@@ -1,26 +0,0 @@
|
||||
// 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>",
|
||||
}),
|
||||
],
|
||||
})
|
||||
@@ -1,13 +0,0 @@
|
||||
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);
|
||||
|
||||
})
|
||||
Reference in New Issue
Block a user