sql injection with union - mysql

So I am doing a little sql injection challenge because I wanted to learn about it and I have a question. I type 'hi' into the HTML form and I get this back as a response
Error: The following error occurred: [near "hi": syntax error]
Query: SELECT * FROM personnel WHERE name=''hi''
The information we need to get is located in a table called users. I was looking at sql and I see here the union operator which combines the results of 2+ select statements.
So, I try this as input: 1 UNION SELECT * FROM users and I get nothing back so it looks like it searched from that input as a name in table personnel. I thought this would work because the query would look like: SELECT * FROM personnel WHERE name=1 UNION SELECT * FROM users. Am I not understanding how the union operator works or is something else wrong in my input

This one:
set #hi = "'hi'";
select #hi;
SELECT * FROM personnel WHERE name="'hi'"
Simulate:
insert into personnel (`name`) values("'hi'");
insert into personnel (`name`) values("'hello'");
select * from personnel where `name` != "'hi'"

-- you can't use a double '' in sql query
Query: SELECT * FROM personnel WHERE name='hi'

Probably the SQL is invalid because personnel and users have different shape. You need to inject something that is identical to the initial select.
Also your entire problem goes away if you have parameterised queries instead of concatenating into SQL.

Related

SQL Query when where clause could be empty or contain value

I would like a select query that would be able to select a value that may or may not be present in the where clause. Schema:
----------------------------------
studentid|firstname|lastname|major
My select clause would be
select * from students where studentid?={param} AND firstname?={param} AND lastname?={param} AND major?={param};
I put a question mark because I mean to say I could pass a value in the where clause or I might not. It could be
select * from students where studentid?=34344 AND firstname?="john" AND lastname?="smith" AND major?="";
select * from students where studentid?=34344 AND firstname?="john" AND lastname?="smith" AND major?="english";
Is there a way to do this easily without a stored procedure?
You can do that by using variables and checking null like this:
Declare #StudentId nvarchar(100) --can be null or evaluated
select * from students
where (#StudentId is null or studnetId= #StudentId) AND -- for other properties as well
Another option is using dynamic sql and first you have to build your sql query and then execute it (I don't like it)
You can handle it in the application side if possible:
string query= "select * from students where 1=1 /*trick for adding more conditions*/"
if(numberId is not null)
query += "AND studentId= {numberId} ";
//for other conditions ...

php prepared statement multiple possible querys

I'm using prepared statement for MySQLi PHP which is all working. However, the application that I'm using this in has 108 different possible statements all very similar that can be run either without condition:
select * from table1
or with
select * from table 1 where user_level = 1)
The question that I'm asking: Is there a way that I can create the statement that covers all possibilities such as
select * from table 1 where user_level = {special input}
that will give the same outcome as
select * from table1
Otherwise I'm looking at a lot of repetition.
You would use parameter binding. See https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php.

WSO2 DAS: SPARK SQL query with UNION producing errors

The following query was attempted to be executed when performing batch analytics with WSO2 DAS using Spark SQL. Tables 'First', 'Middle' and 'Third' are required to be combined and written to table 'All_three'.
INSERT OVERWRITE TABLE All_three
SELECT SYMBOL, VOLUME FROM First
UNION
SELECT SYMBOL, VOLUME FROM Middle
UNION
SELECT SYMBOL, VOLUME FROM Third;
Following error is displayed on WSO2 DAS when this query is executed:
ERROR: [1.79] failure: ``limit'' expected but `union' found INSERT OVERWRITE TABLE X1234_All_three SELECT SYMBOL, VOLUME FROM X1234_First UNION SELECT SYMBOL, VOLUME FROM X1234_Middle UNION SELECT SYMBOL, VOLUME FROM X1234_Third ^
Using LIMIT with UNION is not a necessity to the best of my knowledge. Enclosing the SELECT queries in parentheses too was attempted which didn't work. What am I doing wrong here? Thank you in advance!
I had the same issue.
Please make sure you had an whitespace in end of each row.
The reason is it is not considering \n as a whitespace like SSMS or other query editors.
So it reads your query without whitespace.
Hence, it read like SELECT * FROM FirstUNION not like SELECT * FROM First UNION
My issue was resolved and I hope this helps for you too.
There exists a problem with the query you mentioned here. Please change the query as below.
INSERT OVERWRITE TABLE All_three
select * from (
SELECT SYMBOL, VOLUME FROM First
UNION
SELECT SYMBOL, VOLUME FROM Middle
UNION
SELECT SYMBOL, VOLUME FROM Third
) temp;
Actually what we do here is, wrapping the union result into temporary data element called temp and select everything from there. Spark-SQL parser only takes single select element in the insert queries, and at the end of a select query it expects a limit (if available). therefore, you need to wrap the subsequent select statements into one select element. Hope this resolves your issue.

MySQL select all from list where value not in table

I cannot create a virtual table for this. Basically what I have, is a list of values:
'Succinylcholine','Thiamine','Trandate','Tridol Drip'
I want to know which of those values is not present in table1 and display them. Is this possible? I have tried using left joins and creating a variable with the list which I can compare to the table, but it returns the wrong results.
This is one of the things I have tried:
SET #list="'Amiodarone','Ammonia Inhalents','Aspirin';
SELECT #list FROM table1 where #list not in (
SELECT Description
FROM table1
);
With only narrow exceptions, you need to have data in table form to be able to obtain those data in your result set. This is the essential problem that all attempts at a solution to this problem run into, given that you cannot create a temporary table. If indeed you can provide the input in any form or format (per your comment), then you can provide it in the form of a subquery:
(
SELECT 'Amiodarone' AS description
UNION ALL
SELECT 'Ammonia Inhalents'
UNION ALL
SELECT 'Aspirin'
)
(Note that that exercises the biggest of the exceptions I noted: you can select scalars directly, without a base table. If you like, you can express that explicitly -- in MySQL and Oracle, at least -- by selecting FROM DUAL.)
In that case, this should work for you:
SELECT
a.description
FROM
(
SELECT 'Amiodarone' AS description
UNION ALL
SELECT 'Ammonia Inhalents'
UNION ALL
SELECT 'Aspirin'
) a
LEFT JOIN table1
ON a.description = table1.description
WHERE table1.description IS NULL
That won't work. the variable's contents will be treated as a monolithic string - one solid block of letters, not 3 separate comma-separated values. The query will be parsed/executed as:
SELECT ... WHERE "'Amio.....rin'" IN (x,y,z,...)
^--------------^--- string
Plus, since you're just doing a sub-select on the very same table, there's no point in this kind of a construct. You could try mysql find_in_set() function:
SELECT #list
FROM table1
WHERE FIND_IN_SET(Description, #list) <> ''

AS not working with COUNT(*) and UNION

So I have joined 3 queries together using UNIONs and want to count the number of lines in the result, but it's a bit weird. It actually works, and gives the correct answer, but it doesn't assign the "AS" part correctly.
SELECT COUNT(*) FROM (
(Long Select Statement)
UNION
(AnotherLong Select Statement)
UNION
(Even Longer Select Statement)
)
AS NoOfTweets";
The outcome is correct, but instead of assigning it to "NoOfTweets" it assigns it to "Count(*)". If I remove the "AS NoOfTweets" it stops working. If I remove some brackets it stops working. I'm running low on ideas after a long day! I can post the whole code if needs be but would rather not as it's quite long and I think that bit works.
Thanks in advance, Jack.
Edit: Fixed with:
SELECT COUNT(*) NoOfTweets FROM (
(Long Select Statement)
UNION
(AnotherLong Select Statement)
UNION
(Even Longer Select Statement)
)
AS NoOfTweets";
Thanks guys :)
You aren't putting it in the correct location. The beginning of your query should look like this:
SELECT COUNT(*) AS NoOfTweets
More on Column Alias
SELECT COUNT(*) NoOfTweets FROM
(Long Select Statement)
UNION
(AnotherLong Select Statement)
UNION
(Even Longer Select Statement)
or
SELECT COUNT(*) AS NoOfTweets FROM
(Long Select Statement)
UNION
(AnotherLong Select Statement)
UNION
(Even Longer Select Statement)
You have to use AS exactly after the item you are counting:
SELECT COUNT(*) AS `NoOfTweets`
FROM ( ... )
Also be careful with the " you have near the end. Or maybe it comes from a longer string.
The error is Every derived table must have its own alias which is something I didn't know, so thanks for the education :)
http://sqlfiddle.com/#!9/d30f4/4
Nice of MySQL to give an explanation - I tried with MS SQL on SQLFiddle and just got Incorrect syntax near ')'. which isn't so helpful!
So, your 'NoOfTweets' is the name given to the results column, and also to the 'derived table' which is required by the SQL engine but could be a different name ... it's not returned in the results. The point of naming a derived table is in case you wish to JOIN to other tables and reference the fields in the joins.