SitePoint Sponsor |
|
User Tag List
Results 1 to 22 of 22
Thread: How do you handle security?
-
Apr 12, 2005, 17:36 #1
- Join Date
- Mar 2005
- Posts
- 116
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
How do you handle security?
Just wondering what sort of "best practices" everyone is using for security in PHP?
I have been using the PHP Filters provided by the OWASP Foundation. These filters provide some pretty comprehensive validation methods, but I am sure I can do more.toby hede
Toby Hede’s Blog on Ruby, Rails, User Experience and Stuff
================================================
FiniteStateMachine - Software Development for Social Networks
-
Apr 13, 2005, 00:37 #2
- Join Date
- Jan 2003
- Posts
- 5,748
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I have just downloaded a PDF available from Microsoft the other day there, which you can find here
http://msdn.microsoft.com/library/de...eatCounter.asp
Looking at it briefly earlier today it covers everything you would need to know, provided you take into account what references about DotNet there are, also apply to PHP, but the implementation and script are different
-
Apr 13, 2005, 02:26 #3
- Join Date
- Jan 2005
- Location
- Ireland
- Posts
- 349
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I would say that "PHP Filters" will fit most situations: though may not be tough enough on XSS for some applications.
Thanks for the article Dr Livingston: looks like an alright read.
-
Apr 15, 2005, 01:29 #4
- Join Date
- Apr 2005
- Posts
- 58
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Chris Shiflett is the security guru of PHP. There are a lot of great security resources on his blog , such as his security workbook.
-
Apr 15, 2005, 04:23 #5
- Join Date
- Feb 2003
- Posts
- 156
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by tobyhede
Code:// sanitize a string for SQL input (simple slash out quotes and slashes) function sanitize_sql_string($string, $min='', $max='') { $string = nice_addslashes($string); //gz $pattern = "/;/"; // jp $replacement = ""; $len = strlen($string); if((($min != '') && ($len < $min)) || (($max != '') && ($len > $max))) return FALSE; return preg_replace($pattern, $replacement, $string); }
-
Apr 15, 2005, 04:51 #6
- Join Date
- Apr 2004
- Location
- germany
- Posts
- 4,324
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
sanitize_html in not that bad too
PHP Code:function sanitize_html_string($string)
{
$pattern[0] = '/\&/';
$pattern[1] = '/</';
$pattern[2] = "/>/";
$pattern[3] = '/\n/';
$pattern[4] = '/"/';
$pattern[5] = "/'/";
$pattern[6] = "/%/";
$pattern[7] = '/\(/';
$pattern[8] = '/\)/';
$pattern[9] = '/\+/';
$pattern[10] = '/-/';
$replacement[0] = '&';
$replacement[1] = '<';
$replacement[2] = '>';
$replacement[3] = '<br>';
$replacement[4] = '"';
$replacement[5] = ''';
$replacement[6] = '%';
$replacement[7] = '(';
$replacement[8] = ')';
$replacement[9] = '+';
$replacement[10] = '-';
return preg_replace($pattern, $replacement, $string);
}
First advice to you: stop using "the PHP Filters provided by the OWASP Foundation"
-
Apr 15, 2005, 17:07 #7
- Join Date
- Jan 2005
- Location
- Ireland
- Posts
- 349
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
It's far from extensive protection but it really depends on the application at hand. If the application is not going to be displaying much user-defined data then the sanitize_html_string may be effecient.
However, I do agree that parsing all ';' out of SQL queries is wrong. They should at least use some regex to see if the ; appeared in a quoted string. Valid ; (can't remember the name) would be stripped out.
-
Apr 15, 2005, 18:00 #8
I dont like the look of those OWASP functions, imo either something is valid, or it isnt, you dont attempt fix it by replacing/removing bits.
The ctype_*() functions are my usual first step. (well 2nd after checking min/max lengths)
If there isn't one that matches the characters i want, something like
strlen($value) == strspn($value, '01')
will be true if $value is only made up of 0s or 1s. (a binary number).
If its something bit more complex, then preg_match
-
Apr 15, 2005, 18:06 #9
- Join Date
- Jan 2005
- Location
- Ireland
- Posts
- 349
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Ren
-
Apr 15, 2005, 19:06 #10
- Join Date
- Mar 2005
- Posts
- 116
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
That PHP Security Workbook is a great resource, thanks. Lots of excellent ideas about securing files and sessions -> that's the kind of stuff I am looking for. Validating and verifying data is obvious and realtively simple, but I want to ensure I am not missing other obvious issues.
The PHP Filters I use are slightly modified for my own use-cases. It's not a case of slapping these on and thinking that security is done, data has to be validated for each process according to the tightest possible requirements.
Good catch on the sanitize_sql function. There are obviously cases where semi-colons are required inside text. This is a dangerous issue though, because semi-colons are statement terminators in many SQL variants (if not all) and some databases allow multiple statements to be executed (not such an issue for MySQL as only the most recent versions allow this functionality). Probably need the ability to switch this on or off - only allow semi-colons if the data warrants it and in other cases strip it completely.
I think data needs to be handled on a case by case basis -> data such as email addresses and postcodes can be rejected if they are not in the correct format, but allowing HTML in the case of forums or RSS feeds is often necessary. Allowing the smallest possible set of HTML is the wisest cause of action in these cases.toby hede
Toby Hede’s Blog on Ruby, Rails, User Experience and Stuff
================================================
FiniteStateMachine - Software Development for Social Networks
-
Apr 15, 2005, 20:22 #11
- Join Date
- Jan 2005
- Location
- Ireland
- Posts
- 349
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
To defeat semi-colons issues could you not just:
If input is a string (ie. enclosed within quote tags), make sure slashes are applied (or equivalent procedure)
If input is a number make sure it is a integer (or intval it, so if not valid will be 0).
Just my take on it
-
Apr 16, 2005, 02:53 #12
Originally Posted by Ryan Wray
SQL Injection & XSS are the same problem, both solved by escaping for the intended destination.
-
Apr 16, 2005, 03:05 #13
- Join Date
- May 2003
- Location
- Berlin, Germany
- Posts
- 1,829
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Well as for me I use the following class for all my security needs. Sometimes when some crucial Delete operations are done I may add some additional stuff too depending on the context.
PHP Code:<?php
/**
* Author: Tim Koschützki
* Based on ideas from Matt Mecham
* Date Started: January 7th, 2003
*/
class Request {
/*-------------------------------------------------------------------------*/
// Makes incoming info "safe"
/*-------------------------------------------------------------------------*/
public function parse() {
$this->get_magic_quotes = get_magic_quotes_gpc();
$return = array();
if( is_array($_GET) ) {
while( list($k, $v) = each($_GET) ) {
if ( is_array($_GET[$k]) ) {
while( list($k2, $v2) = each($_GET[$k]) ) {
$return[ $this->clean_key($k) ][ $this->clean_key($k2) ] = $this->clean_value($v2);
}
} else {
$return[ $this->clean_key($k) ] = $this->clean_value($v);
}
}
}
//-----------------------------------------
// Overwrite GET data with post data
//-----------------------------------------
if( is_array($_POST) ) {
while( list($k, $v) = each($_POST) ) {
if ( is_array($_POST[$k]) ) {
while( list($k2, $v2) = each($_POST[$k]) ) {
$return[ $this->clean_key($k) ][ $this->clean_key($k2) ] = $this->clean_value($v2);
}
} else {
$return[ $this->clean_key($k) ] = $this->clean_value($v);
}
}
}
$return['request_method'] = strtolower($_SERVER['REQUEST_METHOD']);
return $return;
}
private function clean_key($key) {
if ($key == "") {
return "";
}
$key = htmlspecialchars(urldecode($key));
$key = preg_replace( "/\.\./" , "" , $key );
$key = preg_replace( "/\_\_(.+?)\_\_/" , "" , $key );
$key = preg_replace( "/^([\w\.\-\_]+)$/", "$1", $key );
return $key;
}
private function clean_evil_tags( $t ) {
$t = preg_replace( "/javascript/i" , "javascript", $t );
$t = preg_replace( "/alert/i" , "alert" , $t );
$t = preg_replace( "/about:/i" , "about:" , $t );
$t = preg_replace( "/onmouseover/i", "onmouseover" , $t );
$t = preg_replace( "/onclick/i" , "onclick" , $t );
$t = preg_replace( "/onload/i" , "onload" , $t );
$t = preg_replace( "/onsubmit/i" , "onsubmit" , $t );
$t = preg_replace( "/<body/i" , "<body" , $t );
$t = preg_replace( "/<html/i" , "<html" , $t );
$t = preg_replace( "/document\./i" , "document." , $t );
return $t;
}
private function clean_value($val) {
if ($val == "") {
return "";
}
$val = str_replace( " ", " ", $val );
$val = str_replace( chr(0xCA), "", $val ); //Remove sneaky spaces
$val = str_replace( "&" , "&" , $val );
$val = str_replace( "<!--" , "<!--" , $val );
$val = str_replace( "-->" , "-->" , $val );
$val = preg_replace( "/<script/i" , "<script" , $val );
$val = str_replace( ">" , ">" , $val );
$val = str_replace( "<" , "<" , $val );
$val = str_replace( "\"" , """ , $val );
$val = preg_replace( "/\n/" , "<br />" , $val ); // Convert literal newlines
$val = preg_replace( "/\\\$/" , "$" , $val );
$val = preg_replace( "/\r/" , "" , $val ); // Remove literal carriage returns
$val = str_replace( "!" , "!" , $val );
$val = str_replace( "'" , "'" , $val ); // IMPORTANT: It helps to increase sql query safety.
// Ensure unicode chars are OK
if ( $this->allow_unicode ) {
$val = preg_replace("/&#([0-9]+);/s", "&#\\1;", $val );
}
// Strip slashes if not already done so.
if ( $this->get_magic_quotes ) {
$val = stripslashes($val);
}
// Swop user inputted backslashes
$val = preg_replace( "/\\\(?!&#|\?#)/", "\", $val );
return $val;
}
}
-
Apr 18, 2005, 00:37 #14
- Join Date
- Jan 2005
- Location
- Ireland
- Posts
- 349
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Ren
When in an input field on a HTTP browser, I may use < and >in my post (ie. < >with valid reasons. However, if you only do a check to see if it is clean or not, then you will either:
Disallow the post, as you deem < and > tags as security risk and hence the post is invalid
Allow it, but you don't convert the characters into their HTML entities.
In this case, my post, although valid, would need to be modified before you can accept it as secure to display.
Hence, for XSS this:
Originally Posted by Ren
Originally Posted by Ren
Good Luck
-
Apr 18, 2005, 04:44 #15
Originally Posted by Ryan Wray
SQL Injection and XSS aren't solved by validation, but escaping. Period.
-
Apr 18, 2005, 15:33 #16
- Join Date
- Jan 2005
- Location
- Ireland
- Posts
- 349
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
What do you mean by escaping, Ren. To me, it seems like you contradict yourself.
Originally Posted by Ren
Originally Posted by Ren
Maybe I am simply reading you wrong. I don't see how efficient is an incorrect term (though I spelled it wrong). Efficient also implies sufficient, with minimal waste. There is no reason to waste, say, memory when you can accomplish the same thing more efficiently.
Oh well, I think I get what you are trying to say, in a round-about way.
-
Jun 25, 2005, 14:07 #17
- Join Date
- Oct 2004
- Location
- Brooklyn, NY
- Posts
- 359
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by tobyhede
The primary reason that I dislike them is that they reflect a very imprecise approach to this particular topic, and I think precision is important for a number of reasons. For example, sanitize_html_string() escapes data, which is a very different thing from filtering. How does a security-conscious developer intuit the behavior of this function or know when it should be used?
Another complaint is that almost every function violates the security principle that says we should never modify invalid data in order to make it valid (although some security professionals agree that this approach can be acceptable when used as a Defense in Depth approach).
Originally Posted by stereofrog
Originally Posted by Ren
Originally Posted by Ryan Wray
What Ren is describing is filtering. If I am filtering a last name, O'Reilly is going to pass my whitelist approach, because it consists entirely of characters that I consider to be valid in a last name. In order to use the name O'Reilly in an SQL query that I intend to send to MySQL, however, I still need to escape it with mysql_real_escape_string().
Originally Posted by Ryan Wray
Originally Posted by Ren
Originally Posted by Ryan Wray
I am writing a book for O'Reilly.
When I escape this with mysql_real_escape_string(), it becomes the following:
I am writing a book for O\'Reilly.
Now, technically, this string has been modified, but that's not the purpose. It is in an escaped state so that the string is preserved when I send it to a MySQL database.
Functions like htmlentities() and urlencode() also preserve data.
Anyway, I hope that helps clarify some things. :-)Chris Shiflett
http://shiflett.org/
-
Jun 25, 2005, 15:53 #18
- Join Date
- Mar 2005
- Posts
- 94
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
not so shy with ads chris
-> http://phpsec.org/
[edit]
A security-careless-packet has dangers, because you cannot protect a
system if you don't know how to compromise it. So its up to the programmer
to learn about security and then use/build the right tools.
my 2 eurocent
-
Jun 25, 2005, 16:33 #19
- Join Date
- Jun 2003
- Location
- Melbourne, Australia
- Posts
- 440
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by shiflett
Zealotry is contingent upon 100 posts and addiction 200?
-
Jun 25, 2005, 21:23 #20
- Join Date
- Mar 2005
- Posts
- 116
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Chris, thanks for the response. Excellent summary of the issues.
By popular demand, I've stopped using those OWASP filterstoby hede
Toby Hede’s Blog on Ruby, Rails, User Experience and Stuff
================================================
FiniteStateMachine - Software Development for Social Networks
-
Jul 1, 2005, 15:11 #21
- Join Date
- Jan 2005
- Location
- Ireland
- Posts
- 349
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by shiftlet
As for the rest, looking back I mis-read Ren.
-
Jul 19, 2005, 18:05 #22
- Join Date
- Mar 2005
- Posts
- 116
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Just wondering what Validation scripts people used? The one I have strung together is getting complex very quickly, and there may be an OS valdiation system that people recommend that will be much more robust and tested than anything I can produce.
toby hede
Toby Hede’s Blog on Ruby, Rails, User Experience and Stuff
================================================
FiniteStateMachine - Software Development for Social Networks
Bookmarks