Node.JS - SQL Injection in URL parameters? - mysql

I'm trying to learn Node.js and I'm currently making an Express app (using ejs) that will return values from a MySQL database, depending on the URL the user visits.
For example, visiting http://localhost:3000/test will list all users from the db table users. And the link http://localhost:3000/test/3 will return information about the user with the id number 3.
My code for: /test
app.get("/test", (req, res) => {
let sql = "SELECT * FROM users ORDER BY name";
db.query(sql, function (err, results, fields) {
if (err)
logmessage(err.message);
res.render("test", { data: results });
});
});
And here is the code for /test/:id
app.get("/test/:id", (req, res) => {
var userId = req.params.id;
let sql = "SELECT * FROM users WHERE id = " + userId;
db.query(sql, function (err, results, fields) {
if (err || !results.length) {
res.redirect("/");
} else {
res.render("test_user", { data: results });
}
});
});
My question is: is this safe? When I previously worked in PHP development, I used to prepare statements before making any queries.
What happens if a user changes the URL from: http://localhost:3000/test/3 and inserts some SQL injection code at the end of the url? Can the database be breached?
This will be for a live app on the web, so it's important no SQL injection can be made. I also want to add a form later on (req.body instead of req.params) that I also need to sanitize.
Or is there a built-in "prepared statement" already in Node?

SQL injection is prevented if you use placeholders:
let sql = "SELECT * FROM users WHERE id = ?";
db.query(sql, [userId], function (err, results, fields) {...});

Have you tried to implement Sequelize? From what I read ORMs prevent SQL injection. Also, it's pretty easy to use :)

Related

How do you update two tables without joining in Node.js?

How do you update two MySQL tables with a single click of the retire button? I have created a table where you can edit based on the serial number of agent shown below. By clicking the retire button, it should change the AgentStatus to Retired and the policies under that agent to another agent. Is MySQL query correct or do I make two queries instead?
This is in my html for showing agent in agentavia
This is the agentavia table to change status from active to retired
This is policy1 table where policyAgent will change to another agent name as they click the retired button.
Code for changing data in mysql
router.get("/retire/:id", function (req, res, next) {
const AgentId = req.params.id;
const sql = `SELECT * FROM agentavia WHERE id= ${AgentId}`;
db.query(sql, function (err, data) {
if (err) throw err;
res.render("modifyagent", { title: "Agent List", editData: data[0] });
});
});
router.post("retire/:id", function (req, res, next) {
const sql = `UPDATE * from agentavia and policy1 WHERE id= ? and agentStatus = 'Retired' and
policyAgent = 'Vani'` ;
db.query(sql, function (err, data) {
if (err) throw err;})
alert("New agent shall take over your policies");
});
});

Using MySQL db functions (?) with SQLite (Node.js)

I'm using a tutorial to do JWT/bcryptjs auth and then INSERT into a SQlite
table.
Thing is the tutorial is for MySQL and I get errors like db.query is not a function
and db.escape is not a function
The db :
const sqlite3 = require('sqlite3').verbose()
const DBSOURCE = "./src/db/db.sqlite"
let db = new sqlite3.Database(DBSOURCE, (err) => {
if (err) {
// Cannot open database
console.error(err.message)
throw err
}else{
console.log('Connected to the SQLite database.')
}
});
module.exports = db
Example query :
db.query(
`SELECT * FROM users WHERE LOWER(username) = LOWER(${db.escape(
req.body.username
)});`,
(err, result) => {
if (result.length) {
return res.status(409).send({
msg: 'This username is already in use!'
});
} else { .........
My best guess is that the functions are different?
How do I get this right?
There are a lot of proprietary functions in MySQL that will not work with standard SQL in other database systems.
That is just the beginning of the differences between Mysql and SQLite
Provide some query examples and we may be able to assist you with each one.
-- update after your addition of query code...
Here is an example of sqlite-nodejs
const sqlite3 = require('sqlite3').verbose();
// open the database
let db = new sqlite3.Database('./db/chinook.db');
let sql = `SELECT * FROM users WHERE LOWER(username) = LOWER(?)`;
db.all(sql, [req.body.username], (err, rows) => {
if (err) {
throw err;
}
rows.forEach((row) => {
console.log(row.name);
});
});
// close the database connection
db.close();

Node Express MySQL multiple routing

I want to make an route with multiple parameters using Node Express MySQL. Is it possible to do this with traditional url parameters like: page?id=2&user=10
Here is a simple query, but the only way of doing it so far is like this: page/2/10
app.get("/get-page/:id/:user", function (req, res) {
let sql = "SELECT * FROM table WHERE id= '${req.params.id}' AND userid= '${req.params.user}'`;";
let query = db.query(sql, (err, results) => {
if (err) throw err;
res.send(results);
});
});
This is just an example.
The reason I would like the traditional way is because, with the "slash" method the parameters always have to come in the correct order, or did I miss something?
Perhaps use the query property of the request to access the query string, as in req.query.id:
app.get("/get-page", function (req, res) {
console.log('ID: ' + req.query.id)
});

nodejs throws error with mysql like query via prepared statements

Am retrieving values from database using nodejs.
I implemented mysql like query via prepared statement to ensure that sql injection attack is eliminated. my problem is that it does not retrieve any result. it just show empty results in the console please can someone point to me what is wrong with the query
exports.autosearch = function (req, res) {
//var search = req.body.searchText;
var search = 'bukatti';
//db.query('SELECT * FROM users WHERE name like ?', ['%' + search + '%'], function (error, results, fields) {
db.query('SELECT * FROM users WHERE name like ?', ['%search%'], function (error, results, fields) {
console.log(results);
});
}
Thanks
I have found out my problem. i added the error log and discover that the was type error somewhere. This fix it anyway
db.query("SELECT * FROM users WHERE name like ?", ['%' + search + '%'], function (error, results, fields) {
Thanks

how do I access the result(object) of a get request using express?

Here is my get request made to a mysql table
app.get('/', (req, res) => {
let sql = 'SELECT * from emarttesttable WHERE id = 229';
let query = db.query(sql, (err, results) => {
if(err){console.log(err);}
else{
console.log(results);
}
});
res.render('index');
});
As it stands, this function allows me to grab the information I want from the table and I can read the results via console.log. However, I'm unable to access results on my index.ejs page.
How do I access results(which is an object that contains the stuff I want) in my index.ejs file? Whenever I try to access results, it says that results in undefined. How do I make sure that the object that is created as a result of the call to the table is able to be used/accessed on a different page. For the time being, I would just like to create a simple table that has the keys in one column and the values in a second column.
You need to modify your code as below. The reason is db.query is an async operation and you are trying to render before the async request completed. Also, to be able to reach the result at your template engine, you need to pass the results to the render. (index.ejs)
app.get('/', (req, res) => {
let sql = 'SELECT * from emarttesttable WHERE id = 229';
let query = db.query(sql, (err, results) => {
if(err){console.log(err);}
else{
res.render('index', results);
console.log(results);
}
});