Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
express-token-api-middleware
Advanced tools
An express middleware that allows to protect an api behind token authentication, rate limiting and endpoint permissions.
An express middleware that allows to protect an api behind token authentication, rate limiting and endpoint permissions.
This is a middleware for express that will hopefully make your life easier if you want to make your api available to 3rd party developer by using token to authenticate. The philosophy behind this middleware is to be completely database independent and rely on token to retrieve information about the user such as access rights and rate limitations.
Tokens are encrypted using AES256 with GCM and can be given out to users without them having access to the data within. Tokens can also be used to store additional metadata, note though that token will increase in size if you do.
First let's initialize the middleware
var express = require('express');
var tokens = require('express-token-api-middleware');
var app = express();
var mw = tokens({
password: 'my super secret password',
salt: 'something that will be at least 16 bytes long (preferably a Buffer)'
});
app.use(mw);
app.get('/', (req, res) => {
console.log(req.user); // => { id: 'My own user id' }
res.end();
}):
We've now set up the token authentication for all requests. Sending requests to the server will all be blocked with a 401 status (No auth provided). Now we need a token to authenticate our requests:
var token = mw.getToken({ id: 'My own user id' })
This token will hold additional data such as a rate limit or access rights (more on that in the API section). Now we need to use the token to authenticate our server (we make use of the supertest request helper, but the code should be self explanatory):
request(app).get('/').set('Authorization', token).end();
// => Status 200 "OK"
And that's all. Now let's dive into the API for more details:
There are a few options that you can set to change the behavior of the middleware:
var mw = tokens({
param: 'token',
nodes: 1,
password: <needs to be set>,
salt: <needs to be set>,
logger: null,
timeout: undefined
})
A look at the individual options:
crypto.randomBytes(16)
.error(req, res, next, status, message)
.Note that password and salt are used to create a single key tha will encrypt all tokens. This tool does not use a key per user as this would require much more memory or a database tie in. In most cases this should be safe enough, but if you require higher security a different solution is probably better suited.
To authenticate your users you need to give them the tokens they can authenticate with. This where this method comes in. There are a few standard properties that are used by the middleware, but you can add any additional properties which will be stored in the token alongside the user configuration.
var token = mw.getToken({
id: 'user id',
path: '/path',
rate: 100,
exp: Date.now() + 86400000
custom: 'whatever'
});
Again a few options that need explaining:
Rate limitation works in such a way that incoming requests will have a minimum interval of the given value. If 2 requests come in faster than that, the second request will be delayed until the desired rate has been reached. The rate format supports multiple units: ns, ms, s, m, h, d, w. Note though that if you use ns (= nano seconds) the minimum wait time between 2 requests is 1 ms).
Now if you're running this server in any serious environment you'll probably have a cluster with more than 1 node running. Since there's no communication between the middleware on the nodes built in, there's 2 ways you can still get a global rate emulated:
Nodes configuration
The simplest method is to specify how many nodes are in the cluster. The middleware will use that number to multiply the wait factors for allowed rates. There are two ways how you can set the current number of nodes:
The nodes setter on the middleware allows you to change the number of nodes that are active even after the middleware has been initialized.
mw.nodes = 10;
Notify requests
The second method to use for cluster support is to notify the middleware of requests on other nodes. Unfortunately you will have to take care of setting up the infrastructure for communicating such information between nodes. You'll also have to specify a user object with rate limit to make use of this feature.
mw.notify({
id: 'user on other node',
rate: 100
}
You can specify the number of requests the user has made on other nodes and thereby make any requests to this instance wait even more. How well this approach will work with your setup depends on how good the communication is set up between nodes.
In any case I would recommend to only use this if you know what you're doing and otherwise stick to the nodes configuration method.
The middleware also emits events in case you want to react to some of the possible error events. All events have the same signature and can be used as such:
mw.on('missing', req => console.log('Missing auth token from request', req));
Triggered whenever the middleware rejects a request because no token has been found. The request object does not include the user object as there is nothing to decrypt.
Triggered whenever the middleware was unable to decrypt a token. The request object does not include the user object as we were unable to decrypt it.
Triggered whenever a user is rejected access to a specific path. The request object includes the decrypted user object.
Triggered whenever a user token has expired. The request object includes the decrypted user object.
The timeout event is triggered whenever the request queue is full and request get rejected. The request object includes the decrypted user object.
Triggered when a request has successfully been queued up and has already been processed or will be processed once the rate limit queue has caught up.
For more examples and to check out the tests you can look at middleware.test.js in the test directory.
Some ideas to maybe work on in the future:
FAQs
An express middleware that allows to protect an api behind token authentication, rate limiting and endpoint permissions.
The npm package express-token-api-middleware receives a total of 7 weekly downloads. As such, express-token-api-middleware popularity was classified as not popular.
We found that express-token-api-middleware demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.