Do you need brackets around Mysql parameters to prevent sql injection? - mysql

I am using nodejs and the mysql npm package and I'm trying to select from a table where other_text =
Here is what it looks like:
var query = connection.query(`SELECT id FROM ${tableName} WHERE other_text = ?`,
attributeName.other_text, function (err, rows) {
...
I have read that using ? will automatically escape the user entered string. In most of the examples that I see that do this, they have brackets around the 2nd parameter in the query function, like below:
var query = connection.query(`SELECT id FROM ${tableName} WHERE other_text = ?`,
[attributeName.other_text], function (err, rows) {
...
Are the brackets necessary in order to escape the string that's passed in? It works when I try it, but I don't even know how to test a SQL injection so I don't really know if the brackets are necessary or even correct.
Thank you.

The brackets represent an array. You can use an array in case you have more values you want to use with your query.
For example, let's say that you want to select multiple columns from the table, and you want to pass them to the statement, you would use something like this:
connection.query(`SELECT ?? FROM ${tableName}`,
[col1, col2, col3], function (err, rows) {
It also does work in combination with strings, numbers or even objects. Let's say that you want to update the user with id 1 from Users table table. You would do something like this:
const tableName = 'users';
const whereCondition = {id: 1};
const whaToUpdate = {name: 'newName'}
const mysql = require('mysql');
const statement = mysql.format('update ?? set ? where ?', [tableName, whaToUpdate , whereCondition]);
I also recommend using .format for better code reading.
Finally you would have something like this:
connection.query(statement, (error, result, fields) => { });

The bracket uses for passing multiple values. You can use escape function or question mark (?) placeholder to prevent SQL injections. Lets have a look in details:
We are using mysql node module to provide all example below (Example 1 to Example 5). The below code is necessary to follow those example.
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
MySQL con.query has overloaded function.
Example 1: it takes sql string and callback function
var sql = 'SELECT * FROM customers;
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
});
Example 2: it takes sql string, parameter and callback function
var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ?';
con.query(sql, [adr], function (err, result) {
if (err) throw err;
console.log(result);
});
In Example 2, the second parameter uses [ ] so that you can pass
array to provide multiple values as parameter. Example 3 shows how to pass multiple values in second parameter.
Example 3: Here two values are passed name and address into [ ]
var name = 'Amy';
var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE name = ? OR address = ?';
con.query(sql, [name, adr], function (err, result) {
if (err) throw err;
console.log(result);
});
Preventing SQL injections
To prevent SQL injections, you should use escape function the values when query values are variables provided by the user.
Example 4: Here we used escape function to avoid SQL injections
var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ' + mysql.escape(adr);
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
});
Example 5: Escape query values by using the placeholder ? method
var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ?';
con.query(sql, [adr], function (err, result) {
if (err) throw err;
console.log(result);
});
More details

Related

Preventing Nodejs MySQL SQL Injection

How do I prevent SQL injection for NodeJS? I am trying to prevent SQL Injection using the ? symbol and the req.param. But I am not able to get to work. How should I use the req.param.id correctly? Many thanks in advance.
app.get('/products/:id', (req, res) => {
conn.getConnection(function (err, connection) {
if (err) throw err;
const SELECT_WHERE_PRODUCT_ID_QUERY = `SELECT * FROM products WHERE id = ?, $[req.param.id]`
connection.query(SELECT_WHERE_PRODUCT_ID_QUERY, function (error, results, fields) {
connection.release()
if (error) throw error;
return res.send(results)
});
});
});
Yes, we should use prepared statements for that and ? as placeholders. In order to make it work, we should pass parameters as a separate argument:
const query = 'SELECT * FROM products WHERE id = ?';
const params = [req.param.id];
connection.query(query, params, function (error, results, fields) {
Another form:
connection.query(
{
sql: 'SELECT * FROM products WHERE id = ?',
values: [req.param.id]
},
function (error, results, fields) {
See documentation for more examples.
This should prevent SQL injection.
const SELECT_ALL_PRODUCT_QUERY = 'SELECT * FROM products WHERE id = ?'
connection.query(SELECT_ALL_PRODUCT_QUERY,[req.params.id], function (error, results)

How to get only name of user from database in node.js

I am retrieving user name of the person who is logged in from database. BUt i am getting results like
[RowDataPacket { First_Name= 'Rani'} ] But i only need to get that "Rani'. How to do that in node.js?
I only want to get username except those extra parameter(First_Name) e.g "Rani" in above case.
This is part of code where i am getting value.
I have tried var myJSON = JSON. stringify(obj) but it shows [ { First_Name= 'Rani'} ].
app.post('/auth', function(request, response) {
var number = request.body.number;
var password = request.body.pwd;
var qu = `SELECT
First_Name
FROM fyp_helpers
WHERE Mobile_number = ?
UNION
SELECT
Employer_Fname
FROM fyp_employers
WHERE Employer_Contact = ?`;
connection.query(qu, [number, number], function (error, results, fields){
if (error) throw error;
else
{
console.log(results);
..........
The column names from the query become properties of the objects that represent the rows of results. So use
console.log(results[0].First_Name);

Node mysql in Discord.js returns empty result/array

I'm trying to make a command that get the selected queries from a table where the id is the one i use in the command, for example: !db 1 but I'm having a problem.
The problem is that the result is empty.
My code:
const Discord = require('discord.js');
const mysql = require('mysql');
module.exports.run = async (bot, message, args, connection) => {
const asd = args.slice(1,2).join(' ');
let querystring = `SELECT * FROM test WHERE id = '${asd}'`
connection.query(querystring, function (err, results, rows) {
if (err) throw err;
console.log(results);
});
}
module.exports.help = {
name: "db"
}
I appreciate any help! Thanks!
From the screenshot you posted earlier, your id column is a type INT. This code is searching as if the column is a VARCHAR.
Try this:
const id = args.slice(1, 2).join(' ');
if (isNaN(id)) { return; } // if the input isn't a number
connection.query(`SELECT * FROM test WHERE id = ${Number.parseInt(id)}`, (err, res, rows) => {
if (err) throw new Error(err);
console.log(res);
});
Important: This code allows SQL Injection. Template literals do not protect against this.

how to return \ retrieve a result from node.js module that does query to mysql?

I want to pass a result from mysql query to the level above...
I have this module: mySQLconnect.js:
var connection = require('mysql').createConnection({
host : 'localhost',
user : 'admin',
password : ''
});
exports.querySelect = querySelect;
function querySelect(query){
var result = connection.query(query, function(err, rows){
return (rows[0]);
});
return result;
}
and when I call this function from outside, let's say from app.js:
var DBconnector = require('mySQLconnect');
var result = DBconnector.querySelectUser("SELECT * FROM TB_USERS");
but the result I get is something else - it's an object from mysql.js module that's been received from:
connection.query(query, function(err, rows)
it has: _resultSet =null, and unreachable _results =[Array]
so it's no good...
I checked in node-mysql website, but didn't find what's connection.query returns.
any ideas how can I pass the result?
You are wrapping an asynchronous call to the DB with a procedural function – a common mistake for nodejs beginners coming from a procedural language like PHP.
You can simplify your mySQLconnect.js module to the following:
var connection = require('mysql').createConnection({
host : 'localhost',
user : 'admin',
password : ''
});
exports.querySelect = connection.query;
And then consume it thusly:
var DBconnector = require('mySQLconnect');
DBconnector.querySelect("SELECT * FROM TB_USERS", function (err, rows) {
console.log(err || rows);
});
I would read up on callbacks, anonymous functions, and asynchronous flow patterns to help you wrap your head around this new style of coding. Good luck!

Parsing string in nodejs

I am uploading images using nodejs
My query is like:
var user = req.body;
var imgurl=projectDir +"/uploads/"+req.files.displayImage.name;
var sql= "INSERT INTO users values('','"+user.name+"','"+user.email+"','"+user.user+"','"+user.pass+"','"+imgurl+"',now())";
Everything goes right, except when it inserts imgurl it does not parse it,
My project directory is D:\node
also I get it in projectDir =D:\node
But it will insert in database like:
D:
ode/uploads/canvas.png
I understand that it converts \n to new line,
So, my question is how to prevent this and what should I do for both single and double quotes insertion?
Thanks.
Escape them using \ as such \\n or \" \' etc.
Here's a related question that answers your query.
The method:
function mysql_real_escape_string (str) {
return str.replace(/[\0\x08\x09\x1a\n\r"'\\\%]/g, function (char) {
switch (char) {
case "\0":
return "\\0";
case "\x08":
return "\\b";
case "\x09":
return "\\t";
case "\x1a":
return "\\z";
case "\n":
return "\\n";
case "\r":
return "\\r";
case "\"":
case "'":
case "\\":
case "%":
return "\\"+char; // prepends a backslash to backslash, percent,
// and double/single quotes
}
});
}
You can store the mysql_real_escape_string() function as a separate module and require it before usage or directly insert it into the .js file that will be using it.
You could use it as shown below:
var sql= "INSERT INTO users values('','"+user.name+"','"+user.email+"','"+user.user+"','"+user.pass+"','"+mysql_real_escape_string(imgurl)+"',now())";
You should consider preparing your queries using the '?' syntax (https://github.com/felixge/node-mysql#preparing-queries).
var sql= "INSERT INTO users SET ?";
// Connection attained as listed above.
connection.query( sql, { name:user.name, email:user.email, user:user.user, pass:user.pass, image:imgurl, timestamp:now()}, function(err, result){
// check result if err is undefined.
});
Using this pattern, node-mysql will do all the escaping and safety checks for you.
Hope this helps...
Uggh, escape all the backslash and quotes in your query string. Always use connection.escape
var mysql = require('mysql');
var connection = mysql.createConnection(...);
var userId = 'some user provided value';
var sql = 'SELECT * FROM users WHERE id = ' + connection.escape(userId);
connection.query(sql, function(err, results) {
// ...
});
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : '*****'
});
connection.connect(function(err){
if(!err) {
console.log("Database is connected");
} else {
console.log("Error while connecting with database");
}
});
var message = req.body.message;
var user_id = req.body.user_id;
var sql = "INSERT INTO users(user_id, message) VALUES ('"+user_id+"', "+connection.escape(message)+")";
connection.query(sql, function(err, result) { });