Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Keep It Simple, Stupid, Secure and Fast JWT module
Most of the time people use node-jsonwebtoken and express-jwt without using a cache mechanism to verify tokens. This requires a lot of CPU on the server side for each request! On client-side, the token is generated once with an infinite expiration timestamp, which is not very secure. The first purpose of this module is to solve these two problems.
When you discover JWT, you do not know which signing algorithm to choose and where to put your data (issuer, audience, ...). This module solves this problem for you. It selects a highly secure algorithm by default. If you want another algorithm, fork it. The algorithm used (asymmetric) allows the client to generate himself a token without having to exchange a secret with the server. Only the public key is exchanged.
To save extra bandwidth, it allows you to define only two parameters: a client ID ("Alice", issuer) and a server ID ("Bob", recipient). The generated token allows only Alice (clientId) to speak exclusively to Bob (serverId).
Main purpose : to be plug'n'play for developers who do not have much of time.
npm install kitten-jwt --save
Using request
module for example:
const jwt = require('kitten-jwt');
// Generate an ephemeral jwt token (short expiration date), auto-renewed every 12-hour by default
// This function is very fast (uses cache), it can be called for every HTTP request
const token = jwt.getToken(options, data);
// Insert the token in HTTP Header, it will be parsed by jwt.verifyHTTPHeaderFn automatically
request.setHeader('Authorization', 'Bearer ' + token); // "Bearer" keyword is optional
Or, if your client is a browser, store the JWT in a cookie
instead of Authorization
header.
With ExpressJS
:
// let the browser send it back automatically.
// Do not forget to refresh it before the 12-hour expiration
response.cookie('access_token', token);
const jwt = require('kitten-jwt');
// custom method to get the client public key, kitten-jwt caches the result automatically
function getPublicKeyFn(req, res, payload, callback) {
const _clientId = payload.iss;
// do whatever you want: db query, file read to return the public key
// it accepts an array of public key ['pubKeyOfTheClient1', 'pubKeyOfTheClient2']
return callback(null /* error object*/, 'pubKeyOfTheClient');
}
// use the helper function to verify token in an express middleware
// This function is very fast (uses lru-cache)
// It searches JWT in req.header.authorization, then in req.header.cookie.<access_token>
express().use(jwt.verifyHTTPHeaderFn('server-app-name', getPublicKeyFn));
// if the public key changes
jwt.resetCache();
// In other middleware, you can print JWT payload object, added by verifyHTTPHeaderFn
console.log(req.jwtPayload);
Token generated by kitten-jwt are quite compact (limited) for performance reasons, and follows JWT RFC
{
alg : algorithm name (defaults to 'ES512'),
typ : token type (defaults to 'JWT' )
}
Note: The 'none' algorithm allows unsigned JWTs. While the JWT specification allows this algorithm (see RFC 7519), it introduces security risks and should be used with caution.
{
iss : clientId, // issuer
aud : serverId, // audience, tenand id, etc...
exp : (Date.now() + expiresIn) // expiration timestamp UTC
}
Why it is important to have a serverId? If the audience is not defined, the same token can be used for another web-service which have the same clientId and public key.
These functions uses cache to be as fast as possible
jwt.getToken (options, data)
Generate a token for the tuple clientId-serverId, which expires in about 12 hours (+- random)
Re-use this same token during about 12 hours if called more than twice
Generate a new token automatically before expiration (20-minute before) or if privKey change
options : {
header : {
alg : algorithm name (defaults to 'ES512'),
typ : token type (defaults to 'JWT' ),
kid : key id
},
payload : {
clientId : JWT issuer, `token.iss`
serverId : JWT audience, `token.aud`
},
privKey : private key
},
data : accessible in token.data
Generate a middleware function(req, req, next)
Verify and set req.jwtPayload
callback(err, String|Array)
where
the second parameter is either a string (one public key) or an array of strings (multiple public key to test)jwt.resetCache (clientId, callback)
: invalidate cacheThese APIs should not be used directly in a web app because nothing is cached (slow).
jwt.generate (options, data)
: generate a token
options : {
header : {
alg : algorithm name (defaults to 'ES512'),
typ : token type (defaults to 'JWT' ),
kid : key id
},
payload : {
clientId : JWT issuer `token.iss`,
serverId : JWT audience `token.aud`,
expiresIn : JWT duration in number of seconds `token.exp`
},
privKey : private key
},
data : accessible in token.data
It returns a signed base64 url encoded string of the token.
jwt.verify (jwt, pubKey, callback, now = Date.now())
: verify the signature of a token
jwt.generateECDHKeys (outputDir, outputKeyName, callback)
: generate pub / priv ECDSA keys
jwt.set (options)
: set default options:
{
// client cache size used by getToken
clientCacheSize : 255,
// how many time before client token expiration kitten-cache renews tokens in millisecond
clientRenewTokenBeforeExp : 60 * 20 * 1000,
// default client tokens expiration in seconds
clientTokenExpiration : 60 * 60 * 12,
// server cache size used by verifyHTTPHeaderFn
serverCacheSize : 255,
// Invalidate bad token cache after XX milliseconds when the error is coming from getPublicKey
serverGetPublicKeyErrorCacheExpiration : 120 * 1000
}
3.2.0
3.1.0
parseToken
3.0.1
generate
must be called with two arguments: generate(options, data)
getToken
must be called with two arguments: getToken(options, data)
2.0.0
getPublicKeyFn(req, res, payload, callback)
must call the callback with two arguments: callback(err, publicKeys)
serverGetPublicKeyErrorCacheExpiration
to invalidate bad token cache after 120 seconds (by default) when the error comes from the getPublicKeyFn
function.
Before this new feature, if the public key was not available (temporary network / disk / database issue for example), the token was stored in the quarantine area forever.1.1.1
verify
returns payload even if the token is expired1.1.0
set(options)
verify
function1.0.0
getPublicKeyFn
can return an array of public keysaccess_token
TODO :
FAQs
Keep It Simple, Stupid, Secure and Fast JWT module
We found that kitten-jwt demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.