Is the express-mongo-sanitize functionality up and running?

Currently, I am in the process of implementing security middleware for my modest MERN web application. Specifically, I have opted to utilize helmet and express-mongo-sanitize to safeguard against NoSQL injection attacks.

In my server.js file, I have configured it as shown below:

const express = require('express')
const helmet = require('helmet')
const mongoSanitize = require('express-mongo-sanitize')

...

app.use(mongoSanitize())
app.use(helmet())

// Routes below

...

To verify its effectiveness, I attempted a simulated sign-up with the following details:

username: {"$gt": ""} password: 'TestPassword'

This resulted in the following req.body:

{
    username: '{"$gt": ""}',
    password: 'TestPassword'
}

However, despite this input, express-mongo-sanitize did not detect any issues and the data was still passed through to the database. Could it be that I am misunderstanding something? Perhaps the value assigned to the username key is already in the correct format? I acknowledge that I may lack certain knowledge on the subject and appreciate your patience as I continue to learn.

Answer №1

Express-mongo-sanitize acts to sanitize any keys that begin with a dollar symbol.

username: '{"$gt": ""}' --> This example does not demonstrate a key starting with a dollar sign. In fact, the value of username is simply a string.

Consider sending this object instead:

{

"username": { "$gt": "" }

}

Answer №2

Encountered a similar issue and found a solution by first parsing the incoming request body before utilizing the mongoSanitize package. Here's how I did it...

const express = require("express")
const mongoSanitize = require("express-mongo-sanitize')

const app = express()

app.use(express.json())
app.use(mongoSanitize())

Answer №3

In my analysis of the code and debugging process, I discovered that the sanitization function targets keys with symbols like $ or a dot in key=value pairs from query and post parameters. It also aims to sanitize keys found in the body and header of the request.

Even the JSON data shared by the previous user was not exempt from this sanitization process.

For instance, a URL like https://your-domain/?$user=json would have its key sanitized to just "user=json".

Interestingly, it does not remove the $ symbol from parameter values as expected, posing potential security risks for both keys and values. I reached out to the creator on GitHub for clarification and await their response. Ideally, full protection should be applied to both keys and values, especially if only the value is being saved in MongoDB.

To enhance security, the sanitization script scans various HTTP sections such as 'body', 'params', 'headers', and 'query' to eliminate any potentially harmful $ or . characters.

Answer №4

Take a close look at the guidelines

This special tool scans for any keys in objects that start with a $ symbol or have a dot, within req.body, req.query or req.params. It then has the option to either:

  • completely eliminate these keys and related data from the object, or
  • substitute the restricted characters with another permitted character.

It focuses on finding KEYS, not values. For instance

{ username: '{"$gt": ""}', password: 'TestPassword'}

the $ symbol is present in the value of username key, not in the key itself. This is why express-mongo-sanitize does not detect it.

To grasp this better, consider this scenario

// req.body
{ 
    "username": "{'$gt': ''}", 
    "password": "TestPassword",
    "$ne": "1",
    "$gt": "",
}

// the default functionality of express-mongo-sanitize will erase 
// the last two keys and keep the first one.
// Therefore, right after applying the middleware you will see this 
{ 
    username: "{'$gt': ''}", 
    password: "TestPassword",
}

Answer №5

It seems that the solution provided by @A10n is accurate, implying that 'express-mongo-sanitize' may only offer a partial remedy. To further enhance security, I have devised a quick-and-dirty method to eliminate curly brackets from all req.body/params objects in order to mitigate most NoSQL attacks:

// Middleware function that switches {} with [] to prevent NoSQL attacks
    const removeCurlies = (req, res, next) => {
      Object.keys(req.body).forEach((key) => {
        req.body[key] = _.replace(req.body[key], "{", "[");
        req.body[key] = _.replace(req.body[key], "}", "]");
      });
      Object.keys(req.params).forEach((key) => {
        req.params[key] = _.replace(req.params[key], "{", "[");
        req.params[key] = _.replace(req.params[key], "}", "]");
      });
      next();
    };

Add the following code before your routes:

    app.use(removeCurlies);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Customizable text editing tool using Jquery

Recently, I made the decision to implement the jQuery text editor. However, I encountered confusion when trying to access the textarea where I have applied the jqte, as the textarea appeared empty. <!DOCTYPE html> <html> <head> <meta ...

Display a specific template in the detail grid of the Kendo Grid depending on certain conditions

I've been using the Kendo Grid and it's been working well for me. I have a requirement to check each row in my grid to see if it contains a specific value, and based on that, bind data using different templates. Is this feasible? Below is the cod ...

Utilize the Webpack library and libraryTarget settings to establish our own custom library as a global variable

I currently have a library named "xyz" that is being imported as a node module from the npm registry. Now, I want to incorporate it as a library and make it accessible under the global name "abc". To achieve this, I plan to utilize webpack configuration. ...

The ng-repeat function is iterating through the array multiple times

Using ng-repeat to bind the same array multiple times. JavaScript : $scope.currentitem = item; $scope.currentitemCategory = $scope.currentitem.category.split(','); console.log($scope.currentitemCategory); HTML: <div ng-repea ...

Best practices for logging error objects in JavaScript

As a beginner in web development, I've recently come across an interesting observation related to handling errors. When working with json.stringyfy(), I noticed that the message key is not displayed in statement 2. However, accessing error.message ret ...

The module at 'D:Education odemonin odemon.js' could not be located by Node

I am just starting out with NodeJS My setup is on Windows 11 64 Bit system. Node, Nodemon (Global installation), and NPM are all properly installed and operational. However, when I execute the command npm run server It results in the following erro ...

Storing and Manipulating a JavaScript Object with Vuex: A New Perspective

Consider a hypothetical JavaScript object class like this: class Car { var engineTurnedOn = false; ... public turnEngineOn() { engineTurnedOn = true } } If I want to turn the engine on, should I create an action called 'turnEngineOn&ap ...

Root location for offline and pre-production in the Backbone boilerplate router

I am currently utilizing the backbone boilerplate found at https://github.com/tbranyen/backbone-boilerplate My development process involves working on static HTML/JS files offline and conducting tests offline before deploying them to another site for pre- ...

Tips for sending a file array together with other string/int variables from JavaScript to PHP

I am looking to pass the imageArray[] along with a variable trackNo. Passing the imageArray[] is not an issue, but I am unsure of how to include other variables with the FormData(). When researching online, I only came across examples of people passing a ...

What is the best way to eliminate the nesting in this ternary operation?

Object.values(filter).filter(item => (Array.isArray(item) && item.length > 0) || (typeof item === "boolean" && item === true) || (item !== null)).length ? filterIcon : unFilledIcon In this code, I aim to simplify the nested ternary operator and ...

Automatically reset the form after submission in CakePHP 1.3

I've encountered an issue with my report form that is linked multiple times on a page to a jQuery dialog box. To prevent cross-posting, I added a random string to the submission process. After successfully submitting the form on a single page access, ...

What impact does turning off Javascript have on ASP.NET?

There seems to be varying accounts of the impact of turning off JavaScript on ASP.NET applications. Some say it works fine, others claim only certain parts are affected, while some suggest that nothing functions at all. I am curious to know specifically h ...

HTML form with a dropdown menu

Imagine you have a HTML form containing two dropdown lists. The first dropdown is labeled "country" and contains a list of countries. The second dropdown, labeled "cities," should be dynamically populated based on the country selected. What is the best ...

What is the best way to create a selection input using buttons and save the chosen option in the state?

Check out this snippet showcasing 3 buttons const [role, setRole] = React.useState('') const [active, setActive] = React.useState(false) <Grid container spacing={1}> <Grid item xs={4}> <Button variant='plain&apos ...

JavaScript file creation and opening issue in Firefox

Check out my code snippet below: var blob = new Blob([data], { type: 'text/plain' }); var downloadLink = angular.element('<a></a>'); downloadLink.attr('href', window.URL.createObjectURL(blob)); downloadLink.attr ...

Crop the contents of an array between two specified characters

Looking to extract individual values from an array like this: "Names": [ "Name[name]", "Result[Type]", "Validation[Option]", "Status[Pointer]" ] The desired output should be: "Names": [ "name", "Type", "Option", ...

What is the best way to include attributes in an HTML element?

I've been researching how to dynamically add attributes to an HTML tag using jQuery. Consider the following initial HTML code: <input type="text" name="j_username" id="j_username" autocorrect="off" autocapitalize="off" style="background-image: lin ...

Error: Unable to locate module - The specified file cannot be resolved when utilizing an external JavaScript library

I am currently integrating a WYSIWYG editor (TUI Editor) into my Angular2+ application. Since there is no official Angular wrapper available, I have decided to create my own based on an existing wrapper. Due to some installation issues with npm, I saved t ...

The border color of the text input is not changing as expected when in focus

Is there a way to change the border color of a text input field to blue when it is not selected and then change it to orange when the field is selected? input[type="text"]{ border: 1px solid blue; } input[type="text"]:focus{ border: 1px solid ora ...

Position the vertical bar directly adjacent to the form input field

Looking for assistance with creating a unique webpage layout that includes a form where the employee ID is visually separated from the rest of the content by a vertical bar extending across the entire page. However, my attempts to achieve this using a gr ...