preg_match returns two different results for same string

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

Post Reply
mrgrammar
Forum Newbie
Posts: 3
Joined: Wed Jul 06, 2011 7:07 am

preg_match returns two different results for same string

Post by mrgrammar »

I want to make sure that my form is not vulnerable to injection. In the process of doing so, I found the following.

If I do a preg_match on the data directly submitted to the form, it returns true.

Code: Select all

// The form input comes from a text box that has two carriage returns
$data = $_POST['forminput'];
$checkdata = preg_match("/[\r\n]/",$value);
// output: $checkdata = true
However, if I treat the data first and then do a preg_match, it returns false.

Code: Select all

// The form input comes from a text box that has two carriage returns
$data = $_POST[forminput];
$data = strip_tags(htmlspecialchars(mysql_real_escape_string($data)));
$checkdata = preg_match("/[\r\n]/",$value);
// output: $checkdata = false
In both examples, if I echo the form input, the string on the screen shows the /r/n. Why does the first example return true and the second return false?
User avatar
social_experiment
DevNet Master
Posts: 2793
Joined: Sun Feb 15, 2009 11:08 am
Location: .za

Re: preg_match returns two different results for same string

Post by social_experiment »

Code: Select all

<?php
$data = strip_tags(htmlspecialchars(mysql_real_escape_string($data)));
?>
I think it would be different because you are changing the composition of the data you receive by subjecting that value to htmlspecialchars() / strip_tags() and mysql_real_escape_string(). If you view the source code of the page, what does that look like?
“Don’t worry if it doesn’t work right. If everything did, you’d be out of a job.” - Mosher’s Law of Software Engineering
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: preg_match returns two different results for same string

Post by AbraCadaver »

Well, you are checking $value instead of $data so it would depend on what $value is.
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.
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: preg_match returns two different results for same string

Post by McInfo »

This isn't an answer to the question that was asked (I believe AbraCadaver's answer is correct), but it is an answer to the "Why doesn't strip_tags() work?" question I foresee coming next.

These function calls are out of order:

Code: Select all

$data = strip_tags(htmlspecialchars(mysql_real_escape_string($data)));
mysql_real_escape_string() should be the last modification made to an input string before it goes into the query string.

See the difference:

Code: Select all

<?php
# strip_tags(htmlspecialchars(mysql_real_escape_string()));
var_dump(
    $str = "<span>\r\n&\r\n</span>",
    # string(18) "<span>
     # &
     # </span>"
     $str = mysql_real_escape_string($str),
    # string(21) "<span>\r\n&\r\n</span>"
     $str = htmlspecialchars($str),
    # string(38) "<span>\r\n&\r\n</span>"
     $str = strip_tags($str)
    # string(38) "<span>\r\n&\r\n</span>"
);

# mysql_real_escape_string(htmlspecialchars(strip_tags()))
var_dump(
    $str = "<span>\r\n&\r\n</span>",
    # string(18) "<span>
     # &
     # </span>"
     $str = strip_tags($str),
    # string(5) "
     # &
     # "
     $str = htmlspecialchars($str),
    # string(9) "
     # &
     # "
     $str = mysql_real_escape_string($str)
    # string(13) "\r\n&\r\n"
);
Save htmlspecialchars() for encoding strings after they are read from the database but before they are sent to output.

Code: Select all

// Pseudo-code
$sanitized_input = mysql_real_escape_string(strip_tags($raw_input));
database_insert($sanitized_input);
$decoded_output = database_select();
$encoded_output = htmlspecialchars($decoded_output);
output($encoded_output);
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Re: preg_match returns two different results for same string

Post by Mordred »

I support McInfo's answer, with the important addition that htmlspecialchars() needs to be called with ENT_QUOTES and proper encoding.
Post Reply