- ExpressJS - Home
- ExpressJS - Overview
- ExpressJS - Environment
- ExpressJS - Installation
- ExpressJS - Hello World
- ExpressJS - Routing
- ExpressJS - HTTP Methods
- ExpressJS - URL Building
- ExpressJS - Middleware
- ExpressJS - Templating
- ExpressJS - Static Files
- ExpressJS - Form Data
- ExpressJS - Database
- ExpressJS - Cookies
- ExpressJS - Sessions
- ExpressJS - Authentication
- ExpressJS - RESTful APIs
- ExpressJS - Scaffolding
- ExpressJS - Serving Dynamic Content
- ExpressJS - Handling File Uploads
- ExpressJS - Internationalization(i18n)
- ExpressJS - Security Practices
- ExpressJS - Rate Limiting
- ExpressJS - Slowing Down Responses
- ExpressJS - Error handling
- ExpressJS - Debugging
- ExpressJS - Best Practices
- ExpressJS - Resources
ExpressJS - Security Practices
ExpressJS is an unopinionated. ExpressJS framework is highly flexible with a simple, minimalistic design principles. We can quickly setup server, define routes and start handling http requests with very few lines of code. It is very important to secure our server in production. Following are the security best practices for an Express Application one should consider while running application in production.
Use latest stable version of Express
We should never use deprecated or vulnerable versions of express in production. You can follow Official Express Security Updates Page to ensure if any listed vulnerable express version is being used. Express 2.x and 3.x are no longer maintained and there is no new security patch or performance fix is planned for them. You can move to express 4.x or the latest stable version.
User Inputs should be sanitized
All types of user inputs should be validated and handled. Sanitizing user input helps preventing injection attacks.
const express = require('express'); const app = express(); const { body, validationResult } = require('express-validator'); app.post('/login', body('username').isAlphanumeric(), body('email').isEmail(), (req, res) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } // if there is no error, proceed });
Use helmet to secure express apps
Helmet is a security library and can protect app from well known vulnerabilities by setting http-headers appropriately. helmet is a collectio of middleware functions to set security related http response headers.
helmet.contentSecurityPolicy− Sets Content-Security-Policy header to prevent cross-site scripting attacks.
helmet.hsts− Sets Strict-Transport-Security to ensure https based secure connections to the server.
helmet.frameguard− Sets X-Frame-Options to provide Clickjacking protection
Install helmet
npm install --save helmet
Use helmet
const helmet = require('helmet'); const app = require('express')(); app.use(helmet());
Use Secure Dependencies Only
Use npm to analyze the dependency tree and figure out any vulnerable dependency.
npm audit
Use Snyk
Snyk is a better alternative to check vulnerabilities against Snyk's open source vulnerability database.
Install snyk.
npm install -g snyk
test application for vulnerabilities.
synk test
Rate Limiting
Rate limiting limits the number of requests that a user can make within given time frame. This helps to prevent brute force attacks.
Use express-rate-limit middleware.
const rateLimit = require('express-rate-limit'); const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, }); app.use(limiter);
Use HTTPS
HTTPS is a secure connection protocol over http. Http traffic can be intercepted. Use https module to read SSL/TLS certificates to make a secure server.
const https = require('https'); const fs = require('fs'); const app = require('express')(); const options = { key: fs.readFileSync('key.pem'), cert: fs.readFileSync('cert.pem') }; https.createServer(options, app).listen(443);
Use Secure and HTTP Only Cookies
During session management, always set cookies as secure and http-only to prevent client side scripts to access your cookies.
const session = require('express-session'); app.use(session({ secret: 'secret-code', cookie: { secure: true, httpOnly: true, }, // ... }));
Error handling
Always handle error and return user a custom message instead of default error handling. Middleware should manage errors properly and avoid revealing stack trace to the users.
app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Server Error!'); });
Apart from these security practices, you should follow best coding practices as specified by your organization. Ensure code reviews, monitorings, reviews processes are followed properly.