expat CVE-2024-8176 payloads (nested entities) can crash firefox tab
Categories
(Core :: XML, defect)
Tracking
()
People
(Reporter: hanno, Assigned: mccr8)
References
Details
(Keywords: crash, csectype-dos, reporter-external)
Attachments
(7 files)
The expat library has just published a security update which fixes several crashes caused due to deep nesting of entities (recursion / stack overflow):
https://blog.hartwork.org/posts/expat-2-7-0-released/
There are scripts to generate example payloads (payload{1,2,3}.py.txt) attached to the relevant expat github issue:
https://github.com/libexpat/libexpat/issues/893
These example payloads can crash a firefox tab.
| Reporter | ||
Comment 1•1 year ago
|
||
| Reporter | ||
Comment 2•1 year ago
|
||
| Reporter | ||
Comment 3•1 year ago
|
||
Error output from an ASAN build.
The stack traces imply that this is wrapped into wasm, probably due to this: https://blog.mozilla.org/attack-and-defense/2021/12/06/webassembly-and-back-again-fine-grained-sandboxing-in-firefox-95/
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Comment 4•1 year ago
•
|
||
At quick glance it seems it could just as well stack overflow in the wasm/rlbox sandbox, but somehow heap overflows before that happens? Shravan, what do you think?
Comment 5•1 year ago
|
||
Comment 6•1 year ago
|
||
| Assignee | ||
Comment 7•1 year ago
|
||
For convenience, here is the top of the 3 ASan reports in the zip file:
==31006==ERROR: AddressSanitizer: SEGV on unknown address 0x7f2f00000018 (pc 0x7f3079e981aa bp 0x7fffc9188570 sp 0x7fffc9188540 T0)
==31006==The signal is caused by a WRITE memory access.
#0 0x7f3079e981aa in i64_store /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:215:1
#1 0x7f3079e981aa in w2c_rlbox_hash /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:110026:3
#2 0x7f3079e6dc21 in w2c_rlbox_lookup /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:97026:12
#3 0x7f3079e784bd in w2c_rlbox_doContent /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:105977:14
#4 0x7f3079e96c79 in w2c_rlbox_processInternalEntity /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:109919:12
==31255==ERROR: AddressSanitizer: SEGV on unknown address 0x7ff800000028 (pc 0x7ff928d191aa bp 0x7fff3168a880 sp 0x7fff3168a850 T0)
==31255==The signal is caused by a WRITE memory access.
#0 0x7ff928d191aa in i64_store /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:215:1
#1 0x7ff928d191aa in w2c_rlbox_hash /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:110026:3
#2 0x7ff928ceec21 in w2c_rlbox_lookup /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:97026:12
#3 0x7ff928d2fa29 in w2c_rlbox_appendAttributeValue /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:110525:14
==31299==ERROR: AddressSanitizer: SEGV on unknown address 0x7f0200000028 (pc 0x7f03988191aa bp 0x7fff0458b130 sp 0x7fff0458b100 T0)
==31299==The signal is caused by a WRITE memory access.
#0 0x7f03988191aa in i64_store /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:215:1
#1 0x7f03988191aa in w2c_rlbox_hash /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:110026:3
#2 0x7f03987eec21 in w2c_rlbox_lookup /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:97026:12
#3 0x7f039880e878 in w2c_rlbox_storeEntityValue /builds/worker/workspace/obj-build/security/rlbox/rlbox.wasm.c:108728:14
Updated•1 year ago
|
Comment 8•1 year ago
|
||
Looking now.
Comment 9•1 year ago
•
|
||
As noted expat is sandboxed with RLBox+Wasm. Based on the prior message showing the ASAN stack trace, all three of the top ASAN reports here are a heap crash which Wasm will protect. So there is NO exploit/security-concern here --- the only reason to update is to avoid the crash.
The reason we see this as heap OOB's that are crashing is the following.
- All heap memory accesses in RLBox+Wasm are bounds checked. OOB accesses are guaranteed to either
abort()orSIGSEGV. - All buffers on the stack are moved to the heap as well and also bounds checked. (Wasm safety requires implementing the same semantics as
-fsanitize=safe-stack)
My assessment: the only issues these bugs can cause are non-exploitable crashes:
- Expat code OOB from a heap access, (or a stack buffer which is moved on to the heap by Wasm) can crash the browser.
- Expat can run code with an infinite function recursion causing too many stack frames running out of stack space. But again, this is not likely to be a security issue --- just a crash. In particular given that there are no buffers on the stack, it is very hard (read: likely impossible) to convert stack exhaustion to a stack-heap clash (you have to work very hard to find a gadget that skips all of the unmapped space in between the memories without performing a single access to the stack --- this is typically only possible if you have buffers on the stack).
@glandium:
- Let me know what you think about above
- One follow up question for you also . Wasm also has an explicit recursion limit for functions, which I have intentionally disabled for performance reasons. My reasoning: since you can't introduce buffers onto the stack, it is very difficult to use things like recursion to do anything except stack exhaustion. If we want to add an on extra layer of safety going forward, I'm happy to flip the switch to limit recursive calls also. (Just need to change this line https://searchfox.org/mozilla-central/source/security/rlbox/rlbox.mozbuild#39)
Updated•1 year ago
|
Comment 10•1 year ago
|
||
Stack access in rlbox indeed actually happens on the heap, with the same protections as other heap access. From that perspective, whatever might be possible from the original stack overflow is practically not exploitable in rlbox.
That being said, I think the only thing that really happens from the original stack overflow is a DoS. I don't think it's possible to craft something that would go over the guard page and possibly start hitting the heap (and even in practice, the likelihood that there's actual mapped heap after the stack guard page would be rather low).
So from that perspective, rlbox is not doing much here, as we get the same result: a DoS.
If the new expat release removes the lengthy recursion (I think it does), then it would be good to apply.
I also agree that enabling the recursion limit wouldn't buy much.
Updated•1 year ago
|
| Reporter | ||
Updated•1 year ago
|
| Assignee | ||
Updated•1 year ago
|
| Reporter | ||
Comment 11•8 months ago
|
||
It is unfortunate that this issue has stayed unfixed for so long. Sure, this is "only" a crash, but it could still be used for some quite annoying attacks.
I would like to add some information that emphasizes the severity. This can be triggered through an SVG image, which gives multiple possibilities:
-
It is not just possible to crash a tab, but also the whole browser process by using a favicon (which gets rendered outside the page sandbox). I will attach a proof of concept.
-
One could make a Github issue unreadable for firefox users by adding a comment including a markdown image tag referencing the PoC as an SVG.
-
It is possible to create a page with an OpenGraph preview using the PoC as the preview image. Some OpenGraph implementations directly use the unmodified preview image. This makes it, e.g., possible to crash the browser for all participants in a Rocketchat or Mattermost chat by posting a link with the payload as an SVG preview image.
| Reporter | ||
Comment 12•8 months ago
|
||
| Reporter | ||
Comment 13•8 months ago
|
||
One more scenario: it's also possible to cause a crash crash in thunderbird (and it appears there's no sandboxing of HTML rendering in thunderbird, it directly crashes the whole application).
| Assignee | ||
Comment 14•7 months ago
|
||
Bug 1988534 (along with bug 2010288) fixes the test cases in this bug.
| Assignee | ||
Comment 15•7 months ago
|
||
I basically landed Peter's patches in this bug, with a few minor additional tweaks given that I updated to a slightly newer version.
Updated•7 months ago
|
| Assignee | ||
Comment 16•7 months ago
|
||
If somebody is looking at verifying this, basically you just open the four test cases in a new tab, one at a time. You might get a weird error page, but the browser shouldn't crash. The test cases are: payload1.xml, payload2.xml, payload3.xml, payload4.xml and crashffsvgxml.html.
Updated•7 months ago
|
Updated•6 months ago
|
Description
•