SQL Injection within a stored procedure? - php

I've found somewhere in the code where a string isn't being escaped properly. I've been trying to see if it is exploitable (don't worry, I'll end up escaping it or using prepared statements anyway, this is just for a learning experience).
This is using mysqli->query() function;
The Query is generated in PHP like so:
$Query = "CALL some_proc(".$_SomeID.",'".$_UnescapedString."')";
By inputting $_UnescapedString as test'); DROP TABLE SomeTable; -- I got the query:
CALL some_proc(1, 'test'); DROP TABLE SomeTable; -- ')
This query was successfully run but it seems that it didn't run the second query. I tested this by putting invalid SQL in the second query and got no errors. I assume this means mysqli is smart enough to only execute a single query?
Now my question is, can I somehow inject SQL into the stored procedure itself? Here is the procedure:
BEGIN
SELECT COUNT(*) AS SomeCount
FROM DataTable
WHERE DataTable.SomeID = _SomeID
AND DataTable.SomeValue LIKE CONCAT('%',_UnescapedString,'%');
END
I've tried various SQL such as test','%')-- to see if the query would carry on as normal, but it only changes the stored procedure call, i.e:
CALL some_proc(1, 'test', '%')--');
Is there anyway to get a DROP TABLE command into _UnescapedString?

Disclaimer, I use SQL Server and not mySQL, but assuming the behavior with regards to parameters in stored procedures is the same, and also assuming that _UnescapedString is an input parameter, putting DROP TABLE in the parameter would look like this:
SELECT COUNT(*) AS SomeValue
FROM DataTable
WHERE DataTable.SomeID = _SomeID
AND DataTable.SomeValue LIKE '%DROP TABLE%');
With regards to the query:
CALL some_proc(1, 'test'); DROP TABLE SomeTable; -- ')
Maybe the DROP TABLE command did not execute due to the user account under which you are running having insufficient permissions to execute DDL statements?
Restricting the permissions of the user account being used to access the database from the web server is a way to limit the damage that an SQL Injection attack could cause. However, it won't stop them.

Related

How to execute two sql queries in php?

I am trying to execute this code in a php page to store some data on my database.
The thing is that I want to Insert data, but due to a foreign key constraint it is impossible. So, in my php code I want to execute two sql queries. The first one to disable foreign key checks and the second one to insert the data.
When I try it in phpmyadmin it works. But manually. I would like to put it on php code.
This is my code. The parameter $conexion is the one that executes my sql queries.
Any ideas?
$sql = "SET foreign_key_checks=0";
$sql. = "INSERT INTO routes (title, distance, subtitle) VALUES ('".$_POST['title']."','".$_POST['distance']."', '".$_POST['subtitle']."');";
$conexion->multi_query($sql);
Try to avoid using multi_query. Sending a small query to the MySQL server doesn't really affect performance and does prevent kind of limit the effect of something like SQL injection.
In your case there's no need for multi_query. If you send two queries in a script, both go over on the same connection. The SET query affect the current connection.
// Protect against SQL injection
$title = $conexion->escape_string($_POST['title']);
$distance = $conexion->escape_string($_POST['distance']);
$subtitle = $conexion->escape_string($_POST['subtitle']);
// Execute queries
$conexion->query("SET forgeign_key_checks=0");
$conexion->query("INSERT INTO routes (title, distance, subtitle) VALUES ('$tittle', '$distance', '$subtitle')");
Apart from the comment above, you need a semi-colon between your sql statements
multi_query - Executes one or multiple queries which are concatenated by a semicolon.

Security and PDO with PHP when dealing with databases. Am I understanding this corectly?

I'm very new to PHP and programming in general. I've come across an article about security, although not an issue yet in my case, I'm sure it will come up in the future at some point.
The article in question was about database input.
I'm using PDO most of the time while dealing with databases, however I'm confused about some parts. Perhaps someone can shed some light on a few things.
As I understand it, prepared statements in PDO for example:
SELECT <column> FROM <table name> WHERE <something>
Doesn't get execute right away(well, obviously) but only when execute(); is called. And gets interpreted as is.
So having something like
"SELECT <column> FROM <table name> WHERE" . <userinput> OR 1=1;
Lets say userinput is the username
And
<userinput> OR 1=1
is a user input variable via a form or whatever, will get interpreted exactly like that, meaning the username will be
userinput OR 1=1
And obviously no username OR 1=1 will exist in the database so an error will be returned.
That this mean that PDO is safe(a strong word, I know) from things like SQL injection? Or other 'hacking' methods?
What can I use/do to sanitize user input in general?
Yes it is safe, you can look at it as sandbox, if you have SQL like SELECT FROM books, it guaranties that input from user will not get out of boundaries (like modifying sql query), so it is safe from 1st order injection, but not from 2nd.
What i mean? Well PDO PREPARED statements(because you can use pdo without preparing statements in php) guaranties that you sql query is safe, but it doesn't filters the actual value.
Consider example: suppose we get some value from the form, the value will be 1); DROP TABLE books and we will save it in our database using our prepared statement INSERT INTO books VALUES(<value1>, ...),so the query will be executed successfully, value 1); DROP TABLE books will be saved in our database, but evil code will no be executed, no drop value. But if you then use our stored value in standard query, not prepared one. You will get hurt. But if you everywhere use PDO prepared statement your are safe. But i advice to filter values anyway.
Make use of Prepared Statements on PDO and you can stop worrying about SQL Injection.
I am sorry as this is the simplest answer i could give for this question.
Source
EDIT :
Found this answer on SO
Statement stmt = conn.prepareStatement("INSERT INTO student VALUES(?)");
stmt.setString(1, user);
stmt.execute();
If "user" came from user input and the user input was
Robert'); DROP TABLE students; --
Then in the first instance, you'd be hosed. In the second, you'd be safe and Little Bobby Tables would be registered for your school.

How people can use this security hole?

I have browser game. There is message send form.
I didn't make real escape string function to the "message_content" variable.
There is any option, that the user could make after the insert of the message, any update ?
I mean that the user could write a sql code in the message_content that can UPDATE values in the sql? Like update users set gold = '9999' where username = 'my_username'
THANKS ALOT....
And that it only a question. Don't worry i already made mysql_real_escape_string...
Please learn about using parametrized queries, preferably with the PDO module, to protect your web app. http://bobby-tables.com/php has examples to get you started.
The mysql_query function doesn't allow the execution of multiple statements at once. So the often mentioned example of Robert'; DROP TABLE Students; -- won’t work.
This also means that the exploitation is restricted to the statement type. So if the injection point is in an INSERT statement, the vulnerability can only be exploited to insert arbitrary values into that specific table.
However, one can still inject arbitrary data from the database into that table. And if the attacker addresses the message to himself, he will be able to read arbitrary data from the database and may also be able to read and write arbitrary files on the server.
If you don't escape the user input the following can happen:
Imagine this query:
SELECT * FROM user WHERE login='$login'
where $loginis the user's input.
Now the user insers the following content in the variable: '; DROP TABLE user; --
The following query will be executed:
SELECT * FROM user WHERE login=''; DROP TABLE user; --'
It's a very generic example, but I hope you get the idea

How does SQL-injection work and how do I protect against it [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is SQL injection?
I see a lot of php code floating around on stackoverflow and (too) little escaping of strings.
Can anyone
Explain what SQL injection is;
Explain what it can do to your server, data and code;
Give an example how to perform an SQL-injection
Give php sample code how to protect against SQL-injection
An SQL injection is a maliciously formed SQL query used to "confuse" an SQL database into giving something it shouldn't. For instance, consider the following query
"SELECT * FROM `users` WHERE `username` = '$name'";
In a normal case, this will work. If we submit 'Jack' to this, it will return all users named Jack. However, if a user enters, say "' OR 1=1", the resulting query would be
"SELECT * FROM `users` WHERE `username` = '' OR 1=1";
Since 1 always equals 1, and the combinating clause is OR, this will return true on every row, which will in turn display EVERY row to the malicious user. Using this technique, someone can view your entire database. Also consider if someone submits something like "'; DROP TABLE users";--, which results in
"SELECT * FROM `users` WHERE `username` = ''; DROP TABLE `users`";--";
Which is two queries, one which will do nothing, the second which will delete the ENTIRE users database, resulting in the loss of your data.
The best method to prevent SQL injections is to use prepared statements. With these, you send a query to the SQL database that says something like
"SELECT * FROM `users` WHERE `username` = '?'";
This lets the database know the format of the query (WHERE username equals some value), so there is no confusion when given a plain text query. Then the database knows to expect one value, and where to put it. Then you pass that value to the database which it can use to search. This is also better as the database can optimize the query for faster searching.
Read up on prepared statements, which will explain this in more detail.
I cannot resist aswell.
SQL Injection is "a code injection technique that exploits a security vulnerability occurring in the database layer of an application". In other words it's SQL code injected in as user input inside a query.
SQL Injections can manipulate data (delete, update, add ecc...) and corrupt or delete tables of the database. I'm not aware of SQL Injections manipulating scripts though.
Let's say in your PHP script you are expecting (as user input) a username and a password from the login form that are later used inside a query such as:
SELECT Id FROM Users WHERE Name = $name AND Password = $password;
The user can insert inside $name and as $password whatever he likes (for example trough an <input>). Let's imagine he adds a name such as "1 OR 1 = 1; --", the query will now look like:
SELECT Id FROM Users WHERE Name = 1 OR 1 = 1; -- AND Password = $password;
and then, after the ; I could add another query or make the script think that the username and the password actually exists.
Notice that -- AND Password = $password; is a SQL comment and will therefore be ignored.
If you are using PHP < 5 then you should look for mysql_real_escape_string() and use it to escape user inputs before embedding it inside a query.
If you are using PHP5+ you should use PDO or the mysqli extension which can prevent this problem via prepared statements.
I cannot resist posting this.
1- Sql Injection is explained better in one cartoon, than most other documents.
2- Mostly it does not do much to the server, but only to the underlying data. Consequence include delete, insert , select records, drop, create tables. (based on permissions etc..)
3- Examples.
4- Sorry I do not know PHP. But as long as you can abstract your DB layer from your View, you should be fine.
There's a lot of information out there (and elsewhere in here) about this subject, so do not take this answer as a complete list by any means and continue to research on your own...
Explain what SQL injection is;
Explain what it can do to your server, data and code;
Give an example how to perform an SQL-injection
Give php sample code how to protect against SQL-injection
SQL injection is where an attacker discovers that an input value supplied to your application is being sent directly to a database and realizes that they can craft that input to be a custom SQL command. It could be something as simple as entering a special character (such as %) into a text field and receiving a strange response.
It can do anything your database allows that command to do. For example, if your web application has DB owner permissions for the application's database then an attack can potentially drop tables or even drop the whole database. Or, with even normal application permissions, the attack can over-write data or read sensitive data (such as plain text passwords if you have those).
For example, if an application has a text field where you enter a username. If that field is open to SQL injection, an attacker can enter something like: MyName';DROP TABLE Users;-- In this example, the attack manually finishes the query with the closing single quote and semi-colon, then adds another query, then comments out anything afterward. If not protected against this, the database may run both queries.
This one I don't know updated enough information, but there's lots out there :)

Select more tables after FROM statement?

this is part of a security audition, so there is no way to "change" the query.
Basically, what I found is a flaw that allows statement manipulation, so basically it goes like:
$query = "DELETE FROM `products` WHERE `products`.`whatever` = $variable";
This is PHP, so as far as I know there is no way to execute multiple queries. Using this SQL Injection, I was able to "clear" this table by running "0 OR 1=1#".
This works just fine, but it doesn't allow me to choose more tables to delete from.
This is, in pseudocode what I want to do:
DELETE FROM `products` WHERE `products`.`whatever` = **0 OR 1=1, FROM `othertable` WHERE `othertable`.`othercolumn` = 0 OR 1=1**
Is this plausible anyhow?
If this isn't reliable, is there any other way I could use this?
You can't have multiple FROM clauses for the same DELETE statement, so you can't go about it exactly how you'd want to. If the MySQL db had 'allow multiple queries per statement' turned on, you could try to terminate the one DELETE query and then tack on another to the end, so that it'd look like this:
DELETE FROM `products` WHERE `products`.`whatever` = **0 OR 1=1; DELETE FROM `othertable` WHERE `othertable`.`othercolumn` = 0 OR 1=1**
But that's about it.
Perhaps I don't fully understand the question, but what I take away is that you're building a SQL command as a string and running that string directly against a MySQL database.
You can separate multiple commands using the command separator (usually ';'), so you could run pretty much any command you want as this comic aptly illustrates.
If your database configuration supports multiple commands (or might in the future if someone changes today's setting), you want to ensure you don't have a command separator as part of the input. See this article for advice on sanitizing your input to prevent this type of attack.
As you stated, multiple queries are not supported by the normal MySQL driver module. From the manual for mysql_query:
mysql_query() sends a unique query
(multiple queries are not supported)
to the currently active database on
the server that's associated with the
specified link_identifier .
Unfortunately for your injection efforts, DELETE syntax only supports multiple table deletes by specifying them in the FROM clause. Your injected variable is part of the WHERE, so the most damage you can do is to the single specified table.
Contrary to popular belief, you can actually run multiple MySQL statements from PHP, you just have to be using a different database driver module such as MySQLi. See MySQLi::multi_query().

Categories