PDA

View Full Version : [PHP] Security Thread


FuRom
09-24-2007, 12:02 AM
This thread is here to talk about the many security issues that come up in php scripting. A lot of issues are just dealing with how you write your if statements in co-relation to your sql queries. I have to admit, I'm not a php security expert, but I've not yet had anyone abuse anything I've made yet. This topic will not discuss just issues pertaining to pet site coding, but any php related coding. If you know common mistakes, share with us what they are and where the coding usually goes wrong.

When programming, take into consideration that users can manipulate anything in a request. $_GET, $_REQUEST, $_POST, $_COOKIE, and such are NOT a safe haven for very important data that gets checked by the server.

Some major security problems some people don't consider:
SQL Injection
Links: PHP.net (http://php.net/security.database.sql-injection) | Script around idea (http://www.virtualpetlist.com/showthread.php?p=76430)
Make use of the mysql_real_escape_string() function for your strings. If magic_quotes_gpc isn't on. You can check with the phpinfo() function.

Includes and Variables
Stay away from putting a user defined variable in the include function without fully checking it to make sure the user doesn't include something from their own server or something you don't want them to have access to.

Allow only the HTML you trust! : Added Sept 28, 2007 at 7:20am
Links: My Way (http://www.virtualpetlist.com/showthread.php?t=5028) | php.net Documentation (http://www.php.net/striptags) | HTML Purifier (http://www.htmlpurifier.org)
// Edited Sept 28 10:02 PM
I was originally mistaken about HTML Purifier's errors. I just mistook the files in the main folder for examples, which led me to believe that it was full of errors. Anyways after finding out what file to include and reading some documentation, the HTML purifier is still crap as far as I'm concerned. It is a great library for cleaning up html and securing your site, but it's too much effort for the daunting task of security. I'm sure that there is a much simpler way beyond allowing only certain HTML tags with strip_tags() function. As OwlManAtt has stated, HTML purifier and strip_tags do different things. Strip_tags is to remove all HTML tags that you do not have on your allow list whereas HTML Purifier will make sure that embedded crap and all is secure.

Notice //
If you post something that is very useful, I'll take and edit it into this first post. Also, if the link says "my way" it just means it's the way I do it, it's not inferring that you have to do it that way.

Tigress
09-24-2007, 12:32 AM
True. It's very easy to have HTTP headers edited (I have a Firefox extension that can do that). One of the major gaping security holes I often see in sites is vulnerability to cross-site request forgery. Basically, you can't trust the source of form data. HTTP_REFERER is not a reliable way to check the source of you data - most browsers, AFAIK, blank this variable (or else it is possible to blank this variable) and in any case it's also possible to spoof this. For example, a user can create their own HTML form that submits to your form processing page, except it has their own malicious data instead - say it submits to a forum thread submission page. The user can then trick other users into visiting this page and submitting data that could get them suspended or banned - and the user would really have no way to prove that it wasn't really them.

One way to protect against CSRF is to generate a token - I use a hashed 64-bit integer - and store it in the database whenever a user loads a form. The token is given to the form as a hidden input field. The user submits their form, etc, and on the next page, the token submitted through the form is checked to see if it exists in the database. If there is a match, then that form data is ok. If there is no match, then it's an invalid token. You'll want a cron script that times out these tokens after a certain amount of time as well. Edit You might want to add a table to your database with data stored on each form as well, and link the tokens through the database to the forms. Makes it harder for any malicious users to somehow manage to get someone else to submit bad data (though it's nigh impossible anyways). It also allows you to set specific timeout lengths for each form - for a forum post, you may want the timeout to be considerably longer than a change preferences form.

Generally, if you use this technique, you should redirect the user back to the form page so as to force the generation of a new token. If the user clicks the back button upon seeing the error (as most do), and they try to submit the form again, they'll get an "invalid token" error since they loaded a cached page rather than reloading it. The more streamlined the user experience, the better.

Anyways... uh... don't use BBCode. Use the HTMLPurifier library (http://htmlpurifier.org/) instead whenever pulling values from the database, such as the user's profile. It's easier and stuff.

stuffradio
09-24-2007, 01:35 AM
When using $_GET or $_POST make sure you validate the data, and for example if it's going to a database maybe use strip_slashes and add_slashes to make sure someone isn't trying to inject it.

FuRom
09-24-2007, 01:49 AM
When using $_GET or $_POST make sure you validate the data, and for example if it's going to a database maybe use strip_slashes and add_slashes to make sure someone isn't trying to inject it.

I believe my initial post has addressed the issue about SQL injection, seeing as SQL injection is one of the number one common issues that I can think of. The $_GET or $_POST data being validated is also addressed. My initial post stated:
When programming, take into consideration that users can manipulate anything in a request. $_GET, $_REQUEST, $_POST, $_COOKIE, and such are NOT a safe haven for very important data that gets checked by the server.

It's a very good point that you bring up and I really want to go into more detail on this.

--------------------------------------------------------
With the ability of a user manipulating any data that you use in your script dealing with $_GET, $_POST, and anything else that is sent through a browser's request, you need to make sure that the user does not use this to take advantage of your script. The only true issue that I know with this is dealing with SQL. When magic quotes are not enabled, you have to take measures to prevent the user from abusing his/her http request. The easiest way to fix this problem is something like this:
foreach($_GET as $k => $v){
$_GET[$x] = mysql_escape_string($_GET[$v]);
}
foreach($_POST as $k => $v){
$_POST[$x] = mysql_escape_string($_POST[$v]);
}
foreach($_COOKIE as $k => $v){
$_COOKIE[$x] = mysql_escape_string($_COOKIE[$v]);
}
Run through a foreach() loop for every varaible array that is usable in you script. This concept can keep your scripts smaller after a while.

FuRom
09-28-2007, 06:23 AM
Anyways... uh... don't use BBCode. Use the HTMLPurifier library (http://htmlpurifier.org/) instead whenever pulling values from the database, such as the user's profile. It's easier and stuff.

I tried to implement the HTML purifier for kicks and well.... it didn't turn out so great. I don't think I should be fixing what shouldn't be broken, which HTML purifier's includes are all screwed up. There is a much simpler way to allow only trusted HTML without a few hundred KB of code involved. Just use the strip_tags() function in php. I posted about it here (http://www.virtualpetlist.com/showthread.php?t=5028).

Tigress
09-28-2007, 02:28 PM
HTMLPurifier's includes are not screwed up. You just don't have the slightest clue what you're doing. Don't blame your own incompetence on HTMLPurifier.

Yes, it is a very big library, and that could be considered a con. But your "simple" function in that thread is (as I demonstrated) utterly useless if you want to give the user the freedom to say, post an image.

Stop spreading misinformation. You don't know the first thing about how to secure a script, as demonstrated by the fact that you think your "trusted HTML" function actually produces trusted HTML. It'd be a completely different matter if you weren't being so goddamn didactic to EVERYONE about how you think they should run their sites. But you are directly encouraging people to use HIGHLY INSECURE functions - "your way", as you put it - and criticizing a library that actually does it right, as large as it is, just because you couldn't figure out how to use it.

Sagashiteru
09-28-2007, 02:53 PM
If you'd like help use this:
http://phpsec.org/projects/phpsecinfo/index.html

FuRom
09-28-2007, 08:58 PM
HTMLPurifier's includes are not screwed up. You just don't have the slightest clue what you're doing. Don't blame your own incompetence on HTMLPurifier.

Yes, it is a very big library, and that could be considered a con. But your "simple" function in that thread is (as I demonstrated) utterly useless if you want to give the user the freedom to say, post an image.

Stop spreading misinformation. You don't know the first thing about how to secure a script, as demonstrated by the fact that you think your "trusted HTML" function actually produces trusted HTML. It'd be a completely different matter if you weren't being so goddamn didactic to EVERYONE about how you think they should run their sites. But you are directly encouraging people to use HIGHLY INSECURE functions - "your way", as you put it - and criticizing a library that actually does it right, as large as it is, just because you couldn't figure out how to use it.

-_O I've stated in my topic about it, I mistook some files as examples and all. I'm posting simpler ways to deal with your php crap. If you use it or not ain't my problem. I'm posting codes for the users that don't have a high understanding of php, because I've noticed that the general audience of people that do try programming pet sites (pet sites are a big co-relation of these message boards) are only beginners that don't yet know how to deal with using classes. I'll admit, I think a web site should have a higher standard of their content, and security-wise, I slack a bit. I'll also admit that I learn some new techniques in php regularly, because I've been in a cave. Anyways, people have a choice what they do with their codes. It's up to the programmer what they do, not me. If you or anyone else has a problem with that, keep it to your damn self, post the simple reasons that the user should or should not use it, and they can read it. If you felt me saying that "HTML Purifier library that tigress referenced" is a personal attack against you, I'm sorry, I was merely stating it was reference by you. I still don't change my view about the html purifier being absolute crap, it's too much code for something I'm sure can be done is a much simpler way, but that's my opinion untill I actually prove it and that is not for you to attack nor question, but to simply state your own opinion in turn. Furthermore when I say "my way" I'm referring to the fact that it's the way I do it.

I do have things that I'm editing and changing because I have realized that I was mistaken in a few things after OwlManAtt explaining that blasted library to me.

Tigress
09-29-2007, 12:18 AM
Did I say anywhere that I think it's a personal attack against me? No, I did not.

The problem I have with you - if I didn't make it blindingly clear before - is that you act as if you are an authority on matters of PHP security. After all, you started this thread, "[PHP] Security Thread", and stickied it - a decidedly authoritative manner to go about things. I do not have a problem if you aren't perfect at PHP.

Where the problem arises is that you act like you are an authority on PHP. People are probably going to take your advice as the best way to do things if no one contests that. And you stated that your simple and insecure function in the other thread would produce trusted HTML. You are lying. Whether knowingly or not, you are stomping all over a surefire solution to protecting against XHTML/XSS attacks simply because you had a bad experience with it.

In response to your argument that it is big - yes, on the webserver it takes up an unusually large amount of space. However, in the script, it only includes what is necessary. I don't know exactly how many files that is when you're just using the simplest aspects of the library, but I'm sure it's a hell of a lot smaller than the actual size of the library, which is what you're complaining about.

Oh, and who cares if the user doesn't know how to write classes? Even the most novice of PHP users could use a class. I stated the simplicity of the necessary code in the other forum. Seriously, it's almost insulting to novice PHP users to imply they can't figure out how to use those three lines of code. The only difference, to them, is that they have to make an object first (and again, that isn't hard. They can copy and paste the lines of code if they really want to.)

You want an example of how effective HTMLPurifier is? Here's a smoketest showing how it fares against a huge variety of XSS attacks:
XSS! (http://htmlpurifier.org/live/smoketests/xssAttacks.php)

FuRom
09-29-2007, 12:27 AM
-_- I'm not claiming to be an authority on security, I made this thread for the simple fact that I'm sure people would like to know a couple of things here and there about security. Fine, I'll unstick it if it makes you feel like I'm claiming to be an authority figure though.

Also, I'd like to state that people can read. The point of a security thread is for people to post better ways to do things and not for people to generally just read one post and go "ah! That's what I'm saposed to do." anyone that would do such a thing mustn't be a very bright person. Also, HTML Purifier, I'm not gunna say this again, is a bullshit system! It has too much coding to get something simple down. XSS is not that hard to protect against! All you have to friekin do is prevent the use of javascript and all tags that you do not want used. As for images, you'd have to do just a little bit more for them. You have to just make sure it's really getting an image file, which ain't fully safe, because I can have "www.blah.com/stupid_filename.gif" and it really be a .php file giving off cookie headers and whatnot.

Thanks for the link to that list. Just for the shits and giggles, I'mma prove that I can block everything on that list with way less code than HTML purifier.