Hi,
Currently the only real "solution" to Full Path Disclosure vulnerabilities in software developed in PHP is to keep display_errors disabled. Even if a developer wishes to prevent disclosures at the application level instead, it is not currently possible with the current implementation of PHP:
-
The output text of Parse and Fatal Errors cannot be modified, far as I can tell
-
Some errors can be triggered by specially crafted requests and occur before the application initializes (think max_input_vars, and other input-related errors)
-
Custom error handlers are needed to remove path strings for other errors, but if multiple frameworks are used together, the error handlers may conflict on which strings should be removed. Only 1 shutdown function can actually be used.
I propose that the default error handling in PHP be updated as follows:
-
Include a new ini directive for fpd_prevention, defaulting to On or a string for replacement, like the ever-popular [path]
-
Provide a new function hide_fpd_path (or pick a better name), defined as:
function hide_fpd_path($path, $replacement_string = '')
$replacement_string would default to the system defined [path] string or other ini value. The function provides an interface to a registry of paths that should not appear in error output, should an error occur.
-
Automatically treat the paths in include_path (and updated by set_include_path) as if they were registered with hide_fpd_path, using the default replacement string or other [include-path] string. Because of set_include_path's existence, it may be best to apply this at error time.
-
Automatically register the containing path of PHP_SELF at initialization. This will deal will fatal errors occurring before the application can specify its paths, such as when max_input_vars is exceeded by a crafted request.
-
When outputting any error, including
E_ERROR
or E_PARSE, filter the file paths with this new registry, applying the most specific pathnames first. Now the security implications of display_errors are largely mitigated. -
Many custom error handlers use debug_backtrace or debug_print_backtrace. I would suggest adding a new DEBUG_BACKTRACE_SKIP_FPD constant in case the error handler absolutely does not want the paths filtered by PHP. However, because there are cases where multiple frameworks have error handlers with different internal filters, I believe the default behavior of debug_backtrace should pre-filter those. This way, developers of other modules and plugins can still add filters, regardless of whatever framework is on top.
By resolving full path disclosures at the scripting engine level, or at least providing a built-in solution for them (which per my suggestion could be disabled if system administrators don't want to use it), PHP can help change the conversation on full path disclosures:
Many instances of full-path disclosure vulnerabilities currently go unresolved because there is a debate whether they are configuration issues (of display_errors) vs bugs in the application, because some developers are resistant to writing software that works well in tandem with the software of other developers, and because many developers do not want to release security patches every time a fatal error is found, especially when it is still possible to cause fatal errors that the application has no control over. The question is sometimes raised whether FPD issues are really worthy of being considered security issues at all; however, I have seen authorities issue CVEs for them. I think this suggestion provides a solution for all these camps of people.
Thanks,
Ted
Hi Ted,
- Include a new ini directive for fpd_prevention, defaulting to On or a string for replacement, like the ever-popular [path]
[...]- Automatically register the containing path of PHP_SELF at initialization. This will deal will fatal errors occurring before the application can specify its paths, such as when max_input_vars is exceeded by a crafted request.
Could you give some concrete examples of what an error message would
look like before and after this change? I'm trying to understand what
the tradeoff might be for users trying to track down where an error has
occurred.
Regards,
Rowan Collins
[IMSoP]