[RFC][DISCUSSION] Script only includes

php.internals

Yasuo Ohgaki

11 years ago
Hi all, Some of you are tired with this topic, but please take a look the RFC [RFC] Script only includes - this is 3rd version. https://wiki.php.net/rfc/script_only_include Please let me know what you like or dislike. Thank you.
-- Yasuo Ohgaki yohgaki@ohgaki.net

Matteo Beccati

11 years ago
Hi Yasuo, On 10/02/2015 01:52, Yasuo Ohgaki wrote:
> Some of you are tired with this topic, but please take a look the RFC > > [RFC] Script only includes - this is 3rd version. > https://wiki.php.net/rfc/script_only_include > > Please let me know what you like or dislike.
I understand you goal, but ini settings are *bad*. We need less of them, not more. Developing applications or libraries that are resilient to all possible "variants" in the ini settings is painful. It's a waste of time for both users and developers trying to provide support. Cheers
-- Matteo Beccati Development & Consulting - http://www.beccati.com/

Yasuo Ohgaki

11 years ago
Hi Matteo, On Tue, Feb 10, 2015 at 5:22 PM, Matteo Beccati <php@beccati.com> wrote:
> On 10/02/2015 01:52, Yasuo Ohgaki wrote: > >> Some of you are tired with this topic, but please take a look the RFC >> >> [RFC] Script only includes - this is 3rd version. >> https://wiki.php.net/rfc/script_only_include >> >> Please let me know what you like or dislike. >> > > I understand you goal, but ini settings are *bad*. We need less of them, > not more. > > Developing applications or libraries that are resilient to all possible > "variants" in the ini settings is painful. It's a waste of time for both > users and developers trying to provide support.
I proposed script()/script_once() at first. Considering new names that might break existing apps, I choose INI. The INI may be removed in the future, if include/require has an option. e.g. require string $filename [, bool $embed_mode_flag]; Would you like me to include this change proposal in the RFC? Even if we have embed_mode_flag, we are better to have the INI option for a while for smooth migration. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Yasuo Ohgaki

11 years ago
Hi Matteo, On Wed, Feb 11, 2015 at 12:48 PM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> On Tue, Feb 10, 2015 at 5:22 PM, Matteo Beccati <php@beccati.com> wrote: > >> On 10/02/2015 01:52, Yasuo Ohgaki wrote: >> >>> Some of you are tired with this topic, but please take a look the RFC >>> >>> [RFC] Script only includes - this is 3rd version. >>> https://wiki.php.net/rfc/script_only_include >>> >>> Please let me know what you like or dislike. >>> >> >> I understand you goal, but ini settings are *bad*. We need less of them, >> not more. >> >> Developing applications or libraries that are resilient to all possible >> "variants" in the ini settings is painful. It's a waste of time for both >> users and developers trying to provide support. > > > I proposed script()/script_once() at first. Considering new names that > might > break existing apps, I choose INI. > > The INI may be removed in the future, if include/require has an option. > e.g. > > require string $filename [, bool $embed_mode_flag]; > > Would you like me to include this change proposal in the RFC? > Even if we have embed_mode_flag, we are better to have the INI option for > a > while for smooth migration. >
How about remove 2 INIs in the future with this RFC? script_embed=On/Off (New with this RFC) allow_url_include=On/Off I'll prepare patch that require(_once) string $filename [, int $include_type]; include(_once) string $filename [, int $include_type]; Where $include_type are - PHP_INCLUDE_DEFAULT (default: no embed, no URL) - PHP_INCLUDE_EMBED (allow embed) - PHP_INCLUDE_URL (allow URL) These types are combined like "PHP_INCLUDE_EMBED | PHP_INCLUDE_URL". Then, above 2 INIs may be deprecated and remove in the future. How about remove them by PHP 7.3. What do you think? Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Stas Malyshev

11 years ago
Hi!
> I proposed script()/script_once() at first. Considering new names that > might > break existing apps, I choose INI.
The problem with script_once is not that it may break existing apps. The problem is that somebody careful enough to use special operator would probably be careful enough not to put $_GET['pleasehackme'] there, and somebody not careful enough to do that won't also use special operator because he probably wouldn't even know why it's needed or whether it exists.
-- Stas Malyshev smalyshev@gmail.com

Markus Fischer

11 years ago
On 10.02.15 01:52, Yasuo Ohgaki wrote:
> Some of you are tired with this topic, but please take a look the RFC > > [RFC] Script only includes - this is 3rd version. > https://wiki.php.net/rfc/script_only_include > > Please let me know what you like or dislike.
How exactly does this detection work?
> move_uploaded_file() searches “start tag” token if it is located as
the first token. What constitutes "first token" in this context? Would this be detected as a PHP file? -----8<---- root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin <?php phpinfo(); -----8<---- thanks, - Markus

Yasuo Ohgaki

11 years ago
Hi Markus, On Tue, Feb 10, 2015 at 5:59 PM, Markus Fischer <markus@fischer.name> wrote:
> What constitutes "first token" in this context? > > Would this be detected as a PHP file? > > -----8<---- > root:x:0:0:root:/root:/bin/bash > daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin > bin:x:2:2:bin:/bin:/usr/sbin/nologin > <?php > phpinfo(); > -----8<---- >
Yes. Since we have custom script loader, file content cannot be used for "pure" PHP script detection. However, parser can detect if it's a "pure" PHP script. i.e. Detect <?php token at first, no ?> in the file. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Derick Rethans

11 years ago
On Wed, 11 Feb 2015, Yasuo Ohgaki wrote:
> Hi Markus, > > On Tue, Feb 10, 2015 at 5:59 PM, Markus Fischer <markus@fischer.name> wrote: > > > What constitutes "first token" in this context? > > > > Would this be detected as a PHP file? > > > > -----8<---- > > root:x:0:0:root:/root:/bin/bash > > daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin > > bin:x:2:2:bin:/bin:/usr/sbin/nologin > > <?php > > phpinfo(); > > -----8<---- > > > > Yes. > > Since we have custom script loader, file content cannot be used for > "pure" PHP script detection. However, parser can detect if it's a > "pure" PHP script. i.e. Detect <?php token at first, no ?> in the > file.
That's arbitrary. The ?> at the end of a file is not an error (or a mistake). cheers, Derick

Pierre Joye

11 years ago
On Tue, Feb 10, 2015 at 7:52 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Hi all, > > Some of you are tired with this topic, but please take a look the RFC > > [RFC] Script only includes - this is 3rd version. > https://wiki.php.net/rfc/script_only_include > > Please let me know what you like or dislike.
I said before but this RFC tries to solve a problem using yet another "security" feature in the engine while the OS and the webserver provides way better solutions without adding a possible new pandora box from a security point of view. Many extensions may have to deal with it too. I can only create an empty for all upcoming CVEs about xyz not following script_embed. Alone that tells me that we should not try again to make php "more secure" using such features. I suppose script_embed ini setting is siimilar to open_basedir but for exec only, which would prevent any script to be exec'ed (require, include, via handlers but works for fopen&co) while open_basedir would remain the same (aka also for fopen&co). Now, that does prevent one to shoot himself in the foot, eval(file_get_contents());. Yes, this is stupid thing to do, just a bit more stupid that require "someuploadedfile"; but not much more. Trying to implement security measures to prevent people to exec codes from an unknown file is a bad idea. They will do it one way or another. And if anyone application still do include/require(random/uploaded files), then they surely have many other problems to solve but none of them is really a php problem. Cheers,
-- Pierre @pierrejoye | http://www.libgd.org

Yasuo Ohgaki

11 years ago
Hi Pierre, On Tue, Feb 10, 2015 at 6:19 PM, Pierre Joye <pierre.php@gmail.com> wrote:
> On Tue, Feb 10, 2015 at 7:52 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote: > > Hi all, > > > > Some of you are tired with this topic, but please take a look the RFC > > > > [RFC] Script only includes - this is 3rd version. > > https://wiki.php.net/rfc/script_only_include > > > > Please let me know what you like or dislike. > > I said before but this RFC tries to solve a problem using yet another > "security" feature in the engine while the OS and the webserver > provides way better solutions without adding a possible new pandora > box from a security point of view. Many extensions may have to deal > with it too. I can only create an empty for all upcoming CVEs about > xyz not following script_embed. Alone that tells me that we should not > try again to make php "more secure" using such features. > > I suppose script_embed ini setting is siimilar to open_basedir but for > exec only, which would prevent any script to be exec'ed (require, > include, via handlers but works for fopen&co) while open_basedir would > remain the same (aka also for fopen&co). Now, that does prevent one to > shoot himself in the foot, eval(file_get_contents());. Yes, this is > stupid thing to do, just a bit more stupid that require > "someuploadedfile"; but not much more. Trying to implement security > measures to prevent people to exec codes from an unknown file is a bad > idea. They will do it one way or another. And if anyone application > still do include/require(random/uploaded files), then they surely have > many other problems to solve but none of them is really a php problem
I think I understood your point of view perfectly and thank you for your comment. We just have different point of views. This is the last serious PHP design issue for me. I've been thinking how it could be resolved for a long time and this is the best. I hope you agree to remove risks of script inclusions. Let's be nicer to new PHP users! Don't let them down by embedded mode include()/require()! Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Pavel Kouřil

11 years ago
On Tue, Feb 10, 2015 at 1:52 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Hi all, > > Some of you are tired with this topic, but please take a look the RFC > > [RFC] Script only includes - this is 3rd version. > https://wiki.php.net/rfc/script_only_include > > Please let me know what you like or dislike. > > Thank you. > > -- > Yasuo Ohgaki > yohgaki@ohgaki.net
Hello, IMHO the real solution to this problem is to educate the programmers how to write safer applications, not by ini settings. Regards Pavel Kouril

Yasuo Ohgaki

11 years ago
Hi Pavel, On Tue, Feb 10, 2015 at 7:06 PM, Pavel Kouřil <pajousek@gmail.com> wrote:
> IMHO the real solution to this problem is to educate the programmers > how to write safer applications, not by ini settings. >
We have been tried to educate users already and introduced some mitigations e.g. allow_url_include, open_basedir. However, enough time is passed to prove that wasn't enough, isn't it? PHP (many and these are _only_ few of them in the wild) http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=PHP&filter_author=&filter_platform=0&filter_type=0&filter_lang_id=0&filter_exploit_text=inclusion&filter_port=0&filter_osvdb=&filter_cve= PERL (0 result) http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=&filter_exploit_text=PERL&filter_author=inclusion&filter_platform=0&filter_type=0&filter_lang_id=0&filter_port=&filter_osvdb=&filter_cve= Rails (0 result) http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=Rails&filter_exploit_text=inclusion&filter_author=&filter_platform=0&filter_type=0&filter_lang_id=0&filter_port=&filter_osvdb=&filter_cve= Python (0 result) http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=Python&filter_exploit_text=inclusion&filter_author=&filter_platform=0&filter_type=0&filter_lang_id=0&filter_port=&filter_osvdb=&filter_cve= JSP (1 result - This is famous) http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=JSP&filter_exploit_text=inclusion&filter_author=&filter_platform=0&filter_type=0&filter_lang_id=0&filter_port=&filter_osvdb=&filter_cve= The picture is clear. I value education as one of the most important security measure indeed. However, education is not perfect. If there is effective counter measure, it is better to be adopted. We can write web apps by PHP, not only because it's faster to write, but easier to write secure code. We removed "script embedding" from regex functions, why not include? My new proposal is simple and does not require performance penalty. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Christoph Becker

11 years ago
Yasuo Ohgaki wrote:
> We have been tried to educate users already and introduced some > mitigations e.g. allow_url_include, open_basedir. > > However, enough time is passed to prove that wasn't enough, isn't it? > > PHP (many and these are _only_ few of them in the wild) > http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=PHP&filter_author=&filter_platform=0&filter_type=0&filter_lang_id=0&filter_exploit_text=inclusion&filter_port=0&filter_osvdb=&filter_cve=
I've arbitrarily checked the top most entry (u5CMS), and the LFI was caused by `echo file_get_contents($_GET['...'])` basically. There was neither include|require(_once) involved, nor move_uploaded_file(). From my, admittedly very limited, experience, this is a rather common source of LFI vulnerabilities in PHP applications. I'm afraid that educating developers is the only way to avoid this kind of vulnerability.
-- Christoph M. Becker

Yasuo Ohgaki

11 years ago
Hi Christoph, On Wed, Feb 11, 2015 at 10:45 AM, Christoph Becker <cmbecker69@gmx.de> wrote:
> > We have been tried to educate users already and introduced some > > mitigations e.g. allow_url_include, open_basedir. > > > > However, enough time is passed to prove that wasn't enough, isn't it? > > > > PHP (many and these are _only_ few of them in the wild) > > > http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=PHP&filter_author=&filter_platform=0&filter_type=0&filter_lang_id=0&filter_exploit_text=inclusion&filter_port=0&filter_osvdb=&filter_cve= > > I've arbitrarily checked the top most entry (u5CMS), and the LFI was > caused by `echo file_get_contents($_GET['...'])` basically. There was > neither include|require(_once) involved, nor move_uploaded_file(). From > my, admittedly very limited, experience, this is a rather common source > of LFI vulnerabilities in PHP applications. I'm afraid that educating > developers is the only way to avoid this kind of vulnerability.
It's not my point. These are only surface of them as you can see it contains only open source project's vulnerabilities. Script inclusion is common by evidence, unlike others. This is what I'm trying to change. Are PHP programmers are worse than others? I don't think they are. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Christoph Becker

11 years ago
Hi Yasuo, Yasuo Ohgaki wrote:
> Hi Christoph, > > On Wed, Feb 11, 2015 at 10:45 AM, Christoph Becker <cmbecker69@gmx.de> > wrote: > >>> We have been tried to educate users already and introduced some >>> mitigations e.g. allow_url_include, open_basedir. >>> >>> However, enough time is passed to prove that wasn't enough, isn't it? >>> >>> PHP (many and these are _only_ few of them in the wild) >>> >> http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=PHP&filter_author=&filter_platform=0&filter_type=0&filter_lang_id=0&filter_exploit_text=inclusion&filter_port=0&filter_osvdb=&filter_cve= >> >> I've arbitrarily checked the top most entry (u5CMS), and the LFI was >> caused by `echo file_get_contents($_GET['...'])` basically. There was >> neither include|require(_once) involved, nor move_uploaded_file(). From >> my, admittedly very limited, experience, this is a rather common source >> of LFI vulnerabilities in PHP applications. I'm afraid that educating >> developers is the only way to avoid this kind of vulnerability. > > > It's not my point. These are only surface of them as you can see it contains > only open source project's vulnerabilities. > > Script inclusion is common by evidence, unlike others.
If you mean "unlike other languages", I tend to agree. However, I'm still afraid that script inclusion vulnerabilities are *way* less common than vulnerabilities due to *reading* and *displaying* (*not* *executing*) arbitrary files in PHP applications.
> This is what I'm trying to change. > Are PHP programmers are worse than others? > I don't think they are.
Certainly, there are many fine PHP programmers, but also there are many PHP programmers who are not sufficently educated with regard to security (I might still be part of the latter group).
> Regards,
Regards,
-- Christoph M. Becker

Stas Malyshev

11 years ago
Hi!
> Some of you are tired with this topic, but please take a look the RFC > > [RFC] Script only includes - this is 3rd version. > https://wiki.php.net/rfc/script_only_include > > Please let me know what you like or dislike.
I think there are several issues with this RFC: 1. It does not protect against all the problems it purports to protect. I.e. if you want to protect against local PHP code accessing evil uploaded files, local PHP code can also do echo file_get_contents('/etc/paswd') and still have a problem (actually, very common LFI issue). Even if the application only allows to require random file, it may be possible to inject data via other means - such as data stream, URL, temp files, session files, etc. Upload is not the only way inputs can be controlled. 2. Legitimate files can include <? as byte sequence - in fact, it is almost guaranteed big enough binary file would contain it. Restricting upload of such files would break uploading functionality on many sites. 3. General approach of this RFC is, given site with glaring security hole in their code, give them a measure of protection against some of the consequences. This looks like safe_mode approach, and that proved ineffective in the past.
-- Stas Malyshev smalyshev@gmail.com

Yasuo Ohgaki

11 years ago
Hi Stas, On Wed, Feb 11, 2015 at 4:32 PM, Stanislav Malyshev <smalyshev@gmail.com> wrote:
> > Some of you are tired with this topic, but please take a look the RFC > > > > [RFC] Script only includes - this is 3rd version. > > https://wiki.php.net/rfc/script_only_include > > > > Please let me know what you like or dislike. > > I think there are several issues with this RFC: > > 1. It does not protect against all the problems it purports to protect. > I.e. if you want to protect against local PHP code accessing evil > uploaded files, local PHP code can also do echo > file_get_contents('/etc/paswd') and still have a problem (actually, very > common LFI issue). Even if the application only allows to require > random file, it may be possible to inject data via other means - such as > data stream, URL, temp files, session files, etc. Upload is not the only > way inputs can be controlled. >
File disclosure issue is not scope of this RFC. 2. Legitimate files can include <? as byte sequence - in fact, it is
> almost guaranteed big enough binary file would contain it. Restricting > upload of such files would break uploading functionality on many sites. >
Good point. User needs compression/encryption to avoid issues. I may make move_uploaded_file() more strict. How about syntax check? If it detected as script and there is no syntax errors, then reject. This will never happens binaries. However, this is not enough. User may upload text with PHP program sample. So add and options that force to move embedded PHP script? Another possibility is use of filename extension(s). It's going back to old approach, but register script extension and allow execution only for matched extension. This may be the way to go. 3. General approach of this RFC is, given site with glaring security
> hole in their code, give them a measure of protection against some of > the consequences. This looks like safe_mode approach, and that proved > ineffective in the past.
I'm not trying to be perfect, but I would like to make PHP as secure as other languages from script inclusion attacks. It's too easy currently... I hope we have consensus for a resolution. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Stas Malyshev

11 years ago
Hi!
> I'm not trying to be perfect, but I would like to make PHP as secure as > other > languages from script inclusion attacks. It's too easy currently...
PHP is already as secure as the other languages. If you have code in Python that loads arbitrary file and executes it, you could upload Python file and execute it. If you have code in Ruby that loads arbitrary file and executes it, you could upload Ruby file and execute it. If you have code in C that... you get the idea. Same with PHP.
-- Stas Malyshev smalyshev@gmail.com

Patrick Schaaf

11 years ago
Hi, another one of my weird ideas: what about a script signing mode? - ini setting containing a HMAC key - first <?php tag in a file must then have a signature, a la <?php:Base64encodedstring - no parsing of files that fail the signature check - (maybe optional) disabling of eval Of course such an approach would need, in addition, a locally well defined place from where updated code is distributed to production servers, which would then need to implement the signing process. So it's only something for sane larger shops with a good dev/production split. best regards Patrick

Yasuo Ohgaki

11 years ago
Hi Stas, On Thu, Feb 12, 2015 at 3:21 AM, Stanislav Malyshev <smalyshev@gmail.com> wrote:
> > I'm not trying to be perfect, but I would like to make PHP as secure as > > other > > languages from script inclusion attacks. It's too easy currently... > > PHP is already as secure as the other languages. If you have code in > Python that loads arbitrary file and executes it, you could upload > Python file and execute it. If you have code in Ruby that loads > arbitrary file and executes it, you could upload Ruby file and execute > it. If you have code in C that... you get the idea. Same with PHP.
Python loads script like import foo where foo is foo.py. Ruby loads script like require 'foo' where foo is foo.rb. This is the origin of the difference. We may have something like this. We may check registered filename extension(s) or may allow to omit registered extension(s). We may take some benchmarks and decide, since these 2 are the same basically. Faster is better, but I guess "checking" is faster. What do you think? Comments are appreciated. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Derick Rethans

11 years ago
On Tue, 10 Feb 2015, Yasuo Ohgaki wrote:
> Hi all, > > Some of you are tired with this topic, but please take a look the RFC > > [RFC] Script only includes - this is 3rd version. > https://wiki.php.net/rfc/script_only_include > > Please let me know what you like or dislike.
Con: - It introduces an INI option that changes PHP's behaviour. - How do you know what is a PHP script? Surely not be checking that the first 4 chars are "<?php" ? cheers, Derick

Lester Caine

11 years ago
On 11/02/15 09:34, Derick Rethans wrote:
>> Some of you are tired with this topic, but please take a look the RFC >> > >> > [RFC] Script only includes - this is 3rd version. >> > https://wiki.php.net/rfc/script_only_include >> > >> > Please let me know what you like or dislike. > Con: > - It introduces an INI option that changes PHP's behaviour. > - How do you know what is a PHP script? Surely not be checking that the > first 4 chars are "<?php" ?
First 5? ... Yasuo ... I don't think this is going in the right direction. The principals are right, but we have been through a lot of this trying to secure included files in the past and nothing has worked yet. I don't think that anything implemented in a PHP distribution will change what is happening in practice?
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Yasuo Ohgaki

11 years ago
Hi all, On Tue, Feb 10, 2015 at 9:52 AM, Yasuo Ohgaki <yohgaki@ohgaki.net> wrote:
> Some of you are tired with this topic, but please take a look the RFC > > [RFC] Script only includes - this is 3rd version. > https://wiki.php.net/rfc/script_only_include > > Please let me know what you like or dislike. >
This proposal has defect. I was excluding old proposals and it turned out old proposal was better. Thank you Stas. There was proposal that limit script execution only for certain filename extension(s). Currently, PHP has text script and phar script loader. If we limit script filenames, then all users has to do is checking filename extensions. We have null byte injection protection for filename already. This would be the simplest and works well against script inclusion. Comments are appreciated. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net