php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #76653 Server Side Request Forgery using exif_read_data?
Submitted: 2018-07-22 21:13 UTC Modified: 2018-07-23 12:45 UTC
From: geeknik at protonmail dot ch Assigned: cmb (profile)
Status: Not a bug Package: EXIF related
PHP Version: 7.2.8 OS: Linux
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: geeknik at protonmail dot ch
New email:
PHP Version: OS:

 

 [2018-07-22 21:13 UTC] geeknik at protonmail dot ch
Description:
------------
I believe that I have found a server side request forgery bug in exif_read_data().

From machine A: 
php-7.2.8 -r 'exif_read_data(file_get_contents("http://dtf.pw/php728/poc/722/http.jpeg"));' 

The http.jpeg on Machine B starts with http://@2328211425:8000, which ip2long converts into an IP I happen to control, aka Machine C. 

And if we look at the console over on Machine C:

Serving HTTP on 0.0.0.0 port 8000 ...
138.68.249.154 - - [22/Jul/2018 19:05:18] code 404, message File not found
138.68.249.154 - - [22/Jul/2018 19:05:18] "GET //c&_▒ HTTP/1.0" 404 -

Machine A never contacts Machine C directly but as soon as Machine A requests the "jpeg" from Machine B, a request is simultaneously sent to Machine C.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-07-22 22:08 UTC] cmb@php.net
Presently, it seems to me that B's IP address is 159.65.100.145,
and C's is 138.197.175.225.  C's access log records a request from
138.68.249.154 – are you sure that this isn't A's address?
 [2018-07-22 22:13 UTC] geeknik at protonmail dot ch
Machine A: 138.68.249.154
Machine B: 159.65.100.145
Machine C: 138.197.175.225

A is where the php request originates, B is where the "jpeg" resides, and when A requests that "jpeg" from B, a request from A is logged on C.
 [2018-07-22 22:30 UTC] cmb@php.net
> A is where the php request originates, B is where the "jpeg"
> resides, and when A requests that "jpeg" from B, a request from A
> is logged on C.

This is expected.  file_get_contents() retrieves the “image”, and
passes its result to exif_read_data(), which accepts stream
wrapper URLs as of PHP 7.2.0.  So, basically, this is like

    file_get_contents("http://dtf.pw/php728/poc/722/http.jpeg");
    exif_read_data('http://@2328211425:8000');

Since this doesn't trigger a request from B to C, I don't see a
problem here.
 [2018-07-22 23:31 UTC] geeknik at protonmail dot ch
Okay, I think I understand what is happening now. So in order for this to be a valid issue, I need to make a request from A to B which triggers a request from B to C?
 [2018-07-23 12:45 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2018-07-23 12:45 UTC] cmb@php.net
> So in order for this to be a valid issue, I need to make a
> request from A to B which triggers a request from B to C?

See <https://en.wikipedia.org/wiki/Server-side_request_forgery>.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Dec 27 03:01:28 2024 UTC