What is an Injection?
Injection vulnerabilities happen anytime untrusted data is used within a system. Commonly this occurs when a user passes some information to a system and the system starts to interpret the input without validation or sanitization.
Examples of Injections
SQL Injection
This example uses a common web application login for to find a user in the database through string concatenation.
Another example using a search bar to find relevant items using a fuzzy SQL “LIKE” search
1 | http://myapplication.com/products?id=1'; DROP DATABASE users -- |
NoSQL Injection
Example Code - Bad1
2
3
4db.collection('users').find({
"user": req.query.user,
"password": req.query.password
});
Let’s look at an example payload and see how this query is vulnerable to injection:
1 | { |
By passing in $ne, not equal, we are asking the NoSQL database to find a user where the user and password are not equal to null, should be any user in the database. There are several sanitizing libraries available. For our example we’re using Mongoose to define our schema and communicate with out MongoDB database so we’ll use the Mongo Sanitize library to first sanitize any user input before passing the query to our database.
Example Code - Good
1 | // Mongoose to define schema |
Cookie Injection
Browser based cookies are another input that the user (or machine) has access to. This is another common area for injection vulnerabilities.
Avoid:
- Easily guessable cookie names (keys) or values
- Values that can be iterated user01, user02, user03…
- Boolean values that you rely on for things like authorization, e.g. { admin: true }
OS Command Injection
Problem:
Solution:
1) Ask “Do we need this functionality at all?!?”
2) Create a simple command lookup key, that ensures user is authorized to perform action
This is an example NodeJS/ ExpressJS API endpoint that allows an authorized user to request the execution of an operating system command from an approved list of commands.
1 | const exec = require('child_process').exec; |
Prevention
Query Parameterization
Never trust unvalidated or un-sanitized data!!! Most database libraries we use to communicate with our databases provide something called “query parameterization”. This allows us to construct a database query and the library with handle escaping and sanitizing input before the query is run by the database engine. This is where it’s far better to use a trusted library than trying to sanitize input on our own.