From 91f89ad3af13536a55229b604eb7b11aea33ed53 Mon Sep 17 00:00:00 2001 From: fixerTwo Date: Sun, 16 Jan 2022 19:37:33 +0000 Subject: [PATCH] added sql injection rules for node express --- .../express/nodejs-express-mysql-injection.js | 51 +++++++++++++++++++ .../nodejs-express-mysql-injection.yml | 32 ++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 semgrep/javascript/nodejs/express/nodejs-express-mysql-injection.js create mode 100644 semgrep/javascript/nodejs/express/nodejs-express-mysql-injection.yml diff --git a/semgrep/javascript/nodejs/express/nodejs-express-mysql-injection.js b/semgrep/javascript/nodejs/express/nodejs-express-mysql-injection.js new file mode 100644 index 0000000..41155f4 --- /dev/null +++ b/semgrep/javascript/nodejs/express/nodejs-express-mysql-injection.js @@ -0,0 +1,51 @@ +const express = require("express"); +const app = express(); +const mysql = require('mysql'); + +const connection = mysql.createConnection({ + host : 'localhost', + user : 'username', + password : 'password', + database : 'databasename' +}); + +connection.connect((err) => { + if(err) throw err; + console.log('Connected to MySQL Server!'); +}); + +//this is vulnerable code +app.get("/insecure",(req,res) => { + connection.query("SELECT * FROM studesnt_records WHERE sid = '"+ req.body.sid +"' AND name = '"+ req.body.name +"'", (error, results) => { + if (error) throw error; + }); +}); + +//this is safer code || Use prepared statements where/when possible +app.get("/safer",(req,res) => { + connection.query("SELECT * FROM student_records WHERE sid = '"+ connection.escape(req.body.sid) +"' AND name = '"+ connection.escape(req.body.name) +"'", (error, results) => { + if (error) throw error; + }); +}); + +//this is safe code +app.get("/safe",(req,res) => { + connection.query("SELECT * FROM health_records WHERE dob = ? AND name = ?",[req.body.dob, req.body.name], (error, results) => { + if(error) throw err; + console.log('The data from users table are: \n', rows); + connection.end(); + }); +}); + + +//this is unexploitable code +app.get("/safe",(req,res) => { + connection.query("SELECT * FROM student_records WHERE sid = '123465' AND name = 'Dan'", (error, results) => { + if (error) throw error; + }); +}); + + +app.listen(3000, () => { + console.log('Server is running at port 3000'); +}); \ No newline at end of file diff --git a/semgrep/javascript/nodejs/express/nodejs-express-mysql-injection.yml b/semgrep/javascript/nodejs/express/nodejs-express-mysql-injection.yml new file mode 100644 index 0000000..24649c0 --- /dev/null +++ b/semgrep/javascript/nodejs/express/nodejs-express-mysql-injection.yml @@ -0,0 +1,32 @@ +rules: + - id: nodejs-mysql-body-inection + languages: + - javascript + message: | + Potential SQL Injection identified. Consider using the connection.escape method built in node-mysql + patterns: + - pattern-inside: | + $MYSQL=require('mysql') + ... + $CONN = $MYSQL.createConnection(...) + ... + - pattern: | + $CONN.query($SQL,...) + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - pattern-inside: $APP.get(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.post(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.put(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.head(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.delete(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.options(..., function $FUNC($REQ, $RES) {...}) + - pattern-regex: \+.*?\+ + - pattern-not-regex: \+.*?escape.*?\+ + - pattern: $REQ.body.$DATA + - metavariable-pattern: + metavariable: $SQL + patterns: + - pattern-regex: .*\b(?i)(SELECT|CREATE|DROP|INSERT|DELETE|UPDATE|ALTER)\b.* + fix: $CONN.escape($REQ.body.$DATA) + severity: ERROR \ No newline at end of file