Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: [PHP] Basic PHP includes

  1. #1
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,156
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default [PHP] Basic PHP includes

    1) CODE TITLE: Basic PHP includes

    2) AUTHOR NAME/NOTES: Daniel Ross

    3) DESCRIPTION: This script will include various 'pages' of code into an existing page.

    4) CODE:
    Code:
    START OF PAGE:
    <?php
    function inc() {
    $inc = 'default';
    $page = isset($_GET['page'])?$_GET['page']:$inc;
    if (file_exists('includes/'.$page.'.txt')) {
    $inc = $page;
    }
    include('includes/'.$inc.'.txt');
    }
    ?>
    
    LINE OF INCLUSION:
    <?php inc(); ?>
    This is very basic PHP for those of us who use it daily, but I just got a question from someone wanting to know how to use PHP includes. Rather than just telling them to use <?php include($_GET['page']); ?>, I suggest this because:
    1. It error checks.
    2. By doing so, it prevents hacking/XSS.


    Anyway, it's not a standard thing for the library, but I know some people would find it useful.
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  2. #2
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    2. By doing so, it prevents hacking/XSS.
    Code:
    includer.php?page=..&#37;2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd%00
    /EDIT: Oh no, PHP has a built-in check for this, it's OK. It doesn't check it at the file_exists() level, however. It just translates NUL to literal '\0' from GET and POST. There may be a way around this, depending on site structure. I'm checking it out now.
    /FURTHER EDIT: No, GET, POST, and cookies all seem to be safe.
    Last edited by Twey; 09-09-2007 at 12:35 AM.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  3. #3
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,156
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    At least it gets around anyone just supplying a URL directly.
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  4. #4
    Join Date
    May 2006
    Location
    Sydney, Australia - Near the coast.
    Posts
    1,995
    Thanks
    0
    Thanked 8 Times in 7 Posts

    Default

    Quote Originally Posted by Twey View Post
    Code:
    includer.php?page=..&#37;2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd%00
    /EDIT: Oh no, PHP has a built-in check for this, it's OK. It doesn't check it at the file_exists() level, however. It just translates NUL to literal '\0' from GET and POST. There may be a way around this, depending on site structure. I'm checking it out now.
    /FURTHER EDIT: No, GET, POST, and cookies all seem to be safe.
    I'm sure you can do this basename('myurlhere') to prevent going through directories.
    Peter - alotofstuffhere[dot]com - Email Me - Donate via PayPal - Got spare hardware? Donate 'em to me :) Just send me a PM.
    Currently: enjoying the early holidays :)
    Read before posting: FAQ | What you CAN'T do with JavaScript | Form Rules | Thread Title Naming Guide

  5. #5
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,156
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    Makes a lot of sense, actually.

    Code:
    START OF PAGE:
    <?php
    function inc() {
    $inc = 'default';
    $page = isset($_GET['page'])?$_GET['page']:$inc;
    $page = basename($page);
    $page = strpos($page,'.')?substr($page,0,strpos($page,'.')):$page;
    if (file_exists('includes/'.$page.'.txt')) {
    $inc = $page;
    }
    include('includes/'.$inc.'.txt');
    }
    ?>
    
    LINE OF INCLUSION:
    <?php inc(); ?>
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  6. #6
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    Code:
    <?php
      function inc() {
        $page = isset($_GET['page'])
          ? $_GET['page']
          : 'default';
    
        if(strpos($page, '.') !== false
            || strpos($page, '/') !== false
            || !file_exists($page = 'includes/' . $page . '.inc.php'))
          $page = 'includes/error.inc.php';
    
        include($page);
      }
    ?>
    You forgot that:
    • You're including these files as PHP, so storing them with a .txt extension isn't safe (on most servers) since they may contain sensitive PHP code;
    • strpos() will return 0 if the character is at the start of the string, which type-converts to boolean false, so you must always check its return value with non-type-converting operators (=== and !==). In this case, by prepending a . to the start of the path name one could bypass your check (and still access interesting files like .htaccess and .htpasswd).
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  7. #7
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,156
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    1. I assumed the included pages were html only, for different elements displayed in a div, based on the original request.. But for maximum compatibility/functionality, that's a good point.
    2. Wouldn't (strpos(a,b)) when b does exist as the first character evaluate to true?
    If not, then--
    echo "" ? '' : (0 ? '' : 'PHP is weird.');
    I know you would need to check it in some situations, if comparing, but didn't realize it actually returned as false if it was first, for all usable purposes...


    Also, really, you don't need the basename() function now that I think about it. Simply use the older version of the code, and it will be sure the file exists before including. 1. You might want a subfolder of the target directory, and, 2. you can't hack with it anyway, so no need for security. Not like you'll really need to error correct your own links, or so one would hope...
    Last edited by djr33; 09-10-2007 at 09:15 PM.
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  8. #8
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    I assumed the included pages were html only, for different elements displayed in a div, based on the original request.
    Then the pages should be included as HTML, rather than processed with PHP. PHP is, however, more useful.
    Wouldn't (strpos(a,b)) when b does exist as the first character evaluate to true?
    No. strpos() can return two types: boolean false, if the character is not found at all, or the position of the character in the string. The first position in an array, string, &c. in PHP is 0; therefore, the first character is at position 0.
    If not, then--
    echo "" ? '' : (0 ? '' : 'PHP is weird.');
    Not really. The indexing position is the same in most languages, but generally they have a less confusing "not found" value, such as null or -1.
    Also, really, you don't need the basename() function now that I think about it.
    Not if you do it my way, with the path check.
    Simply use the older version of the code, and it will be sure the file exists before including.
    No, even without the NUL bug it's possible to read any file on the filesystem that ends with .txt, which is a potential security risk. If you wanted subdirectories, it's possible to simply remove the check for /:
    Code:
    <?php
      function inc() {
        $page = isset($_GET['page'])
          ? $_GET['page']
          : 'default';
    
        if(strpos($page, '.') !== false
            || !file_exists($page = 'includes/' . $page . '.inc.php'))
          $page = 'includes/error.inc.php';
    
        include($page);
      }
    ?>
    The check for . will prevent paths with .. in them. Another option is to do:
    Code:
    <?php
      function inc() {
        $page = isset($_GET['page'])
          ? $_GET['page']
          : 'default';
    
        if(strpos($page, './') !== false
            || !file_exists($page = 'includes/' . $page . '.inc.php'))
          $page = 'includes/error.inc.php';
    
        include($page);
      }
    ?>
    This also allows files with dots in the path, whilst at the same time disallowing paths such as ../file and ././././file, the latter of which is a commonly-used measure for bypassing buggy security systems. It's technically possible to have directories with . at the end of their names, but I've never seen one.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  9. #9
    Join Date
    Jun 2007
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    2. By doing so, it prevents hacking/XSS.

    It sounds good.

  10. #10
    Join Date
    Aug 2006
    Posts
    116
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Hi

    Im thinking about learning php, so if you dont mind me asking what does the code above actualy do?

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
  •