php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #73192 parse_url return wrong hostname
Submitted: 2016-09-28 08:01 UTC Modified: 2019-02-22 22:19 UTC
From: mala at ma dot la Assigned: stas (profile)
Status: Closed Package: URL related
PHP Version: 5.6.26 OS:
Private report: No CVE-ID:
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: mala at ma dot la
New email:
PHP Version: OS:

 

 [2016-09-28 08:01 UTC] mala at ma dot la
Description:
------------
url like these
- http://example.com:80#@google.com/
- http://example.com:80?@google.com/

parse_url return wrong host.

https://tools.ietf.org/html/rfc3986#section-3.2

   The authority component is preceded by a double slash ("//") and is
   terminated by the next slash ("/"), question mark ("?"), or number
   sign ("#") character, or by the end of the URI.

This problem has been fixed in 7.1.

https://github.com/php/php-src/pull/1607

But, this issue should be recognized as security issue.

example:

- bypass authentication protocol (verify hostname of callback url by parse_url)
- open redirector (verify hostname by parse_url)
- server-side request forgery (verify hostname by parse_url and get_content) 


Test script:
---------------
php > echo parse_url("http://example.com:80#@google.com/")["host"];
google.com

php > echo parse_url("http://example.com:80?@google.com/")["host"];
google.com

php > echo file_get_contents("http://example.com:80#@google.com");

... contents of example.com ...


Expected result:
----------------
parse_url("http://example.com:80#@google.com/")["host"];

example.com or parse error.



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-10-05 04:58 UTC] stas@php.net
-Status: Open +Status: Closed -PHP Version: 7.0.11 +PHP Version: 5.6.26 -Assigned To: +Assigned To: stas
 [2016-10-05 04:58 UTC] stas@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.

Merged pull 1607 back to 5.6.
 [2016-10-05 07:10 UTC] mala at ma dot la
Hi, 

I wrote 
```
Expected result:
----------------
parse_url("http://example.com:80#@google.com/")["host"];

example.com or parse error
```

but, recognized # as end of authority component and 
same as http://example.com:80/#@google.com/ is more correct.

   The authority component is preceded by a double slash ("//") and is
   terminated by the next slash ("/"), question mark ("?"), or number
   sign ("#") character, or by the end of the URI.


in PHP 7.1.0RC3, can't parse these url.

php > $result = parse_url("http://example.com:80#@google.com/"); echo $result == null;
1

please review again.
 [2016-10-05 07:34 UTC] stas@php.net
I'm not sure I understand you comment. If you have better fix, please suggest it here or make pull request. If you have scenario which should be handled better, please provide:
1. Reproducing script
2. Expected output
3. Actual output
 [2016-10-05 08:05 UTC] mala at ma dot la
1. Reproducing script
php > var_dump(parse_url("http://example.com:80#@google.com/"));

2. Expected output

array(4) {
  ["scheme"]=>
  string(4) "http"
  ["host"]=>
  string(11) "example.com"
  ["port"]=>
  int(80)
  ["fragment"]=>
  string(12) "@google.com/"
}

3. Actual output

in PHP 7.1
bool(false)

in PHP 5.5
php > var_dump(parse_url("http://example.com:80#@google.com/"));
array(5) {
  ["scheme"]=>
  string(4) "http"
  ["host"]=>
  string(10) "google.com"
  ["user"]=>
  string(11) "example.com"
  ["pass"]=>
  string(3) "80#"
  ["path"]=>
  string(1) "/"
}
 [2016-10-07 23:11 UTC] nikic@php.net
Automatic comment on behalf of nikic
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b061fa909de77085d3822a89ab901b934d0362c4
Log: Fix bug #73192
 [2016-10-17 10:07 UTC] bwoebi@php.net
Automatic comment on behalf of nikic
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b061fa909de77085d3822a89ab901b934d0362c4
Log: Fix bug #73192
 [2016-11-09 19:39 UTC] mala at ma dot la
ping @nikic

I can't find this fix in release note of 5.6.28 and 7.0.13.

https://github.com/php/php-src/commit/c8ff491106f1bdb9f0c62875f52d51cfb461eb5d
https://github.com/php/php-src/commit/7bded39b2fc14c5a181a93a57bc23af858b585f6

This is security issue.
I think CVE-ID should be assigned.

for example, 

cURL's case
CVE-2016-8624 
https://curl.haxx.se/docs/adv_20161102J.html

see WordPress's ugly workaround code.
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2221
https://core.trac.wordpress.org/changeset/36444
 [2016-11-09 20:10 UTC] ab@php.net
@mala thanks for checking, the revision b061fa909de77085d3822a89ab901b934d0362c4 is in the upcoming releases, merely it's missing in the NEWS. The final changelog will contain the entry.

Thanks.
 [2017-02-13 01:14 UTC] stas@php.net
-CVE-ID: +CVE-ID: needed
 [2017-11-02 16:25 UTC] michel dot stpierre at yahoo dot ca
With this fix in php 5.6.28, I have some code that no long works.  The ftp urls contain a username which is in fact an email address and a pw that has symbols.  Then parse_url returns false.  It used to work before this fix (before 5.6.28).

test url:
ftp://usernameisanemail@emailservername.com:passwordhassymbols$%?@ftp.testserver03.com/

test case:
echo print_r(parse_url("ftp://usernameisanemail@emailservername.com:passwordhassymbols$%?@ftp.testserver03.com/"), true);
Should return an array with url elements.
 [2019-02-22 22:19 UTC] stas@php.net
-CVE-ID: needed +CVE-ID:
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 23 21:01:28 2024 UTC