Bug 1194820 (CVE-2015-7219)

Firefox HTTP2 Malformed PushPromise Underflow DoS

RESOLVED FIXED in Firefox 43

Status

()

Core
Networking: HTTP
RESOLVED FIXED
3 years ago
2 years ago

People

(Reporter: c0nrad, Assigned: mcmanus)

Tracking

({csectype-dos, sec-low})

39 Branch
mozilla43
csectype-dos, sec-low
Points:
---

Firefox Tracking Flags

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

Details

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

Attachments

(1 attachment)

(Reporter)

Description

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:
https://notr-bucket.s3.amazonaws.com/977e424b-1c23-413b-b3f4-75d95cddd770

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
(Assignee)

Comment 1

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

Updated

3 years ago
Assignee: nobody → mcmanus
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
(Assignee)

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
https://hg.mozilla.org/mozilla-central/rev/faa0e890a858
Status: ASSIGNED → RESOLVED
Last Resolved: 3 years ago
status-firefox43: --- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla43

Updated

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.