Node: Insert string of special characters in mysql database - mysql

I am implementing fingerprint authentication for my angular app using node tcp server in my scenario the bio metric device return the string of special characters to my node server which includes special characters like single and double like ##$'%" i wanted to store this complete string to database with single as well as double quotes. i have following query
var fingerPrint = '##$'%"'
db.query("insert into tbl_name (id, tempalte) value ('"+fingerPrint+"','')", (err, result)=>{
console.log(result)
})
but when string contain double quotes the query terminates as well as the problem with single quote. is there is any way to achieve this mechanism.
Thanks in advance

Here's one way to do it, using MySQL in NodeJs. This is what you can try:
let fingerPrint = `'##$'%"'`;
let addQuery = "INSERT INTO tbl_name (id, template) VALUES (?,?)";
let values = [1, fingerPrint];
db.query(addQuery, values, function (err, result) {
if (err) {
return console.error(err.message);
}
console.log("Number of records inserted: " + result.affectedRows);
})

Try
encodeURI() and decodeURI() it may work

Related

How to fetch string data stored as array in mysql

I have stored some unique codes in MySQL as array in respective to user email, now i want to verify the user with email and unique code submit by user. I want to create a query where i can match email and unique id stored in database, to proceed the user.
Database Entry:
["BZFeWwnmr8Rm6tuu","daFJWZCEtp2WzxtD","VV80UQQZ1ym77h0m"]
I have tried FIND_IN_SET
This is the code for API, I have stringify the user entered data, where it returns the value if there is single unique value stored, But if i fetch array of unique code e.g, ["BZFeWwnmr8Rm6tuu","daFJWZCEtp2WzxtD","VV80UQQZ1ym77h0m"]
the MySQL query not working.
exports.vr_client_detail = function (req, res) {
const JSON_DATA = 'application/json';
if(req.headers['content-type'] === JSON_DATA){
if (req.body) {
var unique_string = JSON.stringify(req.body.unique_string);
var email = req.body.management_email;
db.sequelize.query('SELECT * FROM im_vr_client_activation '+
'WHERE FIND_IN_SET(unique_string, '+"'"+unique_string+"') AND "+
' management_email= ' + "'" + email + "'").then(function(app){
var arr = app[0];
return res.json({response_status:'success', response_code:185, data:arr, response:'Successfully fetch data.'})
});
}else{
return res.json({response_status:'error',response_code:10001,response:'Post data is empty.'});
}
}else{
return res.json({response_status:'error',response_code:10000,response:'Post data is not a json type.'});
}
}
The data returns nothing
{
"response_status": "success",
"response_code": 185,
"data": [],
"response": "Successfully fetch data."
}
It would be best if you normalized your schema, using a many-to-one table to hold all the unique strings instead of putting them into a single column.
But if you can't do that, you need to remove the [ and ] characters so you can use FIND_IN_SET().
You should also use a parametrized query to prevent SQL injection. See How to create prepared statements in Sequelize?
db.sequelize.query('SELECT * FROM im_vr_client_activation '+
'WHERE FIND_IN_SET(:unique_string, SUBSTR(unique_string, 2, LENGTH(unique_string)-2)) ' +
'AND management_email = :email', {
replacements: { unique_string: unique_string, email: email }
}).then(...)
If you're using MySQL 5.7 or higher you can change the datatype of the column to JSON and use JSON_CONTAINS(). And in 8.0 you can use the MEMBER OF operator.

How is 'Escaping query values' safe in sql? (Or why is it dangerous?) [SQL injection]

I'm following Node.js with sql examples on W3schools. here
It said the following code prevents 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);
});
When query values are variables provided by the user, you should escape the values.This is to prevent SQL injections, which is a common web hacking technique to destroy or misuse your database.
This was the explanation.
I want to understand how this is safe. (how this prevents SQL injections).
Also, how is the following code dangerous?
var sql = 'SELECT * FROM customers WHERE address = "Mountain 21"';
Unprotected string concatenation to generate a SQL statement is dangerous if the injected value (i.e. "Mountain 21") is source from an uncontrolled external source. For example, it is entered by a user.
Consider a plain string concatenation as follows:
var adr = <something accepted from an external source>
var sql = `SELECT * FROM customers WHERE address = "${adr}"`;
Then consider what might happen if the user entered the following into the text field:
Mountain 21"; delete all from customers; //
The query would become:
SELECT * FROM customers WHERE address = "Mountain 21"; delete all from customers; //"
If you ran that, you would probably end up with no customers in your table.
I am not personally familiar with the operation of the node.js mysql.escape function, but typically these sorts of functions "escape" special characters so they lose their "special-ness". For example, it might put a \ in front of the ; to remove it's significance as a statement separator.
Another more common example of what the escape function will typically do is convert a piece of text such as "O'Brien" to "O''Brien" (two single quotes is the way to specify a single quote in an SQL text string). A query that uses the "O'Brien" name would look something like this:
select *
from customers
where name = 'O''Brien';
The mySql.escape function will almost certainly provide the necessary conversion of "O'Brien" into "O''Brien" so that it can properly be run in an SQL query. Without the escape, the last line of the query would read:
where name = 'O'Brien';
which would result in a syntax error.
FWIW, The safest way is to use ? placeholders in your query for user supplied values (e.g. the address). This is a bit more cumbersome as you need to prepare your query, supply all of the values and then execute it. However, the benefit is that this is (should be?) completely immune to most, if not all, forms of "injection attack".
The basic flow for a parameterised query as per your example is (in java'ish pseudocode - as I don't about node.js's capabilities in this area) is:
val sql = "SELECT * FROM customers WHERE address = ?";
val preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString (1, adr);
val resultSet = preparedStatement.executeQuery();
Most if not all databases support parameterised queries, most languages expose this capability, but not all do expose it (or at least not easily). Again, I'm not sure about node.js.
I hope this helps you.
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);
});
var sql = 'SELECT * FROM customers WHERE address = Mountain 21';
To
var sql = 'SELECT * FROM customers WHERE address = "Mountain 21"';
https://stackoverflow.com/a/33679883/11343720
The Grave accent is better quote, double quote

Nodejs and MySQL, How to use NodeJs variable in MySQL INSERT statement

So basically, I have this JavaScript variable which stores this certain value, and I need to put this variable in MySQL Query statement.
Source Code:
var Pollution_Reading = 25;
DatabaseConnection.query('INSERT INTO Air_Pollution_Record (Air_Pollution_Reading) VALUES ('"Pollution_Reading"')');
I've tried every way that I know, but I still can't insert the value that the variable is holding into the database. What should I do?
DatabaseConnection.query('INSERT INTO Air_Pollution_Record (Air_Pollution_Reading) VALUES ('+Pollution_Reading+')');
Try doing this:
//reading post data
const useremail = req.body.useremail;
const password = req.body.password;
//save into db start
var sql = "INSERT INTO `users` (`UserName`, `UserPassword`) VALUES ('"+useremail+"','"+ password+"')";
you can try this format of template literals.
Gives you Easy and Clean code.
const sql = `INSERT INTO query_form (name, email, query_title, query_description) VALUES ('${name}', '${email}', '${query_title}', '${query_description}')`;
const sql = "INSERT INTO users (UserName, UserPassword) VALUES ('"+useremail+"','"+ password+"')";
This method and also above are good but naive if you have quotes in your input variable like single or double quotes. It will match the single quote with the input string and you will get error as it will not consider the remaining input.
So, after a long painful research I found a fix for quotes input strings as well. The solution is to not use values front hand and pass them inside con.query() method directly.
let query = `INSERT INTO gfg_table
(name, address) VALUES (?, ?);`;
// Value to be inserted
let userName = "Pratik";
let userAddress = "My Address";
// Creating queries
db_con.query(query, [userName,
userAddress], (err, rows) => {
if (err) throw err;
console.log("Row inserted with id = "
+ rows.insertId);
});
Reference:
https://www.geeksforgeeks.org/node-js-mysql-insert-into-table/

how to replace all the single quotes to \' for a mysql query

I have made a simple query using nodejs and mysql. The issue is whenever the user inputs product details containing any single quote an error occurs. How do i replace or remove such error.
You must escape the input values as reported in the documentation of mysql for nodejs using escape function.
From my understanding you want to Escape query values when you perform the mysql operations i don't know which mysql driver you are using but i will suggest some solutions with the node.js driver for mysql.
On this nodejs mysql drive builtin mechanism for Escaping query values.In order to avoid SQL Injection attacks, you should always escape any user provided data before using it inside a SQL query. You can do so using the mysql.escape(), connection.escape() or pool.escape() methods:
Caution These methods of escaping values only works when the
NO_BACKSLASH_ESCAPES SQL mode is disabled (which is the default state
for MySQL servers).
var userId = 'some user provided value';
var sql = 'SELECT * FROM users WHERE id = ' + connection.escape(userId);
connection.query(sql, function (error, results, fields) {
if (error) throw error;
// ...
});
Alternatively, you can use ? characters as placeholders for values you would like to have escaped like this:
connection.query('SELECT * FROM users WHERE id = ?', [userId], function (error, results, fields) {
if (error) throw error;
// ...
});
Multiple placeholders are mapped to values in the same order as passed. For example, in the following query foo equals a, bar equals b, baz equals c, and id will be userId:
connection.query('UPDATE users SET foo = ?, bar = ?, baz = ? WHERE id = ?', ['a', 'b', 'c', userId], function (error, results, fields) {
if (error) throw error;
// ...
});
This looks similar to prepared statements in MySQL, however it really just uses the same connection.escape() method internally.I hope this will helps you.
node-mysql this is a good library which auto escape query values check it out https://github.com/mysqljs/mysql#escaping-query-values

IN clause in mysql nodejs

I have a simple nodejs application which executes the following query.
select * from User where userid in (?)
The userids i get is a JSON array send from client side. How can i use that in this select query ? I tried
1. As itself but not working.
2. Convert this to Javascript array, not working
If you are using node module like mysql, the 2nd approach should work.
var query=select * from User where userid in (?);
var data=['a','b','c'];
var queryData=[data];
conn.query(query, queryData, function (err, results) {})
According to the documentation, "Arrays are turned into list, e.g. ['a', 'b'] turns into 'a', 'b'". So this approach should work (I have used it practically).
If you pass an array to the parameter it works with node mysql2. Parameters are already passed as arrays, so your first parameter needs to be an array [[1,2,3]].
select * from User where userid in (?)
const mysql = require('mysql2/promise');
async function main(){
let db = await mysql.createPool(process.env.MYSQL_URL);
let SQL = 'select * from User where userid in (?)';
let [res, fields] = await db.query(SQL, [[1,2,3]]);
console.log(res)
return res;
}
main().then(() => {process.exit()})
Revisiting this, since the original approach on the question is valid, but with some caveats. If your only escaped argument is the one on the IN clause, then you have to specify it as nested array; something like: [['usrId1', 'usrId2', 'usrIdN']]. This is because the un-escaping functionality expects an array, replacing each '?' with the corresponding array element. So, if you want to replace your only '?' with an array, that array should be the first element of all arguments passed. If you had more than one '?', the syntax is more intuitive, but at the end consistent and the same; in this case, you could have your arguments similar to: ['myOtherArgument1', 'myOtherArgument2', ['usrId1', 'usrId2', 'usrIdN'], 'myOtherArgument3']
Something like this could work!
// get your possible IDs in an array
var ids = [1,2,3,4,5];
// then, create a dynamic list of comma-separated question marks
var tokens = new Array(ids.length).fill('?').join(',');
// create the query, passing in the `tokens` variable to the IN() clause
var query = `SELECT * FROM User WHERE userid IN (${tokens})`;
// perform the query
connection.query(query, ids, (err, data) => {
// do something with `err` or `data`
});
You can do like this:
select * from User where userid in (?,?,?,?)
var array = [];
array.push(value);
array.push(value);
array.push(value);
array.push(value);
then use array as parameter that should be bind.
// get query string data with commas
var param=req.params['ids'];
//damy data var param = [1,2,3,4,5];
var array = params.split(",").map(Number);
//Note in select query don't use " and ' ( inverted commas & Apostrophe)
// Just use ` (Grave accent) first key off numeric keys on keyboard before one
con.query(`select * from TB_NAME where COL IN(?)`,[array],(err,rows,fields)=>{
res.json(rows);
});
let val = ["asd","asd"]
let query = 'select * from testTable where order_id in (?)';
connection.query(query, [val], function (err, rows) {
});
In Node, you need to put array in the array.
Update: Please see this answer. It is the correct way to do what is asked in the question.
The methods I have tried are:
Expand JSON array to a string in the required format. Concatenate it with query using '+'. (Beware of SQL injections)
Dynamically add '?' using length of JSON array holding user ids. Then use the array to provide user ids.
Both works. I then changed my logic with a better approach so now i don't need then 'in' clause anymore.