k5hitchcock Posted March 7, 2008 Share Posted March 7, 2008 Here is part of the log I got from my host manager (my website is the www.krishitchcock.com part): 87.118.118.172 - - [06/Mar/2008:11:50:46 -0600] "GET /favicon.ico HTTP/1.1" 404 - "http://www.krishitchcock.com./index.php?a=http://www.hoopster.1142degrees.com./articles/ra.jpg?" "Opera/9.26 (Windows NT 6.0; U; es-es)" and here is what I suspect is the offensive code: if(!isset($a)) { include 'home.php'; } else { include "$a.php"; } That is the code of the index page content, which loads based on the $a value. My links are named index.php?a=whatever I think this is the only time I've used this code, which is why I assume this is the offensive code. The only thing is, I have another site that uses the same code and I've never had a problem with that one. Quote Link to comment Share on other sites More sharing options...
kenrbnsn Posted March 7, 2008 Share Posted March 7, 2008 Never trust input from the user. Always validate. In your case, first check if $_GET['a'] contains "http://" and reject that immediately, then check to see if the value passed is one you expect. You can do that by putting the expected values in an array and checking whether the value passed is in the array, if not, reject it. If hackers found one of your sites, they will find the other one eventually. Fix that code also, so they can't hack you there also. Ken Quote Link to comment Share on other sites More sharing options...
unsider Posted March 7, 2008 Share Posted March 7, 2008 Better hit the books on security and validation, and make sure you backup your DBs or any other info, because like Ken said, they will probably find your other sites too. Quote Link to comment Share on other sites More sharing options...
k5hitchcock Posted March 7, 2008 Author Share Posted March 7, 2008 <?php if(!isset($a)) { include 'home.php'; }else{ $a = preg_replace('/\W/si', '', $_GET['a']); include('./'.$a.'.php'); } ?> Does this look like it would solve the issue? Its removing all non alpha-numeric characters from the input. Quote Link to comment Share on other sites More sharing options...
unsider Posted March 7, 2008 Share Posted March 7, 2008 Ya that looks pretty stable, and I'm certain there are scripts that remove any questionable user input. Google search and you can base your security off of a few scripts. Good luck protecting your stuff, it's going to be my biggest issue when the time comes. Quote Link to comment Share on other sites More sharing options...
k5hitchcock Posted March 7, 2008 Author Share Posted March 7, 2008 thanks y'all! Quote Link to comment Share on other sites More sharing options...
corbin Posted March 7, 2008 Share Posted March 7, 2008 In this situation, you could always do this: (note: I've never actually used this on a site as I just now came up with it, so there might be a few little bitty bugs with it, but as far as I can tell, it should work fine) $a = (isset($_GET['a'])) ? trim($_GET['a']) : 'home.php'; $real_a = realpath($a); $file_root = realpath('includes/pages'); //this would be set to where you wanted files to be able to be included under.... //in this case the subfolder includes and then pages if($real_a && strpos($real_a, $file_root) === 0 && file_exists($real_a)) { include $real_a; } else { include 'home.php'; } Quote Link to comment Share on other sites More sharing options...
k5hitchcock Posted March 7, 2008 Author Share Posted March 7, 2008 haha can you explain to me what that does specifically? Quote Link to comment Share on other sites More sharing options...
corbin Posted March 8, 2008 Share Posted March 8, 2008 realpath takes a path name (relative or what ever) and returns the actual path. For example, let's say I ran: C:\Users\Corbin\Desktop>php -r "echo realpath('../');" C:\Users\Corbin\ See how it takes the path "../" and converts it to where it's really pointing? Let's say I have the code from my last post at http://somesite.com/page.php and my webroot is Y:\web_files\corbin\html\, if someone puts in '../' for the get variable a, the realpath() call would return "Y:\web_files\corbin". So what does this accomplish? Oh crap.... I just realized something. Ignore my code from earlier and pretend it was the following instead: $a = (isset($_GET['a'])) ? trim($_GET['a']) : 'home.php'; $real_a = realpath('includes/pages/'.$a.'.php'); $file_root = realpath('includes/pages'); //this would be set to where you wanted files to be able to be included under.... //in this case the subfolder includes and then pages if($real_a && strpos($real_a, $file_root) === 0 && file_exists($real_a)) { include $real_a; } else { include 'home.php'; } That means that $real_a would contain the real path of what the user entered (as relative to includes/pages). For example, if someone entered ?a=page1, $real_a would be Y:\web_files\corbin\html\includes\pages\page1.php $file_root in the meantime would be Y:\web_files\corbin\html\includes\pages. int strpos ( string $haystack , mixed $needle [, int $offset ] ) Returns the numeric position of the first occurrence of needle in the haystack string. Unlike the strrpos() before PHP 5, this function can take a full string as the needle parameter and the entire string will be used. http://php.net/strpos That means that strpos($a, $b) returns the offset of the first occurance of $b in $a. Example: $a = 'Corbin was here.'; echo strpos($a, 'b'); //echos 3 (counting starts from 0) echo strpos($a, 'h'); //11 echo strpos($a, 'c'); //0 At this point, you may be wondering what the purpose of this is.... Obviously in this scenario you would want to create a folder where people could only access files under that. (For example Y:\web_files\corbin\html\includes\pages\.) Because of the way file systems are setup, a filepath includes all of its parents. (For example--in Y:\web_files\corbin\html\includes\pages\ web_files is the parent of corbin which is the parent of html which is the parent of html which is the parent of includes which is the parent of pages. That means that in theory any file path includes all of the folders above it, basically where exactly it is. "But wait," you say, "What about '../' and '/'?!" (Wow I must be tired if I'm quoting you before you talk..... weird.... hypothetical talking? hmmmm rambling weeeeee) Anyway, realpath() takes a path and evaluates all of the symbolic things such as '..' and '/'. For example, if a php script were ran in C:\Some\crazy\long\directory\tree\omg\this\is\long\and\Ive\never\seen\this\many\forward\slashes\before and the script simply had <?php echo realpath('/'); ?> in it, the output would be C:\. Under the same directory, realpath('..\..\') would say C:\Some\crazy\long\directory\tree\omg\this\is\long\and\Ive\never\seen\this\many So by using realpath, unless there is a bug in it, you will always have the real path (hehehehe) of a file. So, if you have C:\Some\Folder\ and you know that the strpos() position of C:\Some is 0, then you know that C:\Some\Folder\ is under C:\Some. (It's useful to note at this point that strpos() returns an integer or a boolean false, hence why === is used instead of == since boolean false and 0 would be considered the same thing with ==.) Anyway, I can feel my self rambling (for the past 20 lines), so I'll just post this now, and I'm sure if you have questions you will ask them. Quote Link to comment Share on other sites More sharing options...
Psycho Posted March 8, 2008 Share Posted March 8, 2008 How many possible values do you have for $_GET['a']? Instead of stripping out values that shouldn't be in the result I ONLY accept the ones I know should be accepted. <?php switch ($_GET['a']) { case 'page1': case 'page2': case 'page3': case 'page4': case 'page5': include "$a.php"; break; default: include 'home.php'; break; } ?> Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.