Bug 1194820 (CVE-2015-7219)

Firefox HTTP2 Malformed PushPromise Underflow DoS

RESOLVED FIXED in Firefox 43



Networking: HTTP
3 years ago
2 years ago


(Reporter: c0nrad, Assigned: mcmanus)


({csectype-dos, sec-low})

39 Branch
csectype-dos, sec-low

Firefox Tracking Flags

(firefox42 wontfix, firefox43 fixed, firefox-esr38 wontfix)


(Whiteboard: [post-critsmash-triage][adv-main43+])


(1 attachment)



3 years ago
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36

Steps to reproduce:

# Firefox HTTP2 Malformed PushPromise Underflow DoS

## Overview
A malformed HTTP2 PushPromse frame is sent to the browser. The length of the decompressed buffer is miscalculated an underflow occurs. This causes an nsCString to try to allocate nearly 2^32 bytes of memory. This is greater than firefox allows and an assert is tripped.

## Walkthrough

On line 1634 of Http2Session.cpp, a call is made to append the decompressed frame onto a decompressed buffer. 

self->mDecompressBuffer.Append(self->mInputFrameBuffer + kFrameHeaderBytes + paddingControlBytes + promiseLen,
         self->mInputFrameDataSize - paddingControlBytes - promiseLen - paddingLength);

The values and types for the PoC are:

self->mDecompressBuffer.Append(nsAutoArrayPtr<char>(ptr) + uint_8(9) + uint8_t(1) + uint32_t(4), uint32_t(76) - uint8_t(1) - uint32_t(4) - uint16_t(75));

The second argument is casted to a size_type (uint32), and the underflow occurs. The resulting value is 4294967292.

A bunch of string checks are then performed to make sure the append is sane. Eventually in nsTSubstring.cpp:45 MutatePrep is called with:

MutatePrep(this=0x00000xxxx, aCapacity=4294967292, aOldData=0x00000xxxxx, aOldFlags=0x00000xxxxxxx).

In the function, kMaxCapacity for a string is determined to be:

const size_type kMaxCapacity = (size_type(-1) / 2 - sizeof(nsStringBuffer)) / sizeof(char_type) - 2;
// kMaxCapacity = 2147483637

kMaxCapacity is then compared to our capacity (4294967292). Since the capacity exceds the max allowed, an error is thrown on line 531 of nsTSubstring.cpp.

AllocFailed(Length() - aCutLength + 1)

## Tested on 

Firefox 39.0. MacOS
42.0a1 (2015-07-21) MacOS

## PoC
Code can be found here:

To use:
Extract the file and the certs
$ go run firefoxHeaderPoc.go
$ ./firefox https://localhost:8000

## Author

Stuart Larsen
Yahoo! Pentest Team
Component: Untriaged → Networking: HTTP
Flags: needinfo?(mcmanus)
Product: Firefox → Core

Comment 1

3 years ago
Created attachment 8649463 [details] [diff] [review]
h2 push promise padding handling
Attachment #8649463 - Flags: review?(hurley)


3 years ago
Assignee: nobody → mcmanus
Ever confirmed: true

Comment 2

3 years ago
patch passes the PoC included in bug and regression xpcshell h2 testing run locally.
Flags: needinfo?(mcmanus)
Keywords: csectype-dos, sec-low
Last Resolved: 3 years ago
status-firefox43: --- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla43


3 years ago
Group: core-security → core-security-release
Comment on attachment 8649463 [details] [diff] [review]
h2 push promise padding handling

[Approval Request Comment]
If this is not a sec:{high,crit} bug, please state case for ESR consideration: the best case for consideration is that this bug is going to be presented on at an upcoming security conference (https://pacsec.jp/speakers.html) 
User impact if declined: possible DoS
Fix Landed on Version: 43
Risk to taking this patch (and alternatives if risky): low
String or UUID changes made by this patch: none

See https://wiki.mozilla.org/Release_Management/ESR_Landing_Process for more info.
Attachment #8649463 - Flags: approval-mozilla-esr38?
Comment on attachment 8649463 [details] [diff] [review]
h2 push promise padding handling

As it doesn't match the ESR criteria (sec-high or critical), not taking it.
Attachment #8649463 - Flags: approval-mozilla-esr38? → approval-mozilla-esr38-
status-firefox-esr38: --- → wontfix
Whiteboard: [post-critsmash-triage]
status-firefox42: --- → wontfix
Whiteboard: [post-critsmash-triage] → [post-critsmash-triage][adv-main43+]
Alias: CVE-2015-7219
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.