Disable MySQL's UNION SELECT query - mysql

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.

Related

Can mojolicious output the prepared sql query?

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.)

How to declare a variable within the same statement in MySQL?

How do I create variables in MySQL that I can refer to in the same statement?
Does this work for UPDATE and INSERT statements as well?
I asked this because I got a lot of SQL text files where I execute single commands using Ctrl-Enter from MySQL-Workbench. If it would be multiple statements I would have to select the commands to execute before pressing Ctrl-Enter. This is more complex and error-prone.
Before someone asks: this is a private database with single user and I use these scripts to modify data directly where editing through the GUI would take ages.
I just decided that I should wrap more complex code with a java program. This was a good decision. Still I need the solution to this question for less complex problems where I don't want to write java code.
It's not clear why you need to do this in the same statement. It's easy to run two statements, and it makes the code much easier to write and easier to understand. You should always consider how the developer who succeeds you working on your code is going to understand and maintain it.
SET #variable = 'Value';
SELECT ... FROM your_table WHERE a_column = #variable;
If you do need to do it in one statement, I'd do it this way:
SELECT ... FROM your_table
CROSS JOIN (SELECT #variable := 'Value') AS _init
WHERE a_column = #variable;
By doing this in a derived-table, it only does the assignment once. If you do it in the select-list as you showed in your solution, it does the assignment as many times as the number of rows returned by the inner query. This is not a big deal if the assignment is for a constant value, but if your variable is assigned the result of a costly expression, it will be slow.
Well I wasn't able to find a solution on the web. But it turned out to be... fairly straightforward.
Just create a statement that wraps your statement:
select *, #variable:='Value' from (
select * from your_table inner where #variable=inner.column
) as outer

MySQL injection commands

What are ALL THE MySQL commands that can be used to do an injection in a code?
I have disabled UNION and CONCAT.
I have a very basic application so no need for any complex queries so what else can I disable to make sure injections are a non issue?
Yes I have sanitized all variables as far as I know. The issues is it is a project with multiple parties and I have noticed some sloppy work in some libraries I have been handed to work with.
I was thinking on getting all the post variables sanitizing them an putting them back but that would be quite a complex task due to the complex multidimensional nature of some post variables.
Injection is possible with just about any type of SQL statement.
The only safe method of avoiding injections is to use prepared statements and bind data to query parameters.
You cannot simply disable keywords, look at this example:
SELECT id FROM user WHERE name='*' AND password = 'whatever' OR password <> ''
You need to escape the user input, before adding it to the SQL statement (e.g. mysqli_real_escape_string()). Even better would be to use prepared statements with PDO.
[…] to make sure injections are a non issue?
That cannot be done. If SQL injections are possible, then they are an issue.

Can I obfuscate the SQL code in MySQL?

I'm trying to find some way to obfuscate SQL code in MySQL.
In the Oracle databases exists the "wrap" funcionality, but I didn't found some similar. Some ideas?
The final goal is that the client has some difficuties to understand the code.
I think MySQL do not have the ability to obfuscate the code. You can encapsulate the whole SQL query code by creating a STORED PROCEDURE, although not encapsulated but at least your whole SQL query is not shown when used inside your code (PHP, .Net, and the like...).
MySQL does not have any obfuscation abilities - you could write some code that would be confusing to read by having some other table with defined values that you could use IF statements against to make your code difficult to read...
SELECT co1, co2, IF(3 > 18, co3, '') AS co3 FROM table INNER JOIN...
etc... or using COUNTs as parameters in conditional statements is as best as you're going to get (obviously performance may become an issue depending on how "obfuscated").

Why doesn't SQL LIKE work in Microsoft Access?

I want to my make a search-statement and query things like this
select * from table where col like '%vkvk%'
But with trial and error I've come to the conclusion that access doesn't work with LIKE or
wildcard operators. Does anybody have some other solutions because I ain't so in to access actually, so I really don't know.
Try:
select * from table where col like '*vkvk*'
Use an asterisk for the wildcard character.
If you want to use some SQL syntax that is like SQL Server, go to your Access OPTIONS and set it for "SQL 92" mode. So far as I know, this does two main things (there may be others):
allows you to use % and _ as wildcards instead of Jet SQL's * and ?.
allows you to use the non-crazy derived table syntax:
SELECT MyTable.*
FROM (SELECT * FROM SomeTable) As MyTable
...instead of the bollixed-up Jet method:
SELECT MyTable.*
FROM [SELECT * FROM SomeTable]. As MyTable
...which has problems with table and field names with spaces in them, since you have to use brackets inside the derived table definition, which breaks the Jet syntax entirely.
As I said, there may be other things it changes, but if you're a SQL Server programmer, you may find it easier to set SQL 92 mode on. On the other hand, most Access help uses Access/Jet/ACE conventions, so you may end up more confused by trying to use it.
EDIT:
Since originally posting this, I've discovered that there are problems with turning on SQL 92 mode in an existing Access application. The two I discovered were:
It changes the list of reserved words, which means that SQL that previously worked with the SQL 89 list of reserved words can break (if it uses a SQL 92 reserved word).
It can break multi-column combo boxes with a hidden first column (which is a very common UI object in Access applications). Specifically, it breaks the Autoexpend/autoselect behavior.
There may be other problems, but I discovered these accidentally when I turned on SQL 92 mode in a client project to test something for SO and forgot to turn it off when I distributed the next update. Fortunately, the problems were quickly detected, and it didn't take me too long to idenfity SQL 92 mode as the cause of the problems.
In short, I don't consider SQL 92 mode in Access to be of use to anybody at all. It's a feature aimed at people who won't be using Access interactively in the first place, seems to me.
like '%kvk%' sometimes work sometimes don't
With Access 2010 with sql server (2008) linked tables
Use '*kvk*'
I tried several "Like" syntax on one request, (I'm using VB.NET and a MS-ACCESS 2010 database), and none of them could get any other result than throwing an exception.Why? I'm not having any idea about that.
I did this workaround that could be useful on some similar cases:
Instead of
SELECT dbFieldDisplayName FROM dbTableName WHERE dbFieldSearchName Like 'A*'
I Used:
SELECT dbFieldDisplayName FROM dbTableName WHERE dbFieldSearchName >='A' AND dbFieldSearchName <'AZZZ'