javascript.aws-lambda.security.mysql-sqli.mysql-sqli

Author
unknown
Download Count*
License
Detected SQL statement that is tainted by $EVENT
object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: connection.query('SELECT $1 from table', [userinput])
Run Locally
Run in CI
Defintion
rules:
- id: mysql-sqli
message: "Detected SQL statement that is tainted by `$EVENT` object. This could
lead to SQL injection if the variable is user-controlled and not properly
sanitized. In order to prevent SQL injection, use parameterized queries or
prepared statements instead. You can use parameterized statements like so:
`connection.query('SELECT $1 from table', [userinput])`"
metadata:
references:
- https://www.npmjs.com/package/mysql2
category: security
owasp:
- A01:2017 - Injection
- A03:2021 - Injection
cwe:
- "CWE-89: Improper Neutralization of Special Elements used in an SQL
Command ('SQL Injection')"
technology:
- aws-lambda
- mysql
- mysql2
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: MEDIUM
impact: HIGH
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
languages:
- javascript
- typescript
severity: WARNING
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern-inside: |
exports.handler = function ($EVENT, ...) {
...
}
- pattern-inside: |
function $FUNC ($EVENT, ...) {...}
...
exports.handler = $FUNC
- pattern-inside: |
$FUNC = function ($EVENT, ...) {...}
...
exports.handler = $FUNC
- pattern: $EVENT
pattern-sinks:
- patterns:
- focus-metavariable: $QUERY
- pattern-either:
- pattern: $POOL.query($QUERY, ...)
- pattern: $POOL.execute($QUERY, ...)
- pattern-either:
- pattern-inside: |
require('mysql')
...
- pattern-inside: |
require('mysql2')
...
- pattern-inside: |
require('mysql2/promise')
...
- pattern-inside: |
import 'mysql'
...
- pattern-inside: |
import 'mysql2'
...
- pattern-inside: |
import 'mysql2/promise'
...
Examples
mysql-sqli.js
var AWS = require('aws-sdk');
const mysql = require('mysql2');
exports.handler = async (event, context) => {
console.log(event);
var secretsManager = new AWS.SecretsManager();
var secretId = event.arguments[0][2];
const secret = await secretsManager.getSecretValue({
SecretId: secretId
}).promise();
var secretJson = JSON.parse(secret.SecretString);
var host = secretJson.host;
var user = secretJson.username;
var password = secretJson.password;
let connectionConfig = {
host: host,
user: user,
password: password,
connectTimeout: 60000
};
var pool = await mysql.createPool(connectionConfig);
var conn = pool.promise();
var table = event.arguments[0][0];
var columnName = event.arguments[0][1];
var createStmt = 'create temporary table ' + table + '_jointemp (temp_seq int, '+ columnName + ' varchar(100)); ';
// ruleid: mysql-sqli
await conn.query(createStmt);
var values = event.arguments.map((x, i) => "("+i+",'"+x[3]+"')");
var insertStmt = 'insert into ' + table + '_jointemp(temp_seq, '+ columnName +') values ' + values.join(',') + ';';
// ruleid: mysql-sqli
await conn.query({sql: insertStmt, rowsAsArray: true});
var selectStmt = 'select t2.* FROM ' + table + '_jointemp t1 LEFT OUTER JOIN ' + table + ' t2 using ('+ columnName +') order by temp_seq;'
// ruleid: mysql-sqli
const [results, fields] = await conn.execute(selectStmt);
// ok: mysql-sqli
const [results2, fields2] = await conn.execute('SELECT * FROM foobar WHERE id = ?', [columnName]);
var res = {};
if(results.length > 0){
res = results.map((row) => JSON.stringify(row));
}
var response = JSON.stringify({"results": res});
conn.end();
return response;
};
Short Link: https://sg.run/A502