Software Integrity

 

ExpressJS: Preventing common vulnerabilities in the MEAN stack (Part 1)

ExpressJS: Preventing common vulnerabilities in the MEAN stack

Before jumping into the Express framework, get up to speed with Part 1 of this series which explores MongoDB.

Stack precedence (ExpressJS)

The Express framework allows developers to easily add multiple middleware plugins globally to all routes via app.use(). However, middleware order is important because it will only be applied to routes defined further down the stack. Consider the code block below where the isLoggedIn authentication middleware is applied after the /secure/removeInvoice route. The authentication check will be applied to requests for /secure/addInvoice but not /secure/removeInvoice.

An unauthenticated attacker can submit requests directly to the /secure/removeInvoice API and delete invoices.

An unauthenticated attacker can submit requests directly to the /secure/removeInvoice API and delete invoices.

Request submitted directly to unauthenticated API

Request submitted directly to unauthenticated API

Request submitted directly to unauthenticated API

Request submitted directly to unauthenticated API

When applying middleware globally (rather than inline, per route) developers should make all app.use calls at the beginning of the file, before defining routes that must be restricted by the applied middleware.

Case-insensitive routing (ExpressJS)

The Express server framework allows developers to easily define routes for serving static pages or RESTful APIs; however, these routes are case-insensitive by default. This becomes problematic when applying middleware security controls to routes based on regular expression matching. For example, our MEAN Bug application uses the isLoggedIn middleware function to verify that a user is authenticated. This middleware is dynamically applied to all routes that begin with the case-sensitive string /secure via the express-unless plugin.

ExpressJS: Preventing common vulnerabilities in the MEAN stack

Because Express routes are not case-sensitive, a request for /SECURE/manageInvoices will return the same resource as /secure/manageInvoices. However, the authentication-checking middleware will not be applied to /SECURE/manageInvoices, allowing an attacker to access the page without logging in.

User redirected to login page if unauthenticated

User redirected to login page if unauthenticated

Authentication middleware bypassed with /SECURE/manageInvoices

Authentication middleware bypassed with /SECURE/manageInvoices

Authentication middleware bypassed

Authentication middleware bypassed

The isLoggedIn authentication middleware should be applied to each /secure route based on a case-insensitive regular expression denoted by the ‘i’ option after the trailing forward slash.

ExpressJS: Preventing common vulnerabilities in the MEAN stack

Alternatively, the Express application can be configured to use case-sensitive routes by setting the case sensitive routing option to true.

ExpressJS: Preventing common vulnerabilities in the MEAN stack

The screenshot below demonstrates the second solution where the server is configured to use case-sensitive routing. The request for /SECURE/manageInvoices is no longer valid.

Case-sensitive routing enforced

Case-sensitive routing enforced

Stay tuned for Part 3 of this series, exploring Express Sessions and CSRF, which will drop on the Software Security blog on May 4th.