RE: [PHP-DEV] Disabling PHP tags by php.ini and CLI options
| From: | John Crenshaw | Date: | Tue, 10 Apr 2012 18:13:59 +0000 |
| Subject: | RE: [PHP-DEV] Disabling PHP tags by php.ini and CLI options | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-59665@lists.php.net to get a copy of this message | ||
From: yohgaki@gmail.com [mailto:yohgaki@gmail.com] On Behalf Of Yasuo Ohgaki
>
> Hi all,
>
> This is the RFC as in the title.
> Although it's not a direct security measure, but it's related to critical security
> problem prevention.
>
> If you are not familiar to how to execute arbitrary PHP code, steal data from RDBMS via SQL
> injection and LFI, it may be interesting.
>
> This RFC will not break any existing code. Programmers may keep full backward compatibility
> while getting better security.
>
> https://wiki.php.net/rfc/nophptags
The proposed change will NOT make it safe to write require $_GET['name'];
Nothing can ever make that code safe. Even with remote inclusion turned off, even with php tags
disabled. That code is fundamentally broken. It uses an uncontrolled input to execute arbitrary code
and is only slightly more difficult to exploit than eval($_GET[foo']). In most systems you can
upload *anything* with a .jpg extension and the app will take it, so you can still include the file,
and the contents can drop straight into script, no tag needed. If the temporary upload directory is
accessible to the PHP process at all you can also include the file, regardless of extension or
content.
Alternately, in the unlikely case that file contents of uploads are validated, or the exploit file
is otherwise not fully under control, you could use a noop slide of sorts (multiline comment,
string, or docblock) to "slide" past any obligatory starting boilerplate or incontrollable
garbage in a file to quickly reach the code point. Honestly it would be far harder to craft an
attack file if you *REQUIRED* the file to start with <?php, since many file formats have
obligatory tags in the first few bytes. If the file starts in code mode these tags can be
terminated/jumped into a slide in a vast variety of ways (
; or ;/* or
.', just to name a few.) PHP will give a notice, but otherwise happily continue
(assuming an alphanumeric tag, which is most common).
If that is too complicated, you could bypass the need for a file entirely by using data:// or
php://stdin to effectively turn the require into an eval.. I'm sure there are any number of
other inventive exploits that I haven't even thought of.
The supposition that a user can (let alone will) make this code secure by disabling script tags is
insane. It doesn't actually prevent this type of exploit in the first place. No shared host or
distro could possibly get away with disabling this by default, because of the impact to legacy code,
and someone who wrote "require $_GET['name']" isn't watching security on
their side anyway. There's simply no sane reason for such an option, especially globally.
John Crenshaw
Priacta, Inc.