PHP MySQL $_GET Hack prevention [duplicate]
Asked Answered
D

4

8

Possible Duplicate:
Best way to stop SQL Injection in PHP

If I were to use the $_GET function to retrieve a variable from the URL how can I make it hack proof? Right now I just have addSlashes, what else should I add?

$variable1 = addslashes($_GET['variable1']);
//www.xxxxx.com/GetTest.php?variable1=xxxx
Divisive answered 30/12, 2011 at 20:25 Comment(1)
For future reference this is my function to protect numeric values in the get function (remove the floatval(); function for non numeric get values): addslashes(mysql_real_escape_string(strip_tags(floatval())));Divisive
L
21

The first and foremost rule with ANY input, not just $_GET but even with $_POST, $_FILES and anything you read from disk or from a stream you should always VALIDATE.

Now to answer your question in more details, you have several HACKS that exist in this world. Let me show you some:

XSS injections

If you accept data from the URL such as from the $_GET and output this data without stripping out possible tags, you might render your site prone to XSS injection or code injection. For example:

http://myhoturl.com/?search=<script>window.location.href="http://thisisahack.com/"</script>

This would output a hack to your site and people would be redirected to another page. This page could be a phishing attempt to steal credentials

SQL Injection

It is possible to inject SQL to your application. For example:

http://myhoturl.com/?search=%'; UPDATE users SET password=MD5('hello'); SELECT * FROM users WHERE username LIKE '%

Would make your SQL look like this:

SELECT * FROM articles WHERE title LIKE '%%'; UPDATE users SET password=MD5('hello'); SELECT * FROM users WHERE username LIKE '%%';

And thus you'd update all your user's password to Hello and then return something that doesn't match.

This is only a brief overview of what you can do with SQL injection. To protect yourself, use mysql_real_escape_string or PDO or any good DB abstraction layer.

Code injection

Lots of people like to include data from somewhere on the disk and allow uploads of files. For example:

//File igotuploaded.txt
<?php echo 'helloworld'; ?>

And the url allows you to INCLUDE a file by name. ?show=myhotfile.txt

//In this file we include myhotfile.txt
include($_GET['show']);

The person changes that to ?show=../uploads/igotuploaded.txt and you will run echo 'Hello world';

That is dangerous.

rule of thumb... NEVER TRUST USER INPUT, always validate, prevent, validate, fix, validate and again correct...

Good luck

Lorie answered 30/12, 2011 at 20:36 Comment(6)
So how can I make it so my php script will ignore SQL queries that are retrieved via $_get? Thanks for all the examples too!Divisive
mysql_real_escape_string or if you use PDO or a good DB layer it usually does it for you...Lorie
What is "PDO" What does it stand for and how do I use it? I've seen this coming up a lot! Thanks again for all the help so far!Divisive
php.net/manual/fr/book.pdo.php - PHP Data ObjectsLorie
And does "XSS" stand for Cross Site Scripting? I saw that in another user's response.Divisive
Yes, XSS is Cross Site ScriptingLorie
U
5

That totally depends on what you are going to do with it:

Without knowing what you are going to do with your data, it is impossible to say what would make it safe.

Unbelief answered 30/12, 2011 at 20:28 Comment(10)
Let's say I was using it the way the person below stated it (I don't currently have a specific use I'm just trying to learn so when I do decide to use get in the future I will use it safely... Anyways, let's say: mysql_query("SELECT userid FROM user WHERE password='".$_GET["variable1"]."';");Divisive
Passwords you should generally don't read from GET-Variables. Use a password field in POST Form (HTML) instead. And passwords should always be md5()-secured. (For a password you would only need mysql_real_escape_string(); because you won't print it out.Persis
Okay great! Now what about something like viewing a user's profile page and it wasn't a password just an number... like 54038. And I was retrieving and displaying all table entries where that user's number was in a field called "userID" What type of injection could be harmful there and how could I prevent it?Divisive
@Albert Renshaw You have to know your data, if a field is supposed to be an integer, you'd best cast it to an integer: (int) $_GET['...'].Unbelief
That's great advice! Is there anything to make it AlphaNumeric values only?Divisive
So something like <b><center>hello</center></b> would just show up as "bcenterhellocenterb" Also, I think I recall something about stripping off just html tags so it will just show up as "hello", how do I do that?Divisive
@Albert Renshaw You'd probably have to resort to regular expressions like [\w\d]+ but if you get stuck there, you'd better ask a more specific question on SO.Unbelief
@Albert Renshaw strip_tags($string)Unbelief
For proper password security, be sure to read You're Probably Storing Passwords Incorrectly.Diskin
For filtering in PHP, check out php.net/filterDiskin
D
3

The two greatest risks you face when using user input (any HTTP request counts as user input) are:

You should get familiar with the risks and the defenses. The defenses for each of these threats are different. Using addslashes() is not a complete defense.

A great resource for learning more about secure web programming is the OWASP Top Ten project.

I've done a presentation about SQL Injection Myths and Fallacies that I hope is helpful for you.

Diskin answered 30/12, 2011 at 20:35 Comment(2)
I noticed in another user's comment they said "XSS injection" does that stand for Cross Site Scripting Injection?Divisive
Yes, XSS is a popular abbreviation for Cross Site Scripting.Diskin
S
-1

Reading $_GET variables raw isn't dangerous,

The danger usually lies within SQL Injections,

for example:

$_GET["variable1"] = "' OR 1=1 --";

With the query:

mysql_query("SELECT userid FROM user WHERE password='".$_GET["variable1"]."';");

To prevent this:

$safe_input = mysql_real_escape_string($GET["variable1"]);
mysql_query("SELECT userid FROM user WHERE password='".$safe_input."';");
Sandbag answered 30/12, 2011 at 20:30 Comment(10)
-1. mysql_real_escape_string() doesn't always prevent injections. This might give OP the idea that if he just escapes input, he won't ever have to worry about SQL injections.Ulphia
mysql_real_escape_string is good! Also, what other ways are common means of prevention Kristian Antonsen?Divisive
@AlbertRenshaw mysql_real_escape_string() only escapes ticks, quotation marks and the like. Assuming there are none, it isn't helpful at all. An example is with LIMIT 10, $page for pagination. If $page contains 1; DROP TABLE tbl --, escaping wouldn't help a bit. Always validate your input and make sure you have the right value (e.g. is_numeric and intval).Ulphia
What is the intuition behind "' OR 1=1 --"? I've seen this statement (or one similar) written before on hack prevention articles.. It makes an error via logic right? Does this intern display an error message with sensitive info?Divisive
is_numeric! Wow! That is great! Ahhh, that is nice! Thankyou! That will help a lot with thing like page numbers! Sweet! Thankyou! +1Divisive
@AlbertRenshaw No, it makes no error it just returns true. Consider a bad login system, SELECT username FROM tbl WHERE username='$user' AND password='$pass'. If $pass is ' OR 1=1 --, the query would be SELECT username FROM tbl WHERE username='$user' AND password='' OR 1=1 --', thus return the username and lead the application to believe the correct password was entered.Ulphia
Ohhhhh!!! That makes much more sense! Okay, thats good advice, so mysql_real_escape_string(); will prevent this type of hacking?Divisive
Also, for future reference of other clueless people like me. (found this with google) if you are trying to use the function Kristian gave, "intval();" and you have a number but it isn't an integer (e.g 4.389) intval will return 4, but if you want to keep the full numeric value but still strip away things like letters and SQL queries you can use "floatval();"Divisive
No, all mysql_real_escape_string() does is that it replaces ' with \', etc., so input cannot break encapsulation. 'foo \' bar' won't cause an error, but 'foo ' bar' will. And yes, intval only returns 4 - obviously it returns the INTeger value, not the floating point value. :)Ulphia
I didn't take the time to make this post elaborate, but seeing all the comments, yes, mysql_real_escape_string() will prevent all SQL injections within a string only, for numeric values, you should verify with is_numeric() before executing mysql_query().Sandbag

© 2022 - 2024 — McMap. All rights reserved.