Is my field security secure?

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

JasonDFR
Forum Commoner
Posts: 40
Joined: Wed Jan 07, 2009 3:51 am

Re: Is my field security secure?

Post by JasonDFR »

kaisellgren wrote:
JasonDFR wrote:Kai, why do you say strip_tags is useless? I would think that if the input you are asking for is not supposed to include any markup, you have two choices, use strip_tags and accept it, or invalidate it and force the user to enter a value that does not include markup.
Sorry, I was talking solely from the perspective of security. Sure, you could use strip_tags() to remove some markup, but as for securing a site, it's almost always useless.
No problem. I am curious about this from a security prospecive though. I am under the impression that markup based attacks can be limited by using strip_tags and would like to know why you consider strip_tags useless.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: Is my field security secure?

Post by kaisellgren »

JasonDFR wrote:I am under the impression that markup based attacks can be limited by using strip_tags and would like to know why you consider strip_tags useless.
It's not entirely useless, but pretty much so.

strip_tags() can only work in between two tags. As soon as strip_tags() filtered data gets outside of an element, you are probably vulnerable to XSS. Even if you add a single < somewhere, it could destroy you (typing invalid template HTML accidentally can lead to XSS when you are running the software).

The function was malfunctioning in PHP < 5.x (don't remember the exact version): truncation attacks were possible to completely bypass the protection.

Also, if you (or any other developer) ever specifies the second parameter for it, you are likely vulnerable to inline XSS.

One non-security related problem is that it easily removes unintentional data. For example, consider a user supplied comment:

Code: Select all

<a user supplied comment goes here...
lots of text. lots of lines. lots of feedback.
You can really easily get your data stripped away. The above comment would become empty after strip_tags().

The strip_tags() function is also unaware of different encodings. Take a look:

Code: Select all

header('Content-type: text/html; charset=UTF-7');
 
$input = '+ADw-script+AD4-alert(123)+ADsAPA-/script+AD4-';
 
echo strip_tags($input);
It produces an alert (not so surprisingly..).
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Is my field security secure?

Post by AbraCadaver »

andym67 wrote:I have the following PHP code to stop sql injection and whatever else the scum might try to insert bad stuff into my form fields. Does anyone see any problems with this? I have a strong feeling my site will eventually become a target.

As for eregi() you can use preg_match() or preg_grep() by just adding a

Code: Select all

 
function clean($str) {
    $str = @trim($str);
    if(get_magic_quotes_gpc()) {
       $str = stripslashes($str);
    }
    $str = strip_tags($str);
    $str = htmlspecialchars($str,ENT_QUOTES);
    return mysql_real_escape_string($str);
 }
 
 if (eregi("[^#-?.,`!a-zA-Z0-9 ]", $_POST['mystring'])){
       $errmsg_arr[] = 'Non Allowed Character Found';
       $errflag = true;
 }
 
 
Also, eregi is deprecated in PHP 5.# and removed in PHP 6+ so what should I use as an alternative?

Thanks in advance.

Ideally, you want to separate out sanitizing for display and sanitizing for the database. If you have a very narrowly focused app then what you have may work well, though it's overkill. Also, it's not very flexible to restrict all of your data by regex and strip out all of the tags. What happens if you want to accept an email address and it fails your regex, or if you want to accept some HTML? I safely store raw data in case it is needed and then prep it for safe display. You can always extend these or apply specific validation to specific fields where you know what you are expecting.

Code: Select all

 
function prep4store($str) {
    if(get_magic_quotes_gpc()) {
       $str = stripslashes($str);
    }
    return mysql_real_escape_string($str);
}
 
function prep4display($str) {
    $str = your_filter($str);  //custom stuff
    return htmlentities($str);
}
 
As for eregi() you can use preg_match() by adding valid pattern delimiters to your pattern "/[^#-?.,`!a-zA-Z0-9 ]/". And no need for the i because you are matching A-Z and a-z.

Have you looked at filter_var()? http://us3.php.net/manual/en/function.filter-var.php
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
andym67
Forum Newbie
Posts: 8
Joined: Thu Oct 01, 2009 11:03 am

Re: Is my field security secure?

Post by andym67 »

AbraCadaver wrote:
Ideally, you want to separate out sanitizing for display and sanitizing for the database. If you have a very narrowly focused app then what you have may work well, though it's overkill. Also, it's not very flexible to restrict all of your data by regex and strip out all of the tags. What happens if you want to accept an email address and it fails your regex, or if you want to accept some HTML? I safely store raw data in case it is needed and then prep it for safe display. You can always extend these or apply specific validation to specific fields where you know what you are expecting.

Code: Select all

 
function prep4store($str) {
    if(get_magic_quotes_gpc()) {
       $str = stripslashes($str);
    }
    return mysql_real_escape_string($str);
}
 
function prep4display($str) {
    $str = your_filter($str);  //custom stuff
    return htmlentities($str);
}
 
As for eregi() you can use preg_match() by adding valid pattern delimiters to your pattern "/[^#-?.,`!a-zA-Z0-9 ]/". And no need for the i because you are matching A-Z and a-z.

Have you looked at filter_var()? http://us3.php.net/manual/en/function.filter-var.php
Thanks - that has since become the issue and I have close to what you have here. Thanks
Post Reply