Jump to content

[SOLVED] url comparing not working with GET


Dragen

Recommended Posts

Hi,

I'm trying to write a function which takes a given url, runs it through a database and verifies whether it is in the 'allowed' list, 'banned' list or neither.

 

This is my function (I've added quotes to make it easier for you to understand):

<?php
function check_url($id, $url){
	if($url == $_SERVER['REQUEST_URI']){ //makes sure $url isn't the current file
		return false;
	}

	$sql = "SELECT `valid_urls`, `banned_urls` FROM `user_settings` WHERE `user_id` = '" . mysql_real_escape_string($id) . "' LIMIT 1";
		if($sqlres = mysql_query($sql)){
			if(mysql_num_rows($sqlres) > 0){
				while($row = mysql_fetch_assoc($sqlres)){
					// urls are stored like this:
					// http://www.mydomain.com,http://www.anotherdomain.co.uk
					// so i explode it to check them all
					$urls = explode(',', $row['valid_urls']);
						foreach($urls as $u){
							// this ereg makes sure that the $url is in the 'allowed' list,
							// and that the url in allowed is the start of the one being checked.
							// also checks that it's not a banned url
							if(ereg('^' . $u, $url) && !strpos($row['banned_urls'], $url)){
								return true;
							}
						}
				}
				return 'error6';
			}else{
				return 'error7';
			}
		}
	return 'error2';
}
?>

 

Okay now the problem. The url check seems to work absolutely fine, so long as I don't include any GET variables in the 'allowed' url list in the database.

For example..

The $url is: http://www.mydomain.com/index.php?foo=bar

In the database I have: http://www.mydomain.com

Which will validate the $url.

 

But If I change the url in the database to this:

http://www.mydomain.com/index.php?foo=bar

 

it will not validate, even though it's the same url. This also happens if I add just:

http://www.mydomain.com/index.php?f

 

But works fine with just the question mark:

http://www.mydomain.com/index.php?

 

I need to be able to specify file, and GET specific urls though.

If anyone can see what I'm doing wrong it'd be much appreciated.

 

Thanks

Link to comment
Share on other sites

Thanks techie, but that just verifies the the url is actually a url.

What I've got in my database is a list of urls that can and can't be used. Such as www.mydomain.com, or www.anotherdomain.com/thisfolder/file.php?foo=bar

 

I'm not wanting check that the given url is an actual url, just that it is in the allowed list, or more precisely that the begininning of it matches a url in the allowed list. So if the $url is:

http://www.mydomain.com/index.php?foo=bar

 

Then this url in the database would validate it:

http://www.mydomain.com/

or

http://www.mydomain.com/index.php?foo=

Link to comment
Share on other sites

okay. Seems I was wrong (as usual ::)), but it's just removing the http:// part along with the GET vars.

I'm not wanting to remove them. The problem is that for some reason my validation check wont work if I have a url with GET vars stored in my database. It will only work if the database url is a straight forward link.

It's not a problem with the $url var that I'm running through the check, as even if $url has GET's at the end it will work, so long as the one in the database doesn't.

Link to comment
Share on other sites

But I don't want to edit the $url variable :-\

The $url var should stay as it is. The preg match is just removing the GET vars off the end, which I want to keep.

 

All I want to do is compare the $url var with the $u var:

<?php
$urls = explode(',', $row['valid_urls']);
foreach($urls as $u){
	if(ereg('^' . $u, $url) && !strpos($row['banned_urls'], $url)){
		return true;
	}
}
?>

So the $url should start with $u. Which work so long as $u (the url collected from the database) doesn't include any GET vars.

Link to comment
Share on other sites

I'm checking banned urls as well, with the

!strpos($row['banned_urls'], $url)

because I just need to roughly check if the url is anywhere in the banned list, but I'm using the ereg on the allowed list because the url needs to start with one of the ones in the allowed list.

 

Basically if the url isn't in the allowed list you can't use it, even if it's not in the banned list either.

The banned list is more a system of filtering what pages on a server can and can't be used in the url.

So in the allowed list I could have:

http://www.mydomain.com/

which would allow any page on the domain to be used.. (http://www.mydomain.com/somepage.php, http://www.mydomain.com/sub/anotherpage.html)

 

But then in the banned list you can specify certain directories or just single files that can't be used.. such as:

http://www.mydomain.com/bannedfile.php

in the banned list would still allow all other urls on the domain, but not bannedfile.php

 

Hopefully that made a bit of sense..

Link to comment
Share on other sites

sure, here's the var dump:

var_dump($row['valid_urls'], $row['banned_urls']);

// outputs:
string(92) "http://localhost,http://www.gimppro.co.uk,http://www.test.gimppro.co.uk/img_test.php?foo=bar"
string(0) ""

at the moment 'banned_urls' doesn't contain anything.

if $url is: http://www.test.gimppro.co.uk/img_test.php?foo=bar

it wont validate. But if I change the url in $row['valid_urls'] to: http://www.test.gimppro.co.uk/img_test.php

Then it will. But I want to be able to check the GET as well.

 

and yes. It MUST be in valid_urls, but NOT in banned_urls.

 

But the thing is I can't see why the code I started with wont work!

Link to comment
Share on other sites

okay.. this is strange.

If I use this, instead of the ereg it works:

foreach($urls as $u){
if(strstr($url, $u)){
	return true;
}
}

But I need to make sure that $u is found at the beginning of $url. I then tried this (for the billionth time..):

foreach($urls as $u){
if(strpos($url, $u)){
	return true;
}
}

But that fails just as the ereg. I don't understand how strstr can tell me it exists, but strpos can't find it??

 

 

EDIT: got strpos to work with this:

if(($pos = strpos($url, $u)) !== false){
echo $pos;
echo 'YES!';
return true;
}

and it outputs:

0YES!

The reason it wasn't working before is 0 is boolean false.

 

I'll just test it with the urls properly (also checking $pos = 0) and let you know how it goes!

Link to comment
Share on other sites

Try this

 

ran a few tests seams okay

 


<?php
$check = "http://localhos";

if(CheckURL($check, false))
{
echo "allowed";	
}else{
echo "deny";	
}

function CheckURL($check, $full = true)
{
$allowstr= "http://localhost,http://www.gimppro.co.uk,http://www.test.gimppro.co.uk/img_test.php?foo=bar";
$denystr = "http://localhost/private";

$allow = explode(",", strtolower($allowstr));
$deny = explode(",", strtolower($denystr));
$check = strtolower($check);
if($full)
{
	return (in_array($check, $allow) && !in_array($check, $deny));
}else{
	$check = preg_quote($check,"/");
	$valid = false;
	foreach($allow as $V)
	{
		if(preg_match("%^$check%i", $V))
		{
			$valid = true;
			foreach($deny as $D)
			{
				if(preg_match("%^$check%i", $D))
				{
					$valid = false;
				}
			}
			if($valid) break;
		}
	}
	return $valid;
}
}
?>

 

of course tweak $full option.. for more advanced searching

 

EDIT: quick correction

Link to comment
Share on other sites

Thanks techie! it looks fine.. I've just got the strpos code to work though..

This is what I've got:

<?php
function check_url($id, $url){
	if($url == $_SERVER['REQUEST_URI']){
		return false;
	}

	$sql = "SELECT `valid_urls`, `banned_urls` FROM `user_settings` WHERE `user_id` = '" . mysql_real_escape_string($id) . "' LIMIT 1";
		if($sqlres = mysql_query($sql)){
			if(mysql_num_rows($sqlres) > 0){
				while($row = mysql_fetch_assoc($sqlres)){
					$urls = explode(',', $row['valid_urls']);
						foreach($urls as $u){
							// here's the, at last, working code
							if((($pos = strpos($url, $u)) !== false) && ($pos == '0') && !strpos($row['banned_urls'], $url)){
								return true;
							}
						}
				}
				return 'error6';
			}else{
				return 'error7';
			}
		}
	return 'error2';
}
?>

The actuall test is a little long, but it basically checks that the position can be found, then checks the $pos is 0, and checks that it's not in the banned field.

I've just tested it with several urls and it seems to be working fine ;D

 

It also looks a little shorter than your code. Not sure which is more reliable though...

 

Thanks

Link to comment
Share on other sites

well heres the short version

<?php
$check = "http://home.google.com";

if(CheckURL($check))
{
echo "allowed";	
}else{
echo "deny";	
}


function CheckURL($check)
{
$allowstr= "http://localhost,http://www.gimppro.co.uk,http://www.test.gimppro.co.uk/img_test.php?foo=bar,http://home.google.com";
$denystr = "http://localhost/private,http://mail.google.com";

$allow = explode(",", strtolower($allowstr));
$deny = explode(",", strtolower($denystr));
$check = strtolower($check);
return (in_array($check, $allow) && !in_array($check, $deny));
}
?>

:P

Link to comment
Share on other sites

Thanks. I'm gonna stick with mine though ;)

It works well enough, and doesn't seem to be any better or worse than yours. I'm just going to make a couple of minor changes to it so it works a bit better though.

 

Thanks for all your help today! really great!

 

topic is now solved!

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.