filter_var bug. Workaround?

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
vbmark
Forum Newbie
Posts: 19
Joined: Sun Feb 15, 2009 8:53 pm

filter_var bug. Workaround?

Post by vbmark »

Hello,

I just discovered that there is a bug in filter_var, FILTER_VALIDATE_URL that affects my site: http://bugs.php.net/bug.php?id=51192

The fix is not out yet. Is there any workaround?

Thanks!
Mark
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: filter_var bug. Workaround?

Post by Christopher »

It seems like you would need to use something like strpos() to check for space characters in the hostname.
(#10850)
vbmark
Forum Newbie
Posts: 19
Joined: Sun Feb 15, 2009 8:53 pm

Re: filter_var bug. Workaround?

Post by vbmark »

Hey,

Thanks for your reply. I've tried different ways to work around this problem with strpos and str_replace, but can't get it to work.

Anyone have any ideas?

Thanks,
Mark
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: filter_var bug. Workaround?

Post by John Cartwright »

Perhaps something along the lines of,

Code: Select all


$parts = parse_url($url);

if (($parts && strpos($parts['host'], ' ') !== false) && filter_var($url, FILTER_VALIDATE_URL)) 
{
    //valid url   
}
vbmark
Forum Newbie
Posts: 19
Joined: Sun Feb 15, 2009 8:53 pm

Re: filter_var bug. Workaround?

Post by vbmark »

John Cartwright wrote:Perhaps something along the lines of,

Code: Select all


$parts = parse_url($url);

if (($parts && strpos($parts['host'], ' ') !== false) && filter_var($url, FILTER_VALIDATE_URL)) 
{
    //valid url   
}
Hi John,

I tried it and it still will not validate a legitimate URL like http://ubuntu-manual.org/

Any other ideas?

Thanks,
Mark
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: filter_var bug. Workaround?

Post by Christopher »

You should probably just use a regexp to check. The reason that John's example is not working is that you need to change his code to be two-step. First check with filter_var() and if it fails, then check for the dash. But you probably need to tear the URL apart, change the dash to maybe an underscore in the domain name, and then rebuild the URL and recheck with filter_var().
(#10850)
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: filter_var bug. Workaround?

Post by John Cartwright »

Christopher wrote:You should probably just use a regexp to check. The reason that John's example is not working is that you need to change his code to be two-step.
I don't see why it needs to be "two stepped". The logic operators basically make it two stepped, but anyways, I just had a typo in my code.

Code: Select all

if (($parts && strpos($parts['host'], ' ') !== false) && filter_var($url, FILTER_VALIDATE_URL))
should be

Code: Select all

if (($parts && strpos($parts['host'], ' ') == false) && filter_var($url, FILTER_VALIDATE_URL))  
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: filter_var bug. Workaround?

Post by Christopher »

John Cartwright wrote:I don't see why it needs to be "two stepped". The logic operators basically make it two stepped, but anyways, I just had a typo in my code.
It does not work because there is not space in the URL/domain name -- it is a dash. But you only want to check if there is a dash if the filter_var() fails. Otherwise you might get the case where the URL is valid, but does not have a dash, so the test would fail. The problem is that if filter_var() fails, you can't just assume that the problem was ONLY that a dash was used. That's why I think you need to use your own regexp in this case.
(#10850)
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: filter_var bug. Workaround?

Post by John Cartwright »

filter_var() does not have an issue with dashes, but with spaces. Heres a test case:

Code: Select all

function testUrlIsValid($url) 
{
	$parts = parse_url($url);
	
	return $parts && strpos($parts['host'], ' ') == false && filter_var($url, FILTER_VALIDATE_URL);	
}

var_dump(testUrlIsValid('http://ubuntu-manual.org/')); 
var_dump(testUrlIsValid('http://google.com/?foo=bar')); 
var_dump(testUrlIsValid('http://images.google.com')); 
var_dump(testUrlIsValid('http://go ogle.com'));
[text]Expecting:

bool(true)
bool(true)
bool(true)
bool(false)

Returned:

bool(true)
bool(true)
bool(true)
bool(false)[/text]
vbmark
Forum Newbie
Posts: 19
Joined: Sun Feb 15, 2009 8:53 pm

Re: filter_var bug. Workaround?

Post by vbmark »

I finally was able to get around to testing this and it still does not work on my host's server running PHP version 5.2.13.

Can someone else tell me if they can get this to work on PHP version 5.2.13?

Thank you,
Mark
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: filter_var bug. Workaround?

Post by Christopher »

John Cartwright wrote:filter_var() does not have an issue with dashes, but with spaces. Heres a test case:
I am not exactly sure what you logic is doing, but I suspect that the space check is giving incorrect results because there is no satisfactory logic for this.

Code: Select all

function testUrlIsValid($url)
{
        return filter_var($url, FILTER_VALIDATE_URL);
}

var_dump(testUrlIsValid('http://ubuntu-manual.org/'));
var_dump(testUrlIsValid('http://google.com/?foo=bar'));
var_dump(testUrlIsValid('http://images.google.com'));
var_dump(testUrlIsValid('http://go ogle.com'));
Results in:

Code: Select all

bool(false)
string(26) "http://google.com/?foo=bar"
string(24) "http://images.google.com"
bool(false)
As I said above, I don't think that you can use filter_var() and get valid results without doing a complete recheck of the domain name using regexp if filter_var() fails. And if you have to do that ... why use filter_var()?
(#10850)
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: filter_var bug. Workaround?

Post by Benjamin »

Took about 5 seconds to find this using a search engine, hopefully it will work for you.

Code: Select all

/**
* Validate URL
* Allows for port, path and query string validations
* @param    string      $url	   string containing url user input
* @return   boolean     Returns TRUE/FALSE
*/
function validateURL($url)
{
$pattern = '/^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/';
return preg_match($pattern, $url);
}

$result = validateURL('http://www.google.com');
print $result;
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: filter_var bug. Workaround?

Post by Christopher »

Note that that regexp only validates the the protocol, domain name and path. It will fail if there are parameters.
(#10850)
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: filter_var bug. Workaround?

Post by Benjamin »

* Allows for port, path and query string validations
It claims to, although I haven't tested it.
Post Reply