PHP MySQL $_GET Hack prevention

19,633

Solution 1

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

Solution 2

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.

Solution 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.

Share:
19,633
Albert Renshaw
Author by

Albert Renshaw

CEO, Apps4Life, LLC.

Updated on June 22, 2022

Comments

  • Albert Renshaw
    Albert Renshaw almost 2 years

    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
    
  • kba
    kba over 12 years
    -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.
  • Albert Renshaw
    Albert Renshaw over 12 years
    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"]."';");
  • Albert Renshaw
    Albert Renshaw over 12 years
    mysql_real_escape_string is good! Also, what other ways are common means of prevention Kristian Antonsen?
  • Albert Renshaw
    Albert Renshaw over 12 years
    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!
  • Dion
    Dion over 12 years
    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.
  • Mathieu Dumoulin
    Mathieu Dumoulin over 12 years
    mysql_real_escape_string or if you use PDO or a good DB layer it usually does it for you...
  • Albert Renshaw
    Albert Renshaw over 12 years
    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?
  • kba
    kba over 12 years
    @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).
  • Albert Renshaw
    Albert Renshaw over 12 years
    I noticed in another user's comment they said "XSS injection" does that stand for Cross Site Scripting Injection?
  • jeroen
    jeroen over 12 years
    @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['...'].
  • Albert Renshaw
    Albert Renshaw over 12 years
    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?
  • Albert Renshaw
    Albert Renshaw over 12 years
    is_numeric! Wow! That is great! Ahhh, that is nice! Thankyou! That will help a lot with thing like page numbers! Sweet! Thankyou! +1
  • Albert Renshaw
    Albert Renshaw over 12 years
    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!
  • kba
    kba over 12 years
    @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.
  • Albert Renshaw
    Albert Renshaw over 12 years
    That's great advice! Is there anything to make it AlphaNumeric values only?
  • Albert Renshaw
    Albert Renshaw over 12 years
    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?
  • jeroen
    jeroen over 12 years
    @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.
  • jeroen
    jeroen over 12 years
    @Albert Renshaw strip_tags($string)
  • Mathieu Dumoulin
    Mathieu Dumoulin over 12 years
    php.net/manual/fr/book.pdo.php - PHP Data Objects
  • Albert Renshaw
    Albert Renshaw over 12 years
    Ohhhhh!!! That makes much more sense! Okay, thats good advice, so mysql_real_escape_string(); will prevent this type of hacking?
  • Albert Renshaw
    Albert Renshaw over 12 years
    And does "XSS" stand for Cross Site Scripting? I saw that in another user's response.
  • Mathieu Dumoulin
    Mathieu Dumoulin over 12 years
    Yes, XSS is Cross Site Scripting
  • Albert Renshaw
    Albert Renshaw over 12 years
    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();"
  • Bill Karwin
    Bill Karwin over 12 years
    Yes, XSS is a popular abbreviation for Cross Site Scripting.
  • Bill Karwin
    Bill Karwin over 12 years
    For proper password security, be sure to read You're Probably Storing Passwords Incorrectly.
  • Bill Karwin
    Bill Karwin over 12 years
    For filtering in PHP, check out php.net/filter
  • kba
    kba over 12 years
    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. :)
  • Luc Laverdure
    Luc Laverdure over 12 years
    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().