Jump to content

Sanitizing GET or POST, and preventing XSS


leesiulung

Recommended Posts

So I got my pages up and running and right now it prevents SQL injection by using mysql_real_escape_string() on all user input. Now I do have a lot of code that relies on GET and POST variables from users. How do I scrub this for malicious input? What sort of things can malicious users do with this?

 

My guess is that PHP is a scripting language and isn't compiled, but rather interpreted. Thus they can pass in regular PHP code in the GET/POST variables. Is this true for PHP? I have seen code that do stuff like $$contains_variable_name which suggest this is possible.

 

Some older thread suggested a function called htmlentities(), but I fail to see how this is related to this or XSS attacks.

 

Finally, not quite related what is the opposite of mysql_real_escape_string()? Do you have to do the opposite of mysql_real_escape_string() when you display the data? Can't find any information or samples of this on PHP.net's website.

 

 

Link to comment
Share on other sites

Even if they pass in PHP Code as long as you are not using www.php.net/eval on GET/POST data than you are fine.

 

The issue is SQL Injection, which is taken care of by the mysql_real_escape and javascript.

 

They javascript portion can be dangerous in that if you have a field, say Firstname and I can enter this in there:

 

<script>alert('your screwed');</script>

 

and on a page that displays my first name an alert pops up you have a potention XSS exploit. Meaning I can hijack cookies etc using Javascript in your account fields.

 

The best way to handle this, is if your input fields do not and should not have javascript do an eregi check for it. IE:

if (eregi('<script', $_POST['first_name'])) {
    die("Nice try, NO HTML code allowed.");
}

 

It would also be wise to create regex's that check for what SHOULD be in there and disallow everything else. In a username you may want < but for the most part you do not want that in the firstname, etc.

 

Now if you do have a field, say the text of a blog, that can potentially have javascript well create some routines to disallow setting of cookies and redirects. If you do not want javascript period, anytime a user adds <script simply throw the error and you are good. Another way you could do it is change all the < characters to be <  that way the browser takes them literally and not as code. This will skew the html up though.

 

Anyhow hope that helps.

 

EDIT

http://www.phpfreaks.com/forums/index.php/topic,132689.msg557882.html#msg557882

 

On this note check out the above for a routine I created to check Javascript Re-direct spam.

Link to comment
Share on other sites

Is there a function in PHP I can call instead? Something that removes any HTML or JavaScript. All these checks can be hard to maintain and are long....

 

Also, do need to reverse what mysql_real_escape_string() does when I want to retrieve the data from the DB?

Link to comment
Share on other sites

As long as you check for get_magic_quotes_gpc to see if it is on or off you should never have to reverse the mysql_real_escape. Here is an example function:

 

<?php
function myEscape($string) {
     return (get_magic_quotes_gpc())?mysql_real_escape_string($string):$string;
}
?>

 

If get_magic_quotes_gpc is on, than you do not need to addslashes or mysql_real_Escape_string because the data should already be sanitizied.

 

As for the javascript/html if you do not want to allow them just use the strip tags and convert all < to < and you should be fine. I just run a blogging site that allows HTML and Javascript in templates and in blogs. Those checks are necessary to keep the user functionality even with lame old spammers and script kiddies.

Link to comment
Share on other sites

just to clear up on something i've been reading up on. mysql_real_escape_string vs addslashes - there are differences and some things that addslashes wont take care of. you should try and use mysql_real_escape_string in every situation. so to tweak frost's function a bit:

 

<?php
function myEscape($string) 
{
   // undo magic quotes if they're on...
   $string = get_magic_quotes_gpc() ? stripslashes($string) : $string;

   // NOW escape the string
   return mysql_real_escape_string($string);
}
?>

Link to comment
Share on other sites

as for the opposite, the actual escape sequences (ie, the \) don't actually go into the database, so on retrieval, the data is fine - as long as you didnt escape the escapes (ie, \\) by misusing mysql_real_escape_string (or addslashes).

 

the only thing to really do then to make it safe for the screen or a form is to run it through htmlspecialchars() which is useful for situations where you want to allow tags like < script > ,etc, but you don't want them to be "active" (which also helps to produce valid HTML)

Link to comment
Share on other sites

just to clear up on something i've been reading up on. mysql_real_escape_string vs addslashes - there are differences and some things that addslashes wont take care of. you should try and use mysql_real_escape_string in every situation. so to tweak frost's function a bit:

 

<?php
function myEscape($string) 
{
   // undo magic quotes if they're on...
   $string = get_magic_quotes_gpc() ? stripslashes($string) : $string;

   // NOW escape the string
   return mysql_real_escape_string($string);
}
?>

 

Interesting, I will start using that now. Thanks for the tip marky.

Link to comment
Share on other sites

to expand on red bull, from what i've noticed/read... mysql_real_escape_string() requires a connection to a database to work...? so use this instead... just direct your $dblink to your var you set your mysql_connect() to...

 

<?
function add_slashes($string){
global $dblink;
if(!$dblink) return addslashes($string);
$string=get_magic_quotes_gpc() ? stripslashes($string) : $string;
return mysql_real_escape_string($string);
}
?>

i think thats right...?

Link to comment
Share on other sites

It does require a database connection, but you do not need to explicitly specify it because it is "assumed". But if you are escaping it you should have a connection to a database right? Because there is a reason to escape it.

Link to comment
Share on other sites

IMO, there are only 2 places to "treat" data:

1, when performing a DB query (in which case mysql_real_escape_string does the job)

2, when outputting data to the screen / prefilling a form (in which case htmlspecialchars does the trick).

 

effectively, to me, it means that whilst 'stripslashes' is still useful sometimes (when undoing the mess that magic_quotes_gpc causes), there are absolutely no requirements at all for addslashes. Having said that though, I only use mysql, but I do believe that the other types of DB have their own *_escape_string functions if they're required by that type of DB...

 

addslashes -> bin it :)

Link to comment
Share on other sites

agreed... addslashes isnt very useful much of the time... however, on certain things like... installing programs, where you may or may not be able to connect to the database yet, having a single function that covers both grounds, may be helpful... but ya... i agree that its rarely helpful, but why not use a function that makes the correct choice, no matter what situation your database may be in...

Link to comment
Share on other sites

well mysql_real_escape_string throws a wobbly if no connection exists so you could probably trap the error? (not sure, havent tried it but...)

 

<?php
function myEscape($string) 
{
   // undo magic quotes if they're on...
   $string = get_magic_quotes_gpc() ? stripslashes($string) : $string;

   // NOW escape the string
   if ($return = @mysql_real_escape_string($string))
   {
      return $return;
   }
   else
   {
      return addslashes($string);
   }
}
?>

Link to comment
Share on other sites

This will do what mysql_real_escape_string() does:

<?php
function fake_mysql_real_escape_string($string)
{
return addcslashes($string, "\x00\n\r\\'\"\x1a");
}
?>

 

Thats a keeper right there.

 

<?php
function myEscape($string) {
       return get_magic_quotes_gpc()?addcslashes(stripslashes($string), "\x00\n\r\\'\"\x1a"):addcslashes($string, "\x00\n\r\\'\"\x1a");
}
?>

 

Sleek simple with no db connection required and should not throw errors! Plus it is all on one line W00t!

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.