Skip to content

Commit 6a9186c

Browse files
author
Stephan Brandauer
committed
update ATM NosqlInjection and SqlInjection query docs
1 parent 5ee9612 commit 6a9186c

File tree

2 files changed

+43
-35
lines changed

2 files changed

+43
-35
lines changed
Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,62 @@
11
# NoSQL database query built from user-controlled sources (experimental)
2-
If a database query (such as a SQL or NoSQL query) is built from user-provided data without sufficient sanitization, a malicious user may be able to run malicious database queries.
2+
If a database query is built from user-provided data without sufficient sanitization, a user may be able to run malicious database queries.
33

44
Note: This CodeQL query is an experimental query. Experimental queries generate alerts using machine learning. They might include more false positives but they will improve over time.
55

66

77
## Recommendation
8-
Most database connector libraries offer a way of safely embedding untrusted data into a query by means of query parameters or prepared statements.
9-
10-
For NoSQL queries, make use of an operator like MongoDB's `$eq` to ensure that untrusted data is interpreted as a literal value and not as a query object.
11-
8+
Ensure that untrusted data is interpreted as a literal value and not as a query object, eg., by using an operator like MongoDB's `$eq`.
129

1310
## Example
14-
In the following example, assume the function `handler` is an HTTP request handler in a web application, whose parameter `req` contains the request object.
11+
In the following example, an `express.js` application is defining two endpoints that permit a user to query a MongoDB database.
1512

16-
The handler constructs two copies of the same SQL query involving user input taken from the request object, once unsafely using string concatenation, and once safely using query parameters.
13+
In each case, the handler constructs two copies of the same query involving user input taken from the request object. In both handlers, the input is parsed using the `body-parser` library, which will transform the request data that arrives as a string to JSON objects.
1714

18-
In the first case, the query string `query1` is built by directly concatenating a user-supplied request parameter with some string literals. The parameter may include quote characters, so this code is vulnerable to a SQL injection attack.
15+
In the first case, `/search1`, the input is used as a query object. This means that a malicious user is able to inject queries that select more data than the developer intended.
1916

20-
In the second case, the parameter is embedded into the query string `query2` using query parameters. In this example, we use the API offered by the `pg` Postgres database connector library, but other libraries offer similar features. This version is immune to injection attacks.
17+
In the second case, `/search2`, parts of the input are converted to a string representation and then used with the `$eq` operator to construct a query object.
2118

2219

2320
```javascript
2421
const app = require("express")(),
25-
pg = require("pg"),
26-
pool = new pg.Pool(config);
27-
28-
app.get("search", function handler(req, res) {
29-
// BAD: the category might have SQL special characters in it
30-
var query1 =
31-
"SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" +
32-
req.params.category +
33-
"' ORDER BY PRICE";
34-
pool.query(query1, [], function(err, results) {
35-
// process results
36-
});
37-
38-
// GOOD: use parameters
39-
var query2 =
40-
"SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=$1" + " ORDER BY PRICE";
41-
pool.query(query2, [req.params.category], function(err, results) {
42-
// process results
43-
});
22+
mongodb = require("mongodb"),
23+
bodyParser = require('body-parser');
24+
25+
const client = new MongoClient('mongodb://localhost:27017/test');
26+
27+
app.use(bodyParser.urlencoded({ extended: true }));
28+
29+
app.get("/search1", async function handler(req, res) {
30+
await client.connect();
31+
const db = client.db('test');
32+
const doc = db.collection('doc');
33+
34+
const result = doc.find({
35+
// BAD:
36+
// This is vulnerable.
37+
// Eg., req.body.title might be the object { $ne: "foobarbaz" }, and the
38+
// endpoint would return all data.
39+
title: req.body.title
40+
});
41+
42+
res.send(await result);
4443
});
4544

45+
app.get("/search2", async function handler(req, res) {
46+
await client.connect();
47+
const db = client.db('test');
48+
const doc = db.collection('doc');
49+
50+
// GOOD:
51+
// The input is converted to a string, and matched using the $eq operator.
52+
// At most one datum is returned.
53+
const result = await doc.find({ title: { $eq: `${req.body.title}` } });
54+
55+
res.send(await result);
56+
});
4657
```
4758

4859
## References
49-
* Wikipedia: [SQL injection](https://en.wikipedia.org/wiki/SQL_injection).
60+
* Acunetix Blog: [NoSQL Injections and How to Avoid Them](https://www.acunetix.com/blog/web-security-zone/nosql-injections/).
5061
* MongoDB: [$eq operator](https://docs.mongodb.com/manual/reference/operator/query/eq).
62+
* MongoDB: [$ne operator](https://docs.mongodb.com/manual/reference/operator/query/ne).

javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
# SQL database query built from user-controlled sources (experimental)
2-
If a database query (such as a SQL or NoSQL query) is built from user-provided data without sufficient sanitization, a malicious user may be able to run malicious database queries.
2+
If a SQL query is built from user-provided data without sufficient sanitization, a malicious user may be able to run malicious database queries.
33

44
Note: This CodeQL query is an experimental query. Experimental queries generate alerts using machine learning. They might include more false positives but they will improve over time.
55

66

77
## Recommendation
88
Most database connector libraries offer a way of safely embedding untrusted data into a query by means of query parameters or prepared statements.
99

10-
For NoSQL queries, make use of an operator like MongoDB's `$eq` to ensure that untrusted data is interpreted as a literal value and not as a query object.
11-
12-
1310
## Example
14-
In the following example, assume the function `handler` is an HTTP request handler in a web application, whose parameter `req` contains the request object.
11+
In the following example, an `express.js` application is defining two endpoints that permit a user to query a postgres database.
1512

1613
The handler constructs two copies of the same SQL query involving user input taken from the request object, once unsafely using string concatenation, and once safely using query parameters.
1714

@@ -47,4 +44,3 @@ app.get("search", function handler(req, res) {
4744

4845
## References
4946
* Wikipedia: [SQL injection](https://en.wikipedia.org/wiki/SQL_injection).
50-
* MongoDB: [$eq operator](https://docs.mongodb.com/manual/reference/operator/query/eq).

0 commit comments

Comments
 (0)