SitePoint Sponsor

User Tag List

Results 1 to 19 of 19

Hybrid View

  1. #1
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    308
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Preventing direct access to included files

    Hi,

    I have done some research and found a way to prevent access to included files using the below code:

    PHP Code:
    if (count(get_included_files()) == 1) exit('Access denied.'); 
    or

    PHP Code:
    if (count(get_included_files()) == 1header('Location: /* home page or login page */'); 
    Is this a good or secure way to do prevent direct access to files that are not meant to be accessed directly such as PHP script files? Do you have any better alternative methods?

  2. #2
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    You don't stipulate whether you do this or not, but keep them out of (above) your document root.

    /var/www/includes/sensitive.php
    /var/www/html/www-root/websiteA.com/index.php
    /var/www/html/www-root/websiteB.com/index.php

    Name them .php files (not .inc files, like we used to see in the past) so they get run through the parser in case you become susceptible to some directory traversal attack.

    I remember using a similar system. From memory, in pseudocode the first line was something to the tune of:
    Code:
    if( $_SERVER['SCRIPT_NAME'] === self) die();
    When I started using OOP it became a pain to start every class file off with that line, and I never suffered (touches wood) from directory traversal attacks, so dropped the idea.

  3. #3
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,786
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Cups View Post
    I remember using a similar system. From memory, in pseudocode the first line was something to the tune of:
    Code:
    if( $_SERVER['SCRIPT_NAME'] === self) die();
    When I started using OOP it became a pain to start every class file off with that line, and I never suffered (touches wood) from directory traversal attacks, so dropped the idea.
    As the intention of the code is to stop the file being directly accessed you'd just need that one statement at the top of each file. The OOP code would come after it and would not need to test for that individually.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  4. #4
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    308
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the suggestion. What I am working on is a simple application that does a certain task with some sort of admin panel which requires login. This will be distributed. So, I can't ask everyone to put those folders above the root. That's why I am trying to find a solution within the system itself. You can think of it like a CMS, but a very, very simple one.

  5. #5
    SitePoint Wizard
    Join Date
    Oct 2005
    Posts
    1,832
    Mentioned
    5 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by nayen View Post
    Thanks for the suggestion. What I am working on is a simple application that does a certain task with some sort of admin panel which requires login. This will be distributed. So, I can't ask everyone to put those folders above the root. That's why I am trying to find a solution within the system itself. You can think of it like a CMS, but a very, very simple one.
    The idea to declare a constant at your entry point and testing for it and dying if it hasn't been set was previously mentioned. This is the method used by many scripts. It is effective even if checking for a defined constant at the top of every PHP file is a pain.

    Have you considered putting the included files in their own folder (below public_html) and then putting an htaccess file in there with a "deny from all" statement to deny direct access to the included files? Then your scripts could access the files but direct access would be blocked by the server (if you are using Apache). Normally, I try to keep all my important scripts above public_html. But for any includes below public_html, I check for a defined constant and block access with htaccess.

  6. #6
    SitePoint Evangelist pompopom's Avatar
    Join Date
    Feb 2004
    Location
    Huldenberg (Belgium)
    Posts
    426
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    and what about the good old .htaccess file?
    The Path of excess leeds to the tower of wisdom (W. Blake)

  7. #7
    SitePoint Guru bronze trophy
    Join Date
    Dec 2003
    Location
    Poland
    Posts
    930
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)
    I have seen various libraries use checking for a constant that is defined in some common script and then use this at the beginning of every file:
    PHP Code:
    if (!defined('MY_CMS_NAME')) exit('Access denied.'); 
    I like this method because it also disallows including the files from scripts outside the library they are part of therefore increasing security by a tiny little bit.

  8. #8
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    308
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Lemon Juice View Post
    I have seen various libraries use checking for a constant that is defined in some common script and then use this at the beginning of every file:
    PHP Code:
    if (!defined('MY_CMS_NAME')) exit('Access denied.'); 
    I like this method because it also disallows including the files from scripts outside the library they are part of therefore increasing security by a tiny little bit.
    Thanks for the pre-defined constant tip, but why would you want to display an "Access denied" message if that is a critical file? Wouldn't it be better to redirect the visitor (or the bad guy who is looking for a gap in your system) to the home page or login page?

    By the way, I got that idea I used in my OP from the following page:

    http://stackoverflow.com/a/409738

    Some comments say that it is superior to checking a constant, that's why I wanted to ask here for your opinions too.

    Quote Originally Posted by pompopom View Post
    and what about the good old .htaccess file?
    I actually don't want to use htaccess if I don't have to, because I don't want to make the assumption of all the users will be on Apache servers.

  9. #9
    SitePoint Evangelist pompopom's Avatar
    Join Date
    Feb 2004
    Location
    Huldenberg (Belgium)
    Posts
    426
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by nayen View Post
    I actually don't want to use htaccess if I don't have to, because I don't want to make the assumption of all the users will be on Apache servers.
    What makes you think .htaccess only works on Apache?
    It's true that Apache allows a lot more nifty features, but blocking access is a standard .htaccess thing and AFAIK works on IIS also.
    The Path of excess leeds to the tower of wisdom (W. Blake)

  10. #10
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    308
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pompopom View Post
    What makes you think .htaccess only works on Apache?
    It's true that Apache allows a lot more nifty features, but blocking access is a standard .htaccess thing and AFAIK works on IIS also.
    Never heard that, do you have a source to confirm this?

  11. #11
    SitePoint Guru bronze trophy
    Join Date
    Dec 2003
    Location
    Poland
    Posts
    930
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by nayen View Post
    Thanks for the pre-defined constant tip, but why would you want to display an "Access denied" message if that is a critical file? Wouldn't it be better to redirect the visitor (or the bad guy who is looking for a gap in your system) to the home page or login page?
    This is just an example, do whatever you want when the check is false. I think the best idea would be to display a standard "404 page not found" page that you have for non-existent pages, without a redirect (you would then do an internal redirect with include "page404.html"; ). This way an attacker would not be able to tell if he targetet a real file or not. But don't forget about setting the 404 response code in that case.

    Quote Originally Posted by nayen View Post
    By the way, I got that idea I used in my OP from the following page:

    http://stackoverflow.com/a/409738

    Some comments say that it is superior to checking a constant, that's why I wanted to ask here for your opinions too.
    I wouldn't say it's superior, it's just more convenient because you have all the code in one place without a need to define anything. However, I like the constant better because it not only checks if the file is included but also if it was included from the proper context, that is after initializing the library/framework in question.

  12. #12
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    308
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Lemon Juice View Post
    This is just an example, do whatever you want when the check is false. I think the best idea would be to display a standard "404 page not found" page that you have for non-existent pages, without a redirect (you would then do an internal redirect with include "page404.html"; ). This way an attacker would not be able to tell if he targetet a real file or not. But don't forget about setting the 404 response code in that case.

    I wouldn't say it's superior, it's just more convenient because you have all the code in one place without a need to define anything. However, I like the constant better because it not only checks if the file is included but also if it was included from the proper context, that is after initializing the library/framework in question.
    Thank you very much for the clarification.

  13. #13
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by nayen
    You can think of it like a CMS, but a very, very simple one.
    That's funny, me too.

    I'm just trying to work out how to have the core admin files (there are only 4 in a folder called /edit) live in a central place so that server X can have n amount of websites but only sharing one sole set of edit files.

    I may post my problem on the SP server setup forum if I cannot find a ready solution, its going to be something to do with a rewrite rule somewhere, but I'm getting dizzy trying to work out if that should be in the httpd.conf file or elsewhere ...

  14. #14
    SitePoint Addict kduv's Avatar
    Join Date
    May 2012
    Location
    Maui, HI
    Posts
    211
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Cups View Post
    That's funny, me too.

    I'm just trying to work out how to have the core admin files (there are only 4 in a folder called /edit) live in a central place so that server X can have n amount of websites but only sharing one sole set of edit files.
    You could always just add a list of allowed IPs to the PHP file(s) and use the $_SERVER['REMOTE_ADDR'] variable to check it against.
    Keith
    Freelance web developer
    http://www.duvalltech.com/

  15. #15
    SitePoint Enthusiast mildfoam's Avatar
    Join Date
    May 2010
    Location
    Australia.
    Posts
    56
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    this code isn't mine, but actually hope it can works to you.

    just put this code to every script that people can access.

    PHP Code:
    define('access',1); 
    otherwise, use this script to script that you won't let people access it directly

    PHP Code:
    if(!defined('access'))
    {
        echo 
    'You cannot access this file directly.';
        exit;

    Object Oriented Programming Fans Boy ?

  16. #16
    SitePoint Addict kduv's Avatar
    Join Date
    May 2012
    Location
    Maui, HI
    Posts
    211
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by mildfoam View Post
    this code isn't mine, but actually hope it can works to you.

    just put this code to every script that people can access.

    PHP Code:
    define('access',1); 
    otherwise, use this script to script that you won't let people access it directly

    PHP Code:
    if(!defined('access'))
    {
        echo 
    'You cannot access this file directly.';
        exit;

    That's the same thing Lemon Juice said.
    Keith
    Freelance web developer
    http://www.duvalltech.com/

  17. #17
    SitePoint Guru bronze trophy TomB's Avatar
    Join Date
    Oct 2005
    Location
    Milton Keynes, UK
    Posts
    988
    Mentioned
    9 Post(s)
    Tagged
    2 Thread(s)
    Let's take a step back here and look at the bigger picture. How much of an issue is this? These somewhat convoluted solutions are all well and good but the simplest method is just using properly formatted code in the first place.

    If all your code is inside classes or even functions, even if your first line of defence (keeping them outside the web directory) fails, even if the script is executed it can not do anything detrimental to your server. No code will actually get processed other than a class/function being defined.

    The whole idea of adding lines of code to each file is ridiculous because even if the file is run in isolation it should not be possible to have it cause any problems on the server or reveal anything useful to an attacker.

    Beyond that, it limits the script's reusability and makes testing it difficult as well as moving it to a different project - your new project needs to remember to define that constant. What it the files for that project define its own constant? Messy. The crux of the issue is a poor separation of concerns. The script itself should not be governing its own access rights.

  18. #18
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    308
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by TomB View Post
    Let's take a step back here and look at the bigger picture. How much of an issue is this? These somewhat convoluted solutions are all well and good but the simplest method is just using properly formatted code in the first place.

    If all your code is inside classes or even functions, even if your first line of defence (keeping them outside the web directory) fails, even if the script is executed it can not do anything detrimental to your server. No code will actually get processed other than a class/function being defined.

    The whole idea of adding lines of code to each file is ridiculous because even if the file is run in isolation it should not be possible to have it cause any problems on the server or reveal anything useful to an attacker.

    Beyond that, it limits the script's reusability and makes testing it difficult as well as moving it to a different project - your new project needs to remember to define that constant. What it the files for that project define its own constant? Messy. The crux of the issue is a poor separation of concerns. The script itself should not be governing its own access rights.
    Thank you a lot for this additional info. Actually, I haven't been using classes, perhaps I should revise my scripts and create a class system as soon as possible.

  19. #19
    SitePoint Guru bronze trophy
    Join Date
    Dec 2003
    Location
    Poland
    Posts
    930
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)
    TomB, you may have a good point here. I've never used such techniques but thought they might be useful for distributed libraries. But you are right - there is no real threat with leaving php files with classes as they are. Someone might want to use this to prevent others from guessing file names by entering them in a web browser but that's something I'd describe as security through obscurity.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •