Effectiveness of stripslashes against SQL Injection? [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Best way to defend against mysql injection and cross site scripting
How to include a PHP variable inside a mysql insert statement
I was wondering if anyone had came across the stripslashes statement when getting text from a password field, and if there is any way to do an SQL injection when this is the case?
i.e. in the PHP language you can get text from a password field of a website and pass it through the stripslashes statement to remove any (') so (' OR 1=1 --) becomes (OR 1=1). And makes SQL injections hard to do.

stripslashes removes slashes (\), which are escape characters, from data, not quotes ('). If anything, it's use will increase the likelihood of an SQL injection vulnerability existing.
To defend against SQL injection use prepared statements and parameterized queries.

stripslashes should not be used for password. Because it might be stripping slashes which users have input intentionally. To prevent sql injection escape according to the rdbms you are using. This will make sure you enter the exact same string user has inputted but escaped so sql injection will not occur.
For mysql use mysql_real_escape_string
Another better option is to use prepared statement. Its available in all the recent database drivers of PHP. The generic algorithm is
Prepare a statement. Usually by prepare function
Bind the values. usually by bind function.
execute the statement. Usually exec function.

Related

Is using is_string() a good defense against SQL Injection? [duplicate]

This question already has answers here:
Can I protect against SQL injection by escaping single-quote and surrounding user input with single-quotes?
(19 answers)
How can I prevent SQL injection in PHP?
(27 answers)
SQL injection that gets around mysql_real_escape_string()
(4 answers)
Closed 4 years ago.
I was trying to look for mitigation of SQL Injection against my web application based on PHP and MySQL. The first rule is to sanitize the query; Hence I am using mysql_real_escape_string() function for that
Here is what my snippet looks like
if (is_string($string)) {
return $mysqli->real_escape_string($string);
} else {
return "";
}
Here, $string would contain the user-input. After this filtering and escaping, I would use INSERT INTO query to insert into database.
This filter, will thwart any malicious user inputs like haha' , inj'' etc as is_string() will detect those string and apply real_escape_string() to escape those evil characters. The only possibility I can think an attacker can do is use a Numeric payload for SQL Injection but I don't know any Numeric payload itself has caused Injection yet so far.
So, will this filter keep away the bad guys or is it bypassable ?
EDIT:
I know Prepared statements are much better and a good coding practice while launching app in production. But for this question, I am specifically looking answer to how anyone can thwart this filter itself because it does seem strong to me!
NO
is_string() will not protect against SQL injection, a numeric payload will not be able to cause any table damage or unwanted access regardless, and string sanitization does not protect against all SQL injection.
I should give you the spiel about why prepared statements are amazing and all that, but you yourself indicated that the point of the question was to point out flaws in sanitization
Why You Should Use Prepared Statements Over Sanitization
There are situations where you want unsanitized data in your database, e.g. specially formatted text (like LaTeX, XML, or JSON), where you would need to de-sanitize data, which is not a 100% guarantee of accuracy (e.g. XML file which includes HTML entities like " would be changed to ", changing the data)
Prepared statements can be re-bound and executed in very few lines
Theoretically, if you have a query like the one below, sanitization will not save you(borrowed from here)
$iId = mysql_real_escape_string("1 OR 1=1");
$sSql = "SELECT * FROM table WHERE id = $iId";
NO: PHP delusion #1: Mysql(i)_real_escape_string prevents SQL injection
This filter, will thwart any malicious user inputs like haha' , inj''
Your ideas are anything but a protection. There is nothing "malicious" in user inputs like haha' , inj'', neither a really malicious input would contain any of these characters.
That said, any user input is a string, so you will create a mockery of the notorious magic quotes feature, much despised and long removed from the language.
Go for the prepared statements.

Could SQL injection be performed in this case? [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 9 years ago.
I have been fussing around with my PHP code and SQL statements and while I do know that one could use prepared statements when dealing with this, I still wonder how a SQL injection could be performed here.
$name = mysql_real_escape_string(htmlspecialchars($_POST["Name"]));
$age = (int) mysql_real_escape_string(htmlspecialchars($_POST["Age"]));
$amount = (int) mysql_real_escape_string($_POST["Amount"]);
$sql = "insert into nice_table set
name='{$name}',
age='{$age}',
amount='{$amount}'";
$db->sql_query($sql);
I don't know a lot about all different methods when performing a SQL injection, but all the stuff I've looked up passes just fine through this without any database errors. Would it actually be safe to use this instead of the classic prepared statements?
What would be passed right through, for example? I must be missing something, because it can't be this simple and still hold as tight as prepared statements, right?
mysql_real_escape_string ALONE can't prevent all type of SQL Injection.
Whenever you need escaping, you need it despite of "security", but just because it is required by SQL syntax. And where you don't need it, escaping won't help you even a bit.
The usage of this function is simple: when you have to use a quoted string in the query, you have to escape it's contents. Not because of some imaginary "malicious users", but merely to escape these quotes that were used to delimit a string. This is extremely simple rule, yet extremely mistaken by PHP folks.
This is just syntax related function, not security related.
Depending on this function in security matters, believing that it will "secure your database against malicious users" WILL lead you to injection.
A conclusion that you can make yourself:
No, this function is not enough.
Prepared statements is not a silver bullet too. It covers your back for only half of possible cases. See the important addition I made to the famous question for the details
mysql_ functions are deprecated. Preffer mysqli or pdo classes.
And AFAIK, it is possible to use special characters to avoid mysql_real_escape_string.
I would preffer to use prepared statements and validation. You probably wants only alfanumerics and dot to be possible inputs on name. That would help too :P
No, you are using mysql_real_escape_string() properly, so this will be safe.
For the latter two variables, you could also do
$age = intval($_POST["Age"]);
$amount = intval($_POST["Amount"]);
and that will be just as safe. Intval always returns an integer (0 on error), so it's impossible to contain any not-mysql-safe characters.

PHP Sanitizing Input With PDO Statements [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to prevent SQL injection in PHP?
I use PDO prepared statements to prevent MySQL injection, but should I be doing anything more to sanitize user input? The user will only be shown his own input and the input of others he "friends." Is there anything else I need to do to sanitize input?
I don't think that magic quotes are enabled, and I can't think of any other way a user could mess with my site, but I am new to this so I am not sure.
Thanks in advance!
If you're using prepared statements, then you shouldn't have any issue with MySQL injection.
If an application exclusively uses prepared statements, the developer
can be sure that no SQL injection will occur (however, if other
portions of the query are being built up with unescaped input, SQL
injection is still possible).
You might consider sanitizing your output, however, like only displaying certain HTML tags (if any at all), to avoid issues with someone messing with the site's layout or, worse, executing arbitrary JavaScript.

How can I prevent 2nd order SQL attacks?

I'm using PHP PDO for my queries, everywhere, but I read that in very rare cases there could still be "second order injections" where an unsafe variable is stored then executed when used in another statement.
Will prepared statements still protect against this? As long as I make sure I always use them? Or do I have to take more precautions? Am I still vulnerable to XSS attacks?
I also have a couple more questions, just out of curiosity, if you all don't mind:
Is it possible to have an SQL Injection with only alphanumeric characters, spaces, and one dash? Like select * from something where name='$some_variable'. All the examples I've seen seem to require other characters like semicolons, quotes, or double dashes.
I've read many SQL examples where the unsafe variable could be set to form another statement, eg
$foo = "foo'); INSERT INTO users (name) VALUES ('hi";
$bar = ("INSERT INTO users (name) VALUES ('$foo')");
But I just tested and mysql_query doesn't even allow multiple statements. I know you can still have injections within 1 statement, but can I confirm that you won't have problems with multiple statements in PHP?
Not to beat a dead (or is it a very alive?) horse, but...
Injection can only happen when data is read by the SQL engine as commands. In a very simple case, if you allow unescaped " characters in your data, and your data is encapsulated by " characters in SQL, they you have enabled an SQL injection attack.
The key to preventing any SQL injection is to properly validate and escape incoming data EVERY time, at the time it goes into the SQL statement. An easy way to do this is to just use prepared statements, which take care of it for you, allowing you to safely pass parameters to an SQL statement.
Each database library has it's own way of escaping or using prepared statements. In MySQL and PHP, you have mysqli_real_escape_string(), which should be used EVERY TIME PERIOD, when you are using the mysqli library.
The PDO library has it's own way, but if I recall correctly, prepared statements were a big part of PDO -- use them 100% of the time, and you will be OK in that regard.
To prevent agains XSS attacks, use HTML Purifier, and never strip_tags(), see links below for more info, PDO prepared statements should be fine for SQL Injection prevention:
http://www.reddit.com/r/PHP/comments/nj5t0/what_everyone_should_know_about_strip_tags/
http://htmlpurifier.org/

mysqli prepared statements and mysqli_real_escape_string [duplicate]

This question already has an answer here:
Is mysql_real_escape_string() necessary when using prepared statements?
(1 answer)
Closed 3 months ago.
I'm currently using the mysqli php extension.
Traditionally I have used mysqli_real_escape_string to escape user input. However I am looking at changing over the code (hopefully in as few steps as possible) to use prepared statements.
I want to be clear on this - provided I use prepared statements to bind all of my variables, can I be confident that sql injection is impossible? (And dispense completely with mysqli_real_escape_string?)
Thanks
If you correctly bind all your variables you can dramatically reduce the risk of SQL injection. It is still possible to get an SQL injection if you create SQL dynamically for example:
'SELECT * FROM ' . $tablename . ' WHERE id = ?'
But if you avoid things like this it is unlikely you will have problems.
Speaking of security, there is no difference between both methods, if you correctly bind or format your variables.
Binding is just simpler, because it can be used just for any case, while escaping can't (so, you have to cast some variables instead of escaping/quoting).
Also, bear in mind that no binding nor escaping can make identifier safe. So, if you have to use a field name or operator in your query, you have to use a value, hardcoded in your script.
Here's my high-level view on the topic.
When using dynamic SQL strings, you are relying on the escaping function working correctly. Unfortunately, this is not always the case, as can be seen in this (admittedly old) example:
http://dev.mysql.com/doc/refman/5.0/en/news-5-0-22.html
Once your data values have been escaped, the SQL string has to be parsed and compiled by the database server. If the escaping function has not done its job properly, or a clever new SQL injection attack has been discovered, there is a chance that the server will mistake data for SQL statements.
If you use prepared statements with parameters, the statement is first parsed and compiled. The data values are combined with the compiled statement when it is executed. This separates the SQL logic from the data values - the opportunity to confuse the two should never occur.
So, yes, you can dispense with mysqli_real_escape_string, but I would not go so far as to say that using prepared statements with parameters makes SQL injection impossible. It makes it significantly harder, but as with the mysqli_real_escape_string bug, I guess there's always the chance that a yet to be discovered (or newly created) bug will make the seemingly impossible, possible.

Categories