How to escape single quotations (apostrophes) in MySQL query through Node.js? - javascript

I'm making a program where the user will enter data into inputs on a website. This information will then be relayed back to the server, using socket.io, and will be stored in a database. I am using this library to access MySQL from Node.js. Usually, when the user inputs the data, it is fine. But when the data includes single quotations, things aren't working. Here's an example:
let data = "LET'S GO";
// this is the data that the user inputs
// if it has single quotations in it, the code doesn't work
// otherwise it does
connection.getConnection(function(error, conn) {
if (error) throw error; // if there's an error while connecting, throw it
conn.query(
`INSERT INTO table_name (column) VALUES ('${data}')`, // make query with this MySQL call
function(err, result) {
conn.release();
if (err) throw err; // if there's an error with the call, throw it. Usually where my error comes
}
)
})
As commented in the code above, if the data variable has single quotations in it, the MySQL will return an error like the following:
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 's go.' at line 1
After initially running into this error, I've been looking for a solution. On this page, it says to use mysql.escape(), connection.escape() or pool.escape() to eliminate this issue. I've looked all over Stack Overflow solutions, but they all seem to point back to this. The issue with this solution is that the data is entered into the MySQL query with two single quotations around it. Therefore, the query looks a bit like this:
INSERT INTO table_name (column) VALUES (''DATA_HERE'')
Instead of:
INSERT INTO table_name (column) VALUES ('DATA_HERE')
In addition, I've looked at similar issues with mysql.escape(), connection.escape(), and pool.escape(), but they have been of no help because most of them do not have direct solutions.
Is there any OTHER way to escape these single quotations (apostraphes), if they were to appear in the data that the user inputs?
Thank you in advance. Any and all help is appreciated.

Alright, so it looks like I found an answer. My query has to be formatted in a way similar to prepared statements (thanks to #danblack for this). It should be done as such:
conn.query(
`INSERT INTO table_name (column) VALUES (?)`,
[data],
function(err, result) {
conn.release();
if (err) throw err;
}
)
I replaced '${data}' with ? and, in the next argument of the conn.query() function, I gave the value that ? should be replaced with.
If there is more than one data value that needs to be "escaped" in a similar way, you would do this:
conn.query(
`INSERT INTO table_name (column1, column2, column3) VALUES (?, ?, ?)`,
[data1, data2, data3],
function(err, result) {
conn.release();
if (err) throw err;
}
)
If anyone else happens to have a similar pending question, I hope this answers.
Note: this way of "escaping" doesn't only work with INSERT statements. I believe it can be used for all other queries.

Related

Simple postgres select query hangs forever when string passed as parameter

I am unable to figure out why the following query fails in node.js with pg PostgreSQL client (version 8.5.1).
db.query("SELECT id FROM my_table WHERE name LIKE $1", ["foo"], (error, results) => {
if (error) {
throw error
}
console.log(results.rows)
});
I do not get a error message and db.query function hangs forever.
However the following works, which I thought would be the same but I am obviously missing something:
db.query("SELECT id FROM my_table WHERE name LIKE 'foo'", ...
My table looks like this and have less then 10 rows:
CREATE TABLE IF NOT EXISTS my_table (
id SERIAL PRIMARY KEY,
name VARCHAR ( 128 ) UNIQUE NOT NULL
);
In case it is relevant, db.query is called from a express app endpoint handler. Also, passing parameters/values to INSERT statements works.
Edit: A prepared statement also works, still do not understand why above do not.
Any suggestions?

Using a variable in a WHERE clause MySQL/Node

I'm trying to make a MySQL query to filter data from a table. Effectively what I want to do is:
SELECT data FROM table WHERE column IN ?
The filter is coming from checkboxes in a form on a webpage, so I can pass an array or object fairly easily, but it'll be a varying number of parameters for the IN each time, so I can't us multiple ?. I tried making a for loop to make multiple queries concatenate the arrays that the queries returned, but I ran into scope issues with that. I also tried passing an array directly to the query, but that throws a syntax error. I'm sure there's a straightforward answer to this but I'm not sure how to do it.
Edit: source code added:
Here's where I'm at:
const filterShowQuery = `SELECT sl_Show.showId, sl_Band.BandName,
sl_Show.date, sl_Venue.venueName,
sl_Show.length, sl_Show.attendance, sl_Show.encore FROM sl_Show
JOIN sl_Band on sl_Show.BandID = sl_Band.BandId
JOIN sl_Venue on sl_Show.VenueId = sl_Venue.VenueId
WHERE sl_Band.BandName IN (?)
ORDER BY sl_Band.BandName;`;
Trying to get an array into the ? in WHERE sl_Band.BandName IN
const getShows = (req, res,next) =>{
var {bands, venues} = req.body;
var i = 0; //left over from previous attempt
var data = [];
for (b in bands){
mysql.pool.query(filterShowQuery, bands[b], (err, result) => {
if(err){
console.log('filter band error');
next(err);
return;
}
data = data.concat(result);
console.log(data); //data concatenates property and increases through for loop
})
// same action to be performed with venues once solved
// for (v in venues){
// conditions[i] = venues[v];
// i++;
console.log(data); //data is empty when logging from here or using in res
res.json({rows:data});
}
}
SECURITY WARNING!
I must to say: NEVER, NEVER PASS DATA DIRECTLY TO YOUR SQL!
If you don't know why, just google for SQL Injection. There are lots of examples on how it is done, how easily it can be done, and how to protect your application from this sort of attack.
You should always parametrize your queries. But in the very rare case which you really need to insert data concatenating a string into your sql, validate it before.
(E.g.) If it's a number, than use a Regex or some helper method to check if the value you are inserting into your SQL String is really and only a number and nothing else.
But aside that, you did not provide any source code, so it's really hard to give any help before you do that.

Populating a many - many doesn't populate, and throws no errors

My database looks like this:
Table: Guilds -> guild_id, guild_name, guild_owner, guild_owner_id, guild_member_count, guild_prefix.
Table: Members -> member_id, member_name, member_disc
Table: Guildmembers -> guild_id, member_id, warning_points, chat_points
So guild_id and member_id are the values from Discord and are both PK's. My aim is to tie each member to a guild specifically, to add warning_points and chat_points.
I can populate both the Guilds table and the Members table, however, it doesn't auto-populate the Guildmembers table with the relevant data.
Upon trying to populate the table with this code:
let guiMemSQL = 'INSERT INTO Guildmembers(guild_id, member_id) SELECT Guilds.guild_id, Members.member_id FROM Guilds INNER JOIN Members ON Guilds.guild_id = Members.member_id'
con.query(guiMemSQL, (err, result) => {
if(err){ throw err }
console.log(`Updated GuildMembers Table`);
})
I get no errors. The table doesn't populate either. So either there is a flaw in my code/logic or I have not understood what I am doing correctly.
The information I am trying to get is guild_id and member_id, they are BIGINTs.
mysql will not auto-populate a many-many table, you have to INSERT the values as you would any other table. The way I did this was with the below code:
// Update GuildMembers Table
let guiID = MemberInfo.userGuildID;
const memGuiID = BigInt(guiID); // Convert String to Number
const updGMT = {guild_id: memGuiID, member_id: memIdNo };
let guiMemSQL = 'INSERT INTO Guildmembers SET ?';
con.query(guiMemSQL, updGMT, (err, result) => {
if(err){ throw err }
console.log(`Updated GuildMembers Table`);
})
The use case of parameterised queries here, although not question specific are important to help combat the risk of sql injection attacks. And would be seen as good practise.
If anyone does know of a way to get the fields to auto-populate, please share!.
Currently I shall leave what I did to resolve this, In case others have a similar issue.

Node js mysql returns empty result when asking with AND operator

I have trouble with MySQL query in Node.js
This is my source code:
var passwordHash = sha512(data.passwordLogin).toString('hex');
database.query('SELECT `name`, `email`, `email-validated` FROM Players WHERE `email` = ? AND `password` = ?', [database.escape(data.name), database.escape(passwordHash)], function (error, results, fields) {
if(error)
logger.error(error);
else
{
logger.debug(results[0].name); //This line returns an empty array
}
});
It is working fine when I ask only for email, but with AND operator in query it returns an empty array as result.
Data given to query and data in database are equal.
Also trying to access something like results[0], results[0][0] or results[0].name causes server (app.js) to crash.
Any ideas to solve this? If you need more information about the source code just ask.
I really appreciate your help.

MySql Update query using escaping string array giving error

I have just learnt about SQL injection so I am making my queries a little more safe, everything has worked out so far except when I use update.
var sql = 'UPDATE Clients SET LastAccessDate= ? WHERE ClientID= ?';
var values = [
[timeStamp[1], ClientID[1]],//timeStamp=1473674800015, ClientID= 123
[timeStamp[2], ClientID[2]],
[timeStamp[3], ClientID[3]],
[timeStamp[4], ClientID[4]]
];
connection.query(sql, [values], function(err) {
if (err) {
throw err;
console.log("Error updating Last Access times");
}
else if(!err){
connection.end();
}
});
The connection to the database was done correctly, all column names are correct and arrays for the variables is correct, but I get an error that the syntax is wrong for update and I don't know where to look for the correct answer as my searches have been unsuccessful so far. What is the correct syntax for update and where can I look to find the syntax for other queries? The timestamp is a Bigint and the clientID is a unsigned int. Also ClientID is unique. Using nodejs and mysql database.

Categories

Resources