Using variables in a node.js mysql-node query - javascript

I am running a mysql query with WHERE, I would like to include my input prompt variable, input how would I go about doing so? my current query is like so,
var connect = connection.query('SELECT url FROM Sonic_url WHERE name='
+ input //<where I'm confused
, function(err, rows, fields) {

You can just include it the way you did, but that will give you an unescaped query which is open to sql - injection. To prevent you from this, you can use mysql.format
var sql = mysql.format("SELECT url FROM Sonic_url WHERE name=?", [input]);
var connection = connection.query(sql, function(err,rows,fields) {});

Related

how to sanitize sql.js inputs?

I am using sql.js to manage the SQLite file I created for an electron app. My issue is that I want to make sure all the inputs are sanitized. As of now, I am using statements like so:
const SQL = await sqljs();
const db = new SQL.Database();
// These values are just examples and will be user inputs through electron.
let id = 1;
let name = 'row name';
db.run(`INSERT INTO tableName VALUES (${}, 'hello');`);
I'm pretty sure that this way is unsafe and can cause SQL injections. What can I do to prevent such a problem? Thank you kindly.
You can use bound parameters. These are values that are passed to the database engine and not parsed as part of a SQL statement:
let id = 1;
let name = 'row name';
/* Either pass in a dictionary to use named bound parameters */
db.run("INSERT INTO tableName VALUES(:id, :name)", { ':id': id, ':name': name });
/* Or an array to use positional bound parameters */
db.run("INSERT INTO tableName VALUES(?, ?)", [id, name]);
More information is available in the SQLite documentation, as well as sqljs documentation.

Can't parse integer in mysql prepared statement using util.format() in node js

I am using util module in node.js for formatting strings. But I found a catch when I wanna run an SQL Query like -
select * from something LIMIT 5 OFFSET 0;
So what I am trying to do is, I've created a queryString then format that queryString and finally execute the query through server application. Here is the code in nodejs :
queryString = "select * from something LIMIT '%d' OFFSET '%d'";
query = util.format(queryString, 5, 0);
res = db.executeQuery(query);
I have also tried %i and %s, with quotes and without quotes but nothing worked for me.
Here is the log :
Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%i OFFSET %i' at line 1
I am sure I am missing something here. Thanks in advance
Assuming you are using mysql module
There are other ways:
var limit = 5;
var offset = 0;
var qs = `select * from something LIMIT ${limit} OFFSET ${offset}`;
or
connection.query('select * from something LIMIT ? OFFSET ?', [limit, offset], function (error, results, fields) {
...
});
or
var sql = mysql.format('select * from something LIMIT ? OFFSET ?', [limit, offset]);
See docs

how should I apply sync node.js module with mysql, socket functions?

I'm trying to understand and use sync-npm module, but not sure how to change my functions below to match sync format... (https://www.npmjs.com/package/sync)
Basically I'm trying to use input data (which is formed as a list in client side) I receive from frontend(client) and send it to node.js via socket. I tried to store it in my global variable 'query', but I learned that it doesn't get updated. So when I tried to print 'query' outside of socket function, it doesn't work.
It sounds like I should use sync module, but I'm not quite sure how to implement that in my code...If anyone could give me an idea how to change my functions below, it would be great..thanks!
Receiving input data from frontend and sending it to node.js via socket
var server = app.listen(3001);
var socket = require('socket.io');
var io = socket(server);
var query = []
// Register a callback function to run when we have connection
io.sockets.on('connection',newConnection);
function newConnection(socket){
console.log('new connection: ' + socket.id);
socket.on('search', newSearch);
function newSearch(final){
query.push(final)
console.log(query[0]);
console.log(Array.isArray(query[0])); //returns True
console.log(query[0][0]); // this also works
console.log(query[0][1]);
}
}
console.log('print');
console.log(query);
// this only gets printed in the beginning as an empty array
Ultimately, I'm parsing that list of input data and concat into my sql select phrase. Below is my DB portion code:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '~~~',
user : '~~~',
password : '~~~',
database : '~~~'
});
connection.connect();
console.log('mysql connected');
var sql = 'select' + '*' + 'from EBN ';
//ideally data in the 'query' list will concat with this sql string
connection.query(sql,function(err,rows,fields){
if(err){
console.log(err);
}
else{
fs.writeFileSync('search.json', JSON.stringify(rows), 'utf8');
}
});
Firstly, you should wrap the code that does the query execution in a function, something like
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '~~~',
user : '~~~',
password : '~~~',
database : '~~~'
});
connection.connect();
console.log('mysql connected');
function executeQuery(query)
var sql = 'select' + '*' + 'from EBN ';
//do something with query and add it to the sql string
connection.query(sql,function(err,rows,fields){
if(err){
console.log(err);
}
else{
fs.writeFileSync('search.json', JSON.stringify(rows), 'utf8');
}
}
}
This is necessary because you don't want to execute a query right after starting the server, but only after you received the query message via socket. So now you can call executeQuery(final) in your socket message handler.
You should learn how asynchronous programming and callbacks works in nodejs/javascript, and why you should use it as much as possible for server applications (e.g. use fs.writeFile instead of writeFileSync). You can use packages like sync to make life easier for you, but only when you know exactly what you want to do. Just throwing something with the name 'sync' in it at a problem that might be caused by asynchronicity is not going to work.

Prevent SQL Injection in JavaScript / Node.js

I am using Node.js to create a Discord bot. Some of my code looks as follows:
var info = {
userid: message.author.id
}
connection.query("SELECT * FROM table WHERE userid = '" + message.author.id + "'", info, function(error) {
if (error) throw error;
});
People have said that the way I put in message.author.id is not a secure way. How can I do this? An example?
The best way to is to use prepared statements or queries (link to documentation for NPM mysql module: https://github.com/mysqljs/mysql#preparing-queries)
var sql = "SELECT * FROM table WHERE userid = ?";
var inserts = [message.author.id];
sql = mysql.format(sql, inserts);
If prepared statements is not an option (I have no idea why it wouldn't be), a poor man's way to prevent SQL injection is to escape all user-supplied input as described here: https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#MySQL_Escaping
Use prepared queries;
var sql = "SELECT * FROM table WHERE userid = ?";
var inserts = [message.author.id];
sql = mysql.format(sql, inserts);
You can find more information here.
Here is the documentantion on how to properly escape any user provided data to prevent SQL injections: https://github.com/mysqljs/mysql#escaping-query-values .
mysql.escape(userdata) should be enough.

Using mysql node.js driver to get an entire database as JSON

I'm working on creating a JavaScript file to get a JSON dump of an entire MySQL database, running on server side. I found and am using the MySQL driver for node.js (https://www.npmjs.com/package/mysql) for queries, it's been straight forward enough to start. My issue is that I need to call multiple queries and get the results from all of them to put into a single JSON file and I can't quite get that to work. I'm entirely new to JavaScript (basically never touched it before now) so it's probably a relatively simple solution that I'm just missing.
Currently I do a query of 'SHOW TABLES' to get a list of all the tables (this can change so I can't just assume a constant list). I then just want to basically loop through the list and call 'SELECT * from table_name' for each table, combining the results as I go to get one big JSON. Unfortunately I haven't figured out how to get the code to finish all the queries before trying to combine them, thus retuning 'undefined' for all the results. Here is what I currently have:
var mysql = require('mysql');
var fs = require('fs');
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'pass',
database: 'test_data'
});
connection.connect();
connection.query('SHOW TABLES;', function(err, results, fields)
{
if(err) throw err;
var name = fields[0].name;
var database_json = get_table(results[0][name]);
for (i = 1; i < results.length; i++)
{
var table_name = results[i][name];
var table_json = get_table(table_name);
database_json = database_table_json.concat(table_json);
}
fs.writeFile('test_data.json', JSON.stringify(database_json), function (err)
{
if (err) throw err;
});
connection.end();
});
function get_table(table_name)
{
connection.query('select * from ' + table_name + ';', function(err, results, fields) {
if(err) throw err;
return results;
});
}
This gets the table list and goes through all of it with no issue, and the information returned by the second query is correct if I just do a console.log(results) inside the query, but the for loop just keeps going before any query is completed and thus 'table_json' just ends up being 'undefined'. I really think this must be an easy solution (probably something with callbacks which I don't quite understand fully yet) but I keep stumbling.
Thanks for the help.
I'm guessing that this is for some sort of maintenance type function and not a piece that you need for your application. You're probably safe to do this asynchronously. This module is available here: https://github.com/caolan/async
You can also use Q promises, available here: https://github.com/kriskowal/q
This answer: describes both approaches pretty well: Simplest way to wait some asynchronous tasks complete, in Javascript?

Categories