I'm accepting a GET query parameter which will be used as piece of a search string.
If I have this:
x = request.args['x']
MyTable.query.filter(MyTable.myCol.ilike(x)).one()
Am I vulnerable to a SQL injection attack?
EDIT - I am using Postgres and SQLAlchemy 1.0 I think.
According to https://stackoverflow.com/a/31949750/3359014,
MyTable.query.filter(MyTable.myCol.ilike(x)).one() is not considered a raw sql and the underlying db-api will escape x.
Related
This comment made me worried that the way I am searching my databases may result in an injection attack. Bellow is the query I'm currently using:
return db.query("SELECT * FROM customers
WHERE ( num LIKE ? AND name LIKE ? )",
[customer.num + "%", customer.name + "%"], callback)
Should I be adding the % symbol in my call to the API, or how would this be properly implemented?
The comment you're referring to uses string concatenation, whereas you are using prepared statements
This means that the intention is that the db.query function should be applying filtering and escaping to the inputs you provide, and hopefully they would be fairly extensive, and protecting you well.
It doesn't mean that you're immune to SQLI attacks, because there are just so many of them, but you have followed good practices in using prepared statements.
To check and/or improve your security against SQLI attacks, you could:
Audit the database connector library you are using to see whether it has known issues. npm audit is your friend here
Consider using another system for the queries, like an ORM like Sequelize, which tend to use querying systems even further separated from the actual SQL.
No, you misunderstood it. The problem comes when you concatenate a string with the SQL Query . e.g db.query("SELECT * FROM customers WHERE ( num LIKE "+ var +"AND name LIKE "+ var2+" )". You are safe here because you are using placeholders that will escape them.
I want to create SQL queries in a language like Java or C#. Everybody knowns that you must not do this:
sql = "SELECT * FROM T WHERE A='" + someString + "'"
Because this allows code injection, for example with:
someString = "xxx';DROP TABLE T;DECLARE #A CHAR(3) ='xxx"
Everybody knowns you must use proper SQL parameters provided by the standard apis available in most languages.
But for some reason that is too complex to explain (please assume my reasons are good), I can't or don't want to use proper parameters and need to stick to the dangerous method of formatting the string myself.
My question is simple. Is the following safe:
sql = "SELECT * FROM T WHERE A='" + someString.Replace("'","''") + "'"
If you think this depends to on the RDBMS, please stick to MySQL.
Not even by a long shot.
I'm not even going to try to create some viable modifications or recommendations because it is a lost case. Any of them would just make you fall into the false sense of security.
Let me just give you a small list of links to introduce yourself:
SQL Injection Cheat Sheet
... check 'If statements' or 'Strings without Quotes' parts
Bobby tables
And various SO questions:
What's the best method for sanitizing user input with PHP?
Which characters are actually capable of causing SQL injection in mysql
Does eliminating dangerous characters avoid SQL-injection?
How can I prevent SQL injection in PHP?
Does this code prevent SQL injection?
What characters have to be escaped to prevent (My)SQL injections?
Do htmlspecialchars and mysql_real_escape_string keep my PHP code safe from injection?
First of all, it's bad practice.
It will be bad in two condition I considered:
if the field is not VARCAHR, it is INT? It won't work.
if input is "it's ok", it will be "it"s ok", it will be tedious for converting if it is username should be presented.
It will be more problems with your method(But I haven't considered). The best way is using parameters.
I've hear that preparing MySQL queries prevents injection. I'm working with nodejs, so I've found MySql Preparing Queries. According to the documentation,
You can use mysql.format to prepare a query with multiple insertion
points, utilizing the proper escaping for ids and values.
Does that mean that I can put unescaped things in userId and get an escaped mysql request called sql?
The code is:
var sql = "SELECT * FROM ?? WHERE ?? = ?";
var inserts = ['users', 'id', userId];
sql = mysql.format(sql, inserts);
It's safe.
Escaping is performed by the sqlstring module, you can take a look at its source code for additional info, it's rather small.
You should always escape your values, either by using the ? placeholders or calling escape directly. However using the placeholders is more recommended because it protects you from scenarios where you might forget to do the manual escaping.
I'm using a MySql database and was trying to find a MySQL alternative to tedious.js (a SQL server parameterised query builder).I'm using Node.js for my backend.
I read that the .raw() command from knex.js is susceptible to sql injection, if not used with bindings.
But are the other commands and knex.js as a whole safe to use to prevent sql injection? Or am I barking up the wrong tree?
Read carefully from knex documentation how to pass values to knex raw (http://knexjs.org/#Raw).
If you are passing values as parameter binding to raw like:
knex.raw('select * from foo where id = ?', [1])
In that case parameters and query string are passed separately to database driver protecting query from SQL injection.
Other query builder methods always uses binding format internally so they are safe too.
To see how certain query is passed to database driver one can do:
knex('foo').where('id', 1).toSQL().toNative()
Which will output SQL string and bindings that are given to driver for running the query (https://runkit.com/embed/2yhqebv6pte6).
Biggest mistake that one can do with knex raw queries is to use javascript template string and interpolate variables directly to SQL string format like:
knex.raw(`select * from foo where id = ${id}`) // NEVER DO THIS
One thing to note is that knex table/identifier names cannot be passed as bindings to driver, so with those one should be extra careful to not read table / column names from user and use them without properly validating them first.
Edit:
By saying that identifier names cannot be passed as bindings I mean that when one is using ?? knex -binding for identifier name, that will be rendered as part of SQL string when passed to the database driver.
I use jsp and sql and I want to query a table using a variable that I have already declared (entity)
here is my query:
..
String **entite**="informatique";
entite="informatique"
...
rs = st.executeQuery ("select * from User where User.id_e= &**entite** ");
entite is a variable
my question is: how to use a variable in a where clause
My prefered solution - Use a PreparedStatement with ? and setString(...) for parameters.
See further details here:
http://download.oracle.com/javase/tutorial/jdbc/basics/prepared.html
The best and safe way is to use PreparedStatement to bind variables to the query.
For example see (hope the link does not break in a second)
http://download.oracle.com/javase/1.4.2/docs/api/java/sql/PreparedStatement.html
You can use escaping techniques, however they are error prone and quite too often lead to SQL injection attacks and/or database corruption.