Perl Mojolicious use query with placeholder to prevent SQL injection. But the problem is, sometimes I want to see what's the query look like.
Is there a way to print the query with all placeholders replaced with the real values?
I know I can do a replace by myself. But I have to do it every time I want to debug the SQL. It's so cumbersome. If mojolicious has a way like $c->mysql->output_last_sql(), it'll be amazing.
my $sql=q|
SELECT
count(*) cnt
FROM
my_table
WHERE
id= ?
|;
# I know I can do below by myself
print q1|
SELECT
count(*) cnt
FROM
my_table
WHERE
id= $c->param('id')
|;
my $query=$c->mysql->db->query($sql, $c->param('id'));
# how can I print the real SQL with all placeholders replaced?
print $query->hash()->{cnt};
I checked the document of Mojolicious but didn't find anything useful.
https://docs.mojolicious.org/Mojo/Pg/Database
The advantage of query parameters is that they are not simply string-replacements into the SQL query. If they were, they would still cause a risk of SQL injection. The way parameters work is that they are never replaced in your query until after the query is prepared. Parsing occurs during the prepare step, so if parameter values are not combined with the query until after parsing, then there's no way for the values to cause mischief with the SQL syntax.
That means you can't get the SQL combined with its parameters in the client.
The only workaround is to use the query log on the MySQL Server. I give an example here: Getting raw SQL query string from PDO prepared statements. That's about PHP, not Perl, but it works the same regardless of which language you use.
(With exceptions only for client connectors that create fake prepared statements, and actually do interpolate parameters into the SQL string, then send it to the MySQL Server. For example, Python's connector does this by default, for example, but you can optionally make even Python use true prepared statements.)
Related
I have a file that runs a SQL query:
SELECT * FROM items WHERE name LIKE "%<String Passed to It>%"
I am trying to test for basic web security here. How can I break this query to drop the items table, without using spaces or semi-colons
Try setting the value of the to be:
'\gDROP TABLE items\g--
You will need to escape that apostrophe.
Making you're query look like this:
SELECT * FROM items WHERE name LIKE '%'\gDROP TABLE items\g--%'
In mySQL \g is equivalent to a semi-colon. However, I'm not sure if spacing is required as I do not currently have a local installation of mySQL set up, and I do not know exactly what language and framework you're using to execute that query.
However, the other comments are right that using a prepared statement and parameters rather than building the SQL string in code is the way to go in trying to prevent SQL Injection attacks.
See here
Is it possible to completely disable UNION SELECT queries thru a configuration option?
Besides cleaning the entry params, I would like to avoid the use of UNION since with its help it is pretty easy to implement SQL injection of the form:
SELECT * FROM users where username = '1' OR 1=1
UNION
SELECT * FROM users -- ' AND password='something'
To answer your question plainly:
No, there is no option in MySQL to selectively disable UNION.
SQL_MODE can be used to change the meaning of syntax in a couple of very specific cases, like use of double-quotes and the || operator. See https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html
But in general, you cannot disable SQL keywords or clauses, unless you whip out your code editor and modify MySQL's SQL parser code, and then build a custom instance of MySQL.
I agree with the other commenters that it isn't necessary to disable UNION if you write application code with the known practices to avoid SQL injection vulnerabilities.
Even it's easy to do SI with plain SELECT query as well and it has nothing to do with UNION at all. Moreover, as far I know, NO there is no such option to disable UNION unless you are probably taken the open source code and modified it yourself.
The best [proven] solution to avoid SQL Injection is to avoid assembling SQL statements by concatenating strings with values coming from the end user interface (or other unsafe source).
It's safer to use "Prepared Statements" and apply parameters to it, instead of concatenating those parameters.
There's still room for concatenating SQL chunks into a statements, primarily when using Dynamic SQL, but I think this is out of the scope of your question. In simple words: do not concatenate values as strings when producing a SQL statement.
Questions
What is/are the most cheapest SQL-Statment(s) (in terms of Processing Overhead/CPU Cycles).
Are there (this will most likely be DB-Client specific) any Statments that are evaluated directly by the client and even do not go to the database server?
The result doesn't matter, if an empty statement (which produces an SQL Error) is the cheapest OK, then this is good too. But I am more interested in non Error Responses.
Background:
I have an application that queries a lot of data from the DB. However I do not require this data. Sadly, I have no possibility to skip this query. But I have the possibility to change the SQL Query itself. So I am trying to find the cheapst SQL Statement to use, ideally it should not even go to the SQL Server and the SQL-Client Library should answer it. I will be using MySQL.
UPDATES (on comments):
Yes, it can be a No-Operation. It must be something I can pass as a regular SQL String to the mysql client library. Whatever that string could be, is the question. The goal is, that this Query then somehowreturns nothing, using the least Resources on the SQL Server as possible. But in idealcase the client itself will realize that this query doesnt even have to go to the server, like a version Check of the client library (OK I know this is no standard SQL then but maybe there is something I do not know about, a statement that will be "short circuited/answered" on the client itself).
Thanks very much!
DO 0
DO executes the expressions but does not return any results. In most respects, DO is shorthand for SELECT expr, ..., but has the advantage that it is slightly faster when you do not care about the result.
I have a website using mySQL database and I want to do common tasks like add users, modify their info, etc. I can do it perfectly with regular queries. Im using prepared statements to increment security.
Should I use stored procedures to increment the security or the results will be the same? I though that may be using stored procedures I can restrict the direct interaction that a possible attacker could have with the real query. I'm wrong?
I guess it would depend on what language youre using. Using a prepared statement with a sql string that contains all of the sql to be executed, or using a prepared statement with a sql string that executes a stored procedure are going to be about equivalent in most languages. The language should take care of the security around the prepared statement. C# for example will validate the input, so sql injection vulnerabilities are greatly reduced unless your prepared statement is written so poorly that feeding it bad (but expected, ie, 1 vs 0) variables will dramatically change the result set. Other languages may not provide the same level of validation though, so there may be an advantage depending on exactly what your stored proc looks like.
Using a stored procedure is better for maintainability, but there are not many scenarios where its going to provide any sort of change in security level, assuming the program is properly designed to begin with. The only example i can think of off the top of my head would be a stored procedure that takes raw sql strings from user input, and then executes that sql against the db. This is actually less secure than using a prepared statement unless you went to great lengths to validate the acceptable input, in which case you better have a really good reason for using such a stored proc in the first place.
Basically, what I'm saying boils down to the fact that you're going to need to read the documentation for your language about prepared statements, and determine what vulnerabilities, if any, using prepared statements may have, and whether or not those can be eliminated in your specific scenario by switching to a prepared statement that calls out a stored procedure instead of executing a sql query directly.
The results would be the same (assuming that you set your stored procedure up right).
there appears to be a pretty good write up on it here. Though I would never suggest you try to escape user input yourself. (They mention this as option 3)
I want to store IP addresses (v4 and v6) in my rails application. I have installed an extension to MySQL adds functions to convert ip strings to binary which will allow me to query by IP range easily.
I can use unescaped sql statements for SELECT type queries, thats easy.
The hard part is that I also need a way to overwrite the way the field is escaped for insert/update statements.
This ActiveRecord statement
new_ip = Ip.new
new_ip.start = '1.2.3.4'
new_ip.save
Should generate the following SQL statement
INSERT INTO ips(start) VALUES(inet6_pton('1.2.3.4'));
Is there a way to do this? I tried many things, including overriding ActiveRecord::Base#arel_attributes_values, without luck : the generated sql is always converted to binary (if that matters, my column is a MySQL VARBINARY(16)).
ActiveRecord::Base.connection.execute("INSERT INTO ips(start) VALUES(inet6_pton('1.2.3.4'))")