PHP Include Only from a Specified Range

Discussion in 'PHP' started by ~*77*~, Dec 4, 2007.

  1. #1
    I was just looking at an old script I inherited and the security is weak. If a noob like me can notice that, it must be obvious...

    The point of it is to include a flat file with a numerical file name as part of a basic CMS. This is the actual portion where the page is included:

    <?php 
    
    if(!is_numeric($file)) { 
    $file = "0"; 
    echo 'Sorry, page not found! Return to <a href="', $item,'/1">Page 1</a>.'; 
    exit;   
    } 
    
    include ("./$item/$file"); ?>
    Code (markup):
    All that really does is see if it is a number greater than zero. If you enter zero, enter a number higher than what exists, or if you try to enter another web address you get errors. It does keep people from loading malicious garbage, but it doesn't do what I thought it was doing all this time. Only if you enter letters you get the proper "Sorry" message and a link back to the first page.

    I believe a quick fix to make this better may be very simple and figured I would ask for help here.

    The script is aware of variables that should make the range of what is acceptable very narrow:

    "1" is always the first page and the lowest it should ever allow.
    "$pages" is the total number of pages and the highest it should ever allow.
    "$item" is the directory it needs to stay within.
    "$file" is the current page.

    So, I guess to anyone with any PHP smarts (not me), there is probably a simple way to set $file to only be read if it is in the $item directory and within the (range(1, $pages).

    Right?

    Thanks in advance for any help...
     
    ~*77*~, Dec 4, 2007 IP
  2. *louie*

    *louie* Peon

    Messages:
    48
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    0
    #2
    Check for file existence as well:

    
    if (file_exists($file)) {
        include ("./$item/$file");
    } else {
        echo "The file $file does not exist";
    }
    
    PHP:
     
    *louie*, Dec 4, 2007 IP
    ~*77*~ likes this.
  3. tonybogs

    tonybogs Peon

    Messages:
    462
    Likes Received:
    13
    Best Answers:
    0
    Trophy Points:
    0
    #3
    This will work, but it will also return TRUE if /item/$file/ is a directory.

    Try is_file() for a more robust check

    Hope this helps
     
    tonybogs, Dec 4, 2007 IP
  4. ~*77*~

    ~*77*~ Peon

    Messages:
    72
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #4
    didn't see a link yulin11 - but thanks guys. I am on the right path now and it works much better already.
     
    ~*77*~, Dec 5, 2007 IP