2

I have the line

xmlhttp.open("GET","file.php?id=4",true);

This does not work since file.php is not in the same folder but rather in a different private folder not visible to the public.

Is there a way to use the open function to open a file in a different folder?

1
  • 1
    If your AJAX request can access the script, other people can also. Commented Sep 16, 2012 at 17:58

2 Answers 2

2

That's fundamentally impossible.

If you want to send an HTTP request to it, it must be visible to the public over HTTP.

Sign up to request clarification or add additional context in comments.

5 Comments

If I move file.php in the same folder (public folder) can I make it so people can't type in the url to get to that file?
@SLaks Can you provide a code example using a one-time pad key?
@programm3r Technically no, but you could verify that the request coming in is sent through AJAX, and then finish or send back like a 404 if not AJAX. I'm pretty sure this could be faked, but at least it makes it harder
@ianpgall: The attacker can load the page, not execute the JS, then use the one-time key.
@SLaks I'm not sure what you mean. I was responding to the first comment by programm3r, to help distinguish between a normal and AJAX HTTP request.
1

You can only request files from within the public webspace. To access files outside the public webspace you need a script in the public webspace that can fetch the contents from the private folder, e.g.

<?php // file.php in the public webspace

    $allowedFiles = array(
        1 => '/path/to/private/space/on/server/file1.txt',
        2 => '/path/to/private/space/on/server/file2.txt',
        3 => '/path/to/private/space/on/server/file3.txt',
        4 => '/path/to/private/space/on/server/file4.txt',
    );

    $id = filter_var($_GET['id'], FILTER_VALIDATE_INT);

    if (isset($allowedFiles[$id])) {
        readfile($allowedFiles[$id]);
    }

Now when you do

xmlhttp.open("GET","file.php?id=4",true);

the script will send the content of

/path/to/private/space/on/server/file4.txt

to the client.

Edit regarding some comments:

  • Note that readfile will not execute the file contents. If you need to send the results of a PHP script, you have to use include instead of readfile. Please refer to the Manual for details.

  • The above approach is effectively the same as most of the frameworks nowadays use. You have one single script that acts as a gateway into your application (kind of like a Front Controller pattern). This script accepts any and all requests (think mod_rewrite) to your application and is the only publicly accessible PHP file. It will bootstrap your application and then determine from the URL (or whatever you seem fit) what file, usually a controller when using MVC, in the private space should be instantiated and called.

18 Comments

Could you provide an example?
But this is no different from directly accessing it in a public place - this script would just be a middle man that adds unnecessary overhead. Sure, it's not directly accessible in the public root, but the user could still access the "private" file by accessing the script...and by accessing the script, I mean typing its URL in the browser and getting its result (which would be the private file)
@Gordon Would this code make it so that I could call an external PHP file using xmlhttp.open()?
@SLaks I put my comment above to see if Gordon is saying something different than you.
@programm3r what is an "external" file to you? the script above would act as a proxy file to an otherwise not publicly accessible file. there is no other way short of moving the private files into the public root.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.