How do I properly escape the single quote in node-postgres queries? - node.js

I need to execute the following query:
db.query("SELECT * FROM items WHERE name ILIKE '%$1%';", [ query ])
It seems like node-postgres doesn't replace the $1 parameter and I don't know why. My query works if I change the line to:
db.query(`SELECT * FROM items WHERE name ILIKE '%${query}%';`)
But now I have problems when the query contains single quotes (').
Should I replace all single quotes using regex (as in query.replace(/'/g, "''")) (I don't think that's recommended)?
Otherwise, how can I get node-postgres to accept my parameter? I think it has something to do with the encapsulating % symbols. I keep running into the same problem with this issue.

Your placeholder isn't replaced because '%$1%' is an SQL string literal that just happens to look like it contains a $1 placeholder. You can add the percents in JavaScript using string operations:
db.query("SELECT * FROM items WHERE name ILIKE $1", [ `%${query}%` ])
// ---------------------------------------------------^^^^^^^^^^^^
or in SQL using SQL's string operations:
db.query("SELECT * FROM items WHERE name ILIKE '%' || $1 || '%'", [ query ])
// --------------------------------------------^^^^^^----^^^^^^

Related

How to avoid `%` symbol injection using LIKE fuzzy query

I am using like for fuzzy query, here is my code:
let mut q = users::table.into_boxed();
if let Some(email) = data.user.email {
if !email.is_empty() {
q = q.filter(users::email.like(format!("%{}", email)));
dbg_sql!(q);
}
}
If I set email=gmail% while querying, it generates sql like this
SELECT * FROM `users` WHERE (`users`.`email` LIKE ?) -- binds: [\"%gmail%\"]
A % symbol is spliced at the end of sql, and unexpected results are obtained after execution. How to avoid this? Need to escape the email query field, or use other sql queries, how to avoid this in diesel What happens?
You want to escape the corresponding query string by using the corresponding .escape() method.

DynamoDB parameterized PartiQL query with executeStatement

I have the following query with the aws sdk in nodejs and running in aws lamdba that doesn't work when using the parameters array:
executeStatement({
Statement: `select * from "myTable"."myIndex" where "pk" = '?' and "sortKey5" >= 50 ORDER BY "sortKey5" DESC`,
Parameters: [{"S": pk}] })
the same query with the parameter directly inline works
executeStatement({
Statement: `select * from "myTable"."myIndex" where "pk" = 'xxx' and "sortKey5" >= 50 ORDER BY "sortKey5" DESC` })
it's probably the syntax with '?' that is wrong but I couldn't find any sample with an other syntax.
does any one knows how to write the statement so that it uses the parameter?
It seems that, at least in a SELECT statement, one needs to omit the single-quotes around the ?, e.g. foobar = ? rather than foobar = '?'.
So your query would be:
executeStatement({
Statement: `select * from "myTable"."myIndex" where "pk" = ? and "sortKey5" >= 50 ORDER BY "sortKey5" DESC`,
Parameters: [{"S": pk}]
})

How to construct a `select ... in` SQL query in nim?

I'm using nim and db_sqlite to fetch some rows with certain _ids from a database table. For example:
for row in db.fastRows("SELECT * FROM t WHERE _id IN (?, ?)", #["1", "2"]):
echo row
This works as expected, however, the sequence at the end is constructed dynamically at runtime, which means I need a variable amount of ? in the query. I end up creating a sequence with question marks, joining them, interpolating the string and turning it into a database query:
var qs : seq[string]
for id in ids:
qs.add("?")
let query_string = """SELECT * FROM t WHERE _id IN ($1)""" % join(qs, ",")
let query = SqlQuery(query_string)
for row in db.fastRows(query, ids):
echo row
Is there a better way to construct a select ... in query in nim? Ideally one with just one ? in the SqlQuery.
(For what it's worth, the current behavior is similar to other languages I've used)
you could do the replacement manually, here's one way using strformat and map
import strformat,db_sqlite,sequtils,strutils
#assuming ids is a seq[string] here
let query = sql(&"SELECT * FROM t WHERE _id IN ({ids.map(dbQuote).join(\",\")})")
for row in db.fastRows(query):
echo row

psql query not returning proper results?

var searchValue = 'shahid';
var query = ("select * from students where name ilike '%"+searchValue+"%'");
This is my psql query, but it is not returning any values. So that I just console the query to know the execution.
The query is executing as:
select * from students where name ilike 'hahid%'
When I capitalize the first letter of search value (Shahid), it's executing perfectly.
If you want to pass in the upper case you should convert the variable searchValue
eg.
var newSearchValue = (select initcatp(searchValue)) ;
This will convert 'shahid' to 'Shahid' Then use this in your query variable.
This, lacking a '%' on the left hand side, will only match thing that start with hahid
select * from students where name ilike 'hahid%'
It's not the same as this
select * from students where name ilike 'Shahid%'
which will match only things that start with Shahid. Now if you want something that will match anything with hahid then you want
select * from students where name ilike '%hahid%'
BTW, your example is extremely insecure if searchValue comes from I/O (user, file, network etc).

"non-integer constant in ORDER BY" when using pg-promise with named parameters

I am trying to write a simple query using the pgp-promise library. My original implementation looks like:
var bar = function(orderBy){
var qs = 'select * from mytable order by ${orderBy};';
return db.many(qs,{orderBy:orderBy});
}
...
bar('id').then(...)
But this gives an error of non-integer constant in ORDER BY
I have also tried adding quotes aroung ${orderBy} and adding double quotes to the orderBy paramater to no avail. I have a working solution by doing var qs = 'select * from mytable order by "' + orderBy + '";' though it should be obvious why I don't want code like that in the project.
My question: Is there a way to get pg-promise to build a query with an order by clause that isn't vulnerable to sql injection?
Is there a way to get pg-promise to build a query with an order by clause that isn't vulnerable to sql injection?
The value for ORDER BY clause is an SQL name, and it is to be formatted using SQL Names:
const bar = function(orderBy) {
const qs = 'select * from mytable order by ${orderBy:name}';
return db.many(qs, {orderBy});
}
whereas :raw / ^ is injecting raw text, which is vulnerable to SQL injections when it comes from outside, and to be used only for strings that have been created and pre-formatted inside the server.

Resources