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:
 [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: Wed Dec 11 07:01:27 2024 UTC