Search code examples
phpfile-iophp-stream-wrappers

How to restrict file system access in PHP?


Someone knows a trick to have a PHP script self-restrict access to the file system (fopen, file_get_contents etc.)?

Such calls should be blocked except for a handful of selected file names (log file, access to /tmp and similar).

This is not a security thing, but rather a means of forcing the development team not to access the file system directly (and detect spots in existing code, where this is already the case). We want to see an exception in that case (which gets caught and reported), as the content of such files must be accessed by other means.

I was thinking about implementing my own streamWrapper for the file:// protocol, but apparently there is no way to extend the built-in filewrapper class.


Solution

  • Option #1

    You can use open_basedir which is a php.ini directive to limit the directories the app has access too. The directories can be semicolon separated so you can just list the directories you want the app to access including the /tmp folder.

    The caveat is that this also affects things like include, require.

    Option #2

    You could rename them using rename_function or runkit_function_rename and then wrap the renamed versions with your own logic.

    Quote from the documentation:

    Renames a orig_name to new_name in the global function table. Useful for temporarily overriding built-in functions.

    Example:

    rename_function('file_get_contents', 'nouse_file_get_contents');
    
    function file_get_contents($filename, $use_include_path = false, $context, $offset = -1, $maxlen) {
        //
        // Do some validation here
        //
        return nouse_file_get_contents($filename, $use_include_path, $context, $offset, $maxlen);
    }
    

    Option #3

    You could setup some coding standards for your devs and write some unit tests that run as part of the deployment before things are pushed to production. Not sure what your release procedures are but these types of things should be caught before production.