Why does this SQl injection only work together with AND ''='? - sql

I'm testing some SQL stuff on sqlzoo.net/hack and I'm not getting why
' OR EXISTS(SELECT * FROM users WHERE name='jake' AND password LIKE '__w%') AND ''='
does work for the SQL injection and
' OR EXISTS(SELECT * FROM users WHERE name='jake' AND password LIKE '__w%')
not. Why is it necessary to put this last
AND ''='
?
Also i guess that these SQL injections are very 'old' and won't work. Are there newer methods and are there sites where someone can learn this?
Thanks in advance.

Because you need to close the '.
The code that checks for the password may be something like this:
"SELECT * FROM usersPassword where password = '" + TEXTINPUT + "';"
If you want to simply go in, ' OR ''=' will do the job.
The complete query will be
"SELECT * FROM usersPassword where password = '' OR ''='';"
which is an always true condition.
The example on the website does something more. It checks how the password of a certain user look like, if a certain character is present you will know by the fact that you're able to log in.
EDIT:
In your case the final query will be
"SELECT * FROM usersPassword where password = '' OR EXISTS(SELECT * FROM users WHERE name='jake' AND password LIKE '%w%') AND ''=''"
if you don't put the AND
"SELECT * FROM usersPassword where password = '' OR EXISTS(SELECT * FROM users WHERE name='jake' AND password LIKE '%w%')'" ----> which does not close !

I think it is because it will concat to the input parameter which mean that your first query will be
OR EXISTS(SELECT * FROM users WHERE name='jake' AND password LIKE '%w%') AND ''='' OR''='{somevalue}'
which always true

Related

SQL select rows case INsensitive not works my statement

I have Android app that sends to server pattern to find user by name. I want to be able to find rows where VARCHAR column is like pattern (but case INsensitive) that I send to server. Lets say we have a nickname like 'Bigboss'. The SQL statement should be able to find this row either when is passed 'Bigboss' or 'bIGBOSS' or 'biGbOsS' or 'bi' etc. Currently it works weird.
Here is my SQL statement:
SELECT *
from users_details
where upper(name) like '" + pattern + "%'
or lower(name) like '" + pattern + "%'
Help me please.
SELECT *
from users_details
where name ilike '" + pattern + "%'
see the manual :
The key word ILIKE can be used instead of LIKE to make the match
case-insensitive according to the active locale
Can you try this.
SELECT * from users_details where upper(name) like '%PATTERN%'
If you are passing pattern dynamically then like pattern.touppercase()

Passing a string variable in SQLite with GDScript

I have a question about SQLite in GDScript.
I wanted to print one query result to debug but I cannot find the way to do it.
In my code I have:
var tableName = "users"
db.query("SELECT username, email FROM " + tableName + " WHERE username=?;" + (username))
I cannot pass the username as "username", what is the correct way to do it?
I also try this:
var tableName = "users"
db.query("SELECT username, email FROM " + tableName + " WHERE username= " + username + ";")
And this:
var tableName = "users"
db.query("SELECT username, email FROM " + tableName + " WHERE username = " + 'username' + ";")
By the way, im getting the username from this:
var username = $NinePatchRect/VBoxContainer/username.get_text()
I've printed and the variable username is fine.
Thank you all!
What to do
The proper way to do this, is with prepared statements and argument bindings. You need to find a way to do that with whatever solution you are using.
If you are using this solution: 2shady4u/godot-sqlite (Which is available from the Godot Asset Library, here). Do the following:
var query = "SELECT username, email FROM " + tableName + " WHERE username=?;"
db.query_with_bindings(query, [username])
Which should use prepared statements and argument bindings behind the scenes. Source.
If you are using this solution: godot-extended-libraries/godot-sqlite (towards which the Godot Core developers contributed). Do the following:
var query = "SELECT username, email FROM " + tableName + " WHERE username=?;"
db.query_with_args(query, [username])
Which should use prepared statements and argument bindings behind the scenes. Source.
If you are using this solution: khairul169/gdsqlite-native (which is an older project). Do the following:
var query = "SELECT username, email FROM " + tableName + " WHERE username=?;"
db.query_with_args(query, PoolStringArray([username]))
Which should use prepared statements and argument bindings behind the scenes. Source.
If you are using another solution, please figure out how to use prepared statements with it. And if there is no way to do it, please switch to a solution that supports them, such as the ones linked above.
What NOT to do, and why
SQLite needs the strings between quotation marks.
A common way to put quotation marks in Godot is by writing your string between ' instead of ".
For example:
print('Hello "World"')
Should print Hello "World".
Alternatively, you can use escape sequences:
print("Hello \"World\"")
Which should also print Hello "World".
Thus, you can - please don't - make your query like this:
db.query("SELECT username, email FROM " + tableName + " WHERE username= \"" + username + "\";")
Then if the user typed:
peter
The query would be built like this (And let us say tableName is users):
SELECT username, email FROM users WHERE username= "peter";
And you would have a SQL injection vulnerability. If the user writes a quotation mark, then the rest of the string will be considered part of the query.
For example if the user writes
" or "" = "
The query will be built like this:
SELECT username, email FROM users WHERE username= "" or "" = "";
And that will return all users. And that is just an example of what they could write, because remember they would be writing SQL.
Prepared statements avoids the vulnerability. And not by string tricks, but by proper support. And without the hassle. Please use prepared statements.

Can someone clarify this SQL command

I saw this in some ASP code and didnt understand the last line, specifically all the apostrophies and quotation marks between Name= and AND. what is being appended? why do we need both?
uName = getRequestString("UserName");
uPass = getRequestString("UserPass");
sql = "SELECT * FROM Users WHERE Name ='" + uName + "' AND Pass ='" + uPass + "'"
The code is building a query that looks like this:
SELECT * FROM Users WHERE Name = 'foo' AND Pass = 'bar'
It passes in the text from the uName and uPass variables into the query string.
This is very dangerous though - it's an open door for SQL Injection.
That is very simple, you have the start of a string sentence with double quotes. Double quotes indicate the start and the end or part of a string.
for example, if you have
sql ="SELECT * FROM USERS"
your sentence takes all the value; if you have:
sql = "SELCT * FROM USERS"
whereSentence = " WHERE id = 1"
wholeSql = sql + whereSentence
with the + (plus symbol) you are concatening all the string.
With the simple quotes you are adding the simple quote in the string and concatening the other parts of the sentence.
For example if
uName = 'John' and uPass = 'McDonals'
sql = "SELECT * FROM Users WHERE Name ='" + uName + "' AND Pass ='" + uPass + "'"
your final sentence should be
SELECT * FROM Users WHERE Name = 'John' And Pass = 'McDonals'.
Is a simple way to say that the name is John McDonals as String, but the parameters are variables, depending the request
The first quotation (') mark is in the SQL lateron. The second quotation mark ("), marks the String literal for ASP.
After parsing, the query will be something like:
SELECT * FROM Users WHERE Name ='name' AND Pass ='password'
Which is why you need the ', because your intention is to give the DBMS a string.
This code is building a complete string for the SQL request. Presumably, this is connected to a webpage that asks for the username and password to be submitted in a block.
The uName and uPass strings will be set to something like this:
uName = "John";
uPass = "qwerty";
When the sql string gets created, the SQL query needs to put quotes around the string values, so the final query will look like this:
sql = "SELECT * FROM Users WHERE Name ='John' AND Pass ='qwerty'"
If you wrote:
SELECT x from y where y.name = martin
you would get an error. You need apostrophes to denote a string, like so:
SELECT x from y where y.name = 'martin'
Quotes are because someone appends a variable to a string, then appends another string and first character of that string, the apostrophe, is a closing apostrophe after my martin example.
Don't do that though, I mean don't append variables to strings, unless you know what you are doing. Use parameterized queries.

SQL Server Compact Edition ISNULL(sth, ' ') returns a boolean value?

I have an Accounts table with columns name, password and email. They are all type nvarchar.
I wrote a query like
SELECT name, password, ISNULL(email, 'eeee')
FROM Accounts
WHERE name = '" + textBox1.Text + "' AND password ='" + textBox2.Text + "'"
I read the email as reader.getString(2) since it is nvarchar.
As I read from the internet, if email is NULL, then it should return eeee. But it says System.boolean can not be translated to System.String.
How can I correct this? Why does it return a boolean value?
According this ISNULL is not implemented in SQL Server CE. I would expect to see a syntax error raised, however.
Workaround: you can use CASE WHEN email IS NULL THEN 'eeee' ELSE email END or COALESCE. Preferably the latter.
Also use parameterised queries. If you don't know why you should, learn.

Getting "The column name xxx is not valid" exception when trying to combine columns

I am trying to combine two columns in SQL query but getting the following exception in java.sql.ResultSet's FindColumn method:
JdbcSqlException: The column name
FullName is not valid. Column:
'FullName'
Here is my SQL query
SELECT U.FirstName + ' ' + U.LastName AS FullName FROM User as U
Anyone?
Please note that query runs fine when I run it directly in SQL Server management studio. Also, this query is part of a big query that's why U as alias.
When you put "AS FullName", Fullname is a label now. JDBC gets data by "column name" or "field name". You have to change your code (I dont know your prog. language) accordingly.
You might try putting parentheses around the string concatenation, as in
SELECT (U.FirstName + ' ' + U.LastName) AS FullName FROM User U
Share and enjoy.
Sorry I am answering this late. I am sure someone will need the answer. I have had the same problem and whereas I do not know exactly why and what causes it, I have found a way to fix it (at least for my case).
jahanzeb farooq did not show his code but if you had declared the PreparedStatement and ResultSet variables variables outside the current method and used them in other queries then try declaring them anew inside the current method, that is
PreparedStatement pst=conn.prepareStetement(sql);
ResultSet rs=pst.executeQuery();
The problem will be sorted (or at least fixed)
String sql = "SELECT U.FirstName + ' ' + U.LastName AS FullName FROM User U ";
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
if (rs.next()) {
String fullname = rs.getString("FullName");
jtextfiel.setText(fullname);
//////or - short
jtextfiel.setText(rs.getString("FullName"));
}