
ASP.NET Core 5 Secure Coding Cookbook
By :

NoSQL databases are a different type of database in which non-relational and semi-structured data is stored. There are many kinds of NoSQL databases to name, such as Cassandra, Redis, DynamoDB, and MongoDB, each with its own query language. Although distinct from one another, these queries are also prone to injection attacks.
In this recipe, we will identify the NoSQL injection vulnerability in code that is using MongoDB as the backend and fix the problem by applying several countermeasures.
Using Visual Studio Code, open the sample Online Banking app folder at Chapter02\nosql-injection\before\OnlineBankingApp
.
Let's take a look at the steps for this recipe:
code .
dotnet build
Services/PayeeService.cs
file and locate the vulnerable part of the code in the Get(string name)
method:public List<Payee> Get(string name) { var filter = "{$where: \"function() {return this.Name == '" + name + "'}\"}"; return payees.Find(filter).ToList(); }
public List<Payee> Get(string name) { return payees.Find(payee => payee.Name == name).ToList(); }
The filter passed into the Find
method is now replaced with a Lambda expression, a much more secure way of searching for a payee by name.
The Get
method has a string parameter that can be supplied with a non-sanitized or validated value. This value can alter the MongoDB filter composed with it, making the NoSQL database perform an unintended behavior.
The name
parameter can be appended with an expression that would evaluate the query into a logical result different from what the query was expected to perform. A JavaScript clause can also be inserted into a query that can terminate the statement and add a new block of arbitrary code.
By way of some general advice, avoid using the $where
operator. Simply apply a C# Lambda expression as a filter to prevent any injectable JSON or JavaScript expression.
Suppose the preceding options are not possible and it is necessary to use the $where
clause, you must then JavaScript-encode the input. Use the JavaScriptEncoder
class from the System.Text.Encodings.Web
namespace to encode the value being passed into the parameter:
PayeeService.cs
file to add a reference to the Encoder
namespace:using System.Text.Encodings.Web;
JavaScriptEncoder
:private readonly JavaScriptEncoder _jsEncoder;
PayeeService
constructor and add a new parameter to inject JavaScriptEncoder
:public PayeeService(IOnlineBankDatabaseSettings settings,JavaScriptEncoder jsEncoder)
name
parameter using the Encode
function of JavaScriptEncoder
:var filter = "{$where: \"function() {return this.Name == '" + _jsEncoder.Encode(name) + "'}\"}";
If a malicious input was passed into the name
parameter and was escaped by the Encode
method, the C# MongoDB driver will throw an exception if the escaped value could not be interpreted as a valid JavaScript expression.
To prevent NoSQL injections, developers must avoid building dynamic queries using string concatenation. NoSQL databases offer ways to query and process data, but you must be aware of potential security implications a feature might bring into the ASP.NET Core web application.