php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #76834 Local File Inclusion through unrecognized protocol of file_get_contents
Submitted: 2018-09-02 06:51 UTC Modified: 2018-12-16 13:02 UTC
From: bgkn1260128 at gn dot iwasaki dot ac dot jp Assigned:
Status: Suspended Package: Streams related
PHP Version: 7.2.9 OS: Darwin MBP.local 17.6.0 Darwin K
Private report: No CVE-ID: None
 [2018-09-02 06:51 UTC] bgkn1260128 at gn dot iwasaki dot ac dot jp
Description:
------------
When file_get_contents("file://google.com/"); is executed The following error is displayed:

Warning: file_get_contents(): remote host file access not supported, file://google.com/ in Command line code on line 1

Warning: file_get_contents(file://google.com/): failed to open stream: no suitable wrapper could be found in Command line code on line 1
This behavior is explained at the following URL and you can see that file:// does not support relative path specification:
https://bugs.php.net/bug.php?id=28820

However, file_get_contents("0://google.com/../../../../../etc/hosts"); is executed The following error is displayed:

127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3  ee151a077be0
Although file:// does not support relative path specification in this operation, 0:// can read the local file with relative path specification.
It seems that pass traversal is made by bypassing the filter.

Test script:
---------------
php -r "file_get_contents('file://google.com/../../../../../etc/hosts');"
php -r "file_get_contents('0://google.com/../../../../../etc/hosts');"


Expected result:
----------------
If an unrecognized protocol is input as an argument of file_get_contents (), appropriate error handling is performed.

Actual result:
--------------
When file://google.com/../../../../../etc/hosts:

Warning: file_get_contents(): remote host file access not supported, file://google.com/../../../../../etc/hosts in Command line code on line 1

Warning: file_get_contents(file://google.com/../../../../../etc/hosts): failed to open stream: no suitable wrapper could be found in Command line code on line 1

When 0://google.com/../../../../../etc/hosts:
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3  ee151a077be0

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-09-02 10:58 UTC] cmb@php.net
-Assigned To: +Assigned To: stas
 [2018-09-02 10:58 UTC] cmb@php.net
This doesn't look like a security issues, since a properly
configured open_basedir couldn't be bypassed.

However, it seems to me that failing to recognize the zero as
protocol is a bug.  At least the behavior is inconsistent with
realpath() which would return FALSE, even though
file_get_contents() could read the file.  The culprit would be in
php_stream_locate_url_wrapper() where a protocol is only
recognized if it is longer than a single char[1].  Changing to `n
>= 1` would solve the issue, but would break filenames like
C://Users/cmb/… on Windows which currently work like
C:/Users/cmb/….

Stas, could you please assess whether this is a security issue,
and if not assign back to me.

[1] <https://github.com/php/php-src/blob/php-7.3.0beta3/main/streams/streams.c#L1740>
 [2018-09-09 18:44 UTC] stas@php.net
-Type: Security +Type: Feature/Change Request -Assigned To: stas +Assigned To: cmb
 [2018-09-09 18:44 UTC] stas@php.net
Not a security issue - if you allow people to feed arbitrary paths into your code, you have arbitrary file access. 0:// is not a stream, so it treats it like a path.
 [2018-12-16 13:02 UTC] cmb@php.net
-Status: Assigned +Status: Suspended -Package: Unknown/Other Function +Package: Streams related -Assigned To: cmb +Assigned To:
 [2018-12-16 13:02 UTC] cmb@php.net
The suggested fix[1] is obviously controversial, so this issue may
need further discussion on internals@ and perhaps even the RFC
process[2].  Feel free to start it!  For the time being, I'm
suspending this ticket.

[1] <https://github.com/php/php-src/pull/3513>
[2] <http://wiki.php.net/rfc/howto>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Oct 06 23:01:26 2024 UTC