Low watch CVSS 4.3 chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Low
Severity
4.3
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInappropriate implementation in Permissions
DescriptionInappropriate implementation in Permissions
ComponentPermissions
Sub-componentPEPC
Bug ClassLogic Error
Action tierwatch — logic/policy bug — security-relevant, no memory-unsafety
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker423670839
Fix commit9344dfce9c3a (chromium/src) +31/-0
CWECWE-451
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N
CISA KEVNot listed
CreditedHafiizh
Reported2025-06-10 · bounty $500 (per vendor advisory)
Fix landed2025-06-28 (public git)
Disclosed2025-09-02
Patch gap66 days — fix public in source before the advisory

Background

`<permission>` element (PEPC)
the Page-Embedded Permission Control: a browser-rendered button (e.g. type="camera") whose click is trusted as a user permission decision, implemented in third_party/blink/renderer/core/html/html_permission_element.cc.
PEPC style locking
Blink forces or clamps many CSS properties on <permission> (borders, cursor, colors, sizes) so a page cannot make the control misleading, hide it, or disguise it.
Propagated text decoration
under CSS Text Decoration Level 3, text-decoration set on an ancestor “decorating box” is drawn through descendant inline text, even when the descendant itself sets text-decoration: none. Blink stores this inherited state as “base text decoration data” on the ComputedStyleBuilder.
`ComputedStyleBuilder::SetBaseTextDecorationData`
the setter for the inherited decoration list; passing nullptr clears decorations inherited from ancestors.

Root Cause Analysis

The <permission> style-adjustment code in html_permission_element.cc locked many properties on the element’s ComputedStyleBuilder (the hunk shows SetBorderRightWidth() and ClearCursorList() next to it; the enclosing function name is not shown in the hunk). It did not clear the base text-decoration data inherited from ancestor elements. As the commit message explains, the spec would stop propagation if the element’s internal container were display: inline-box, but that does not fit PEPC’s layout, so decorations such as an underline on a parent div were drawn through the permission control’s label even though PEPC is meant to have a locked, browser-controlled appearance.

The fix tightens the lock by unconditionally calling builder.SetBaseTextDecorationData(nullptr) for every <permission> element, so ancestor decorations do not propagate. The WPT reftest text-decoration-tentative.html, with text-decoration: underline on both the parent div and permission, must now render identically to an undecorated <permission>.

Key insight
PEPC’s style lock covered properties set on the element itself but missed text decoration, which reaches the element from ancestors through propagation rather than ordinary inheritance. Resetting the base text-decoration data closes that path.

Attack Path

  1. Page embeds a permission control A site places <permission type="camera"> (or another type) inside a container it styles.
  2. Ancestor sets `text-decoration` The page applies a decoration to an ancestor, as the reftest does with div { text-decoration: underline; }.
  3. Decoration bleeds into the locked control Before the fix, the propagated decoration was painted over the browser-rendered label, changing the control’s appearance despite PEPC’s style restrictions.
  4. User is misled Decorations such as line-through or heavy, coloured lines could obscure or change the apparent meaning of the label, encouraging a permission grant the user did not intend (inferred; the patch only demonstrates an underline).

Impact Assessment

A web page could change the rendering of the trusted <permission> control in its own renderer, weakening PEPC’s anti-deception guarantees. The result is UI spoofing or clickjacking-style deception (inferred), not a memory-safety or sandbox issue. Exploitation needs only ordinary page content where the <permission> element is available. That depends on the PEPC feature being enabled for the page (it was gated by a flag or origin trial at the time; this is inferred, since the diff does not show the gating). It also requires the user to click the misleading control. The vendor severity is low, and the supplied metadata does not report in-the-wild exploitation.

Files Changed

  • third_party/blink/renderer/core/html/html_permission_element.cc
  • third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-ref.html
  • third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-tentative.html

Audit Directions

  • Propagated or non-inherited style channels
    Review PEPC style locking (and other trusted browser-drawn controls) for visual effects that reach an element without being set on it: ancestor text-decoration, filter/opacity/mask/clip-path on ancestors, mix-blend-mode, transforms, and ::first-line/::first-letter styling.
  • Allowlist vs. reset gaps
    Compare the set of properties PEPC clamps with the full CSS property list, especially properties stored in builder fields that are not tied to a single longhand (such as base text-decoration data or applied text decorations).
  • Overlay/occlusion checks
    Make sure the activation-time checks for <permission> (visibility, occlusion, minimum contrast) take ancestor-applied effects into account, not only the element’s own computed style.
From 9344dfce9c3a39fd2f6757d3b20390a86f5e5298 Mon Sep 17 00:00:00 2001
From: Thomas Nguyen <[email protected]>
Date: Sat, 28 Jun 2025 01:42:47 -0700
Subject: [PATCH] [PEPC] Disallow text-decoration CSS property

The CSS Text Decoration Module Level 3 spec (https://drafts.csswg.org/css-text-decor-3/#decorating-box) says PEPC's internal container needs `display: inline-box`. That doesn't work with our current layout, so we'll just reset the base text-decoration to get the same result.

Bug: 423670839
Change-Id: I53b574d2bc2c9e0e03b62a145cce3f682466866e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6681790
Reviewed-by: Joey Arhar <[email protected]>
Commit-Queue: Thomas Nguyen <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1480204}
---

diff --git a/third_party/blink/renderer/core/html/html_permission_element.cc b/third_party/blink/renderer/core/html/html_permission_element.cc
index 9a7084c..1e57769 100644
--- a/third_party/blink/renderer/core/html/html_permission_element.cc
+++ b/third_party/blink/renderer/core/html/html_permission_element.cc
@@ -959,6 +959,11 @@
     builder.SetBorderRightWidth(builder.FontSize());
   }
 
+  // The base `text-decoration` property must be reset for each `<permission>`
+  // element. This prevents any `text-decoration` from a parent element from
+  // being propagated to the `<permission>` element.
+  builder.SetBaseTextDecorationData(nullptr);
+
   // Cursor only allows 'pointer' (default) and 'not-allowed'. No custom images.
   builder.ClearCursorList();
   if (builder.Cursor() != ECursor::kNotAllowed) {
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-ref.html
new file mode 100644
index 0000000..c420d08
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<body>
+  <div>
+    <permission type="camera"></permission>
+  </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-tentative.html
new file mode 100644
index 0000000..be4bd04
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-tentative.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<link rel="match" href="text-decoration-ref.html">
+<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md#locking-the-pepc-style">
+<body>
+  <style>
+    permission {
+      text-decoration: underline;
+    }
+    div {
+      text-decoration: underline;
+    }
+  </style>
+  <div>
+    <permission type="camera"></permission>
+  </div>
+</body>
+</html>
\ No newline at end of file
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-ref.html
new file mode 100644
index 0000000..c420d08
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<body>
+  <div>
+    <permission type="camera"></permission>
+  </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-tentative.html
new file mode 100644
index 0000000..be4bd04
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/permission-element/text-decoration-tentative.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<link rel="match" href="text-decoration-ref.html">
+<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md#locking-the-pepc-style">
+<body>
+  <style>
+    permission {
+      text-decoration: underline;
+    }
+    div {
+      text-decoration: underline;
+    }
+  </style>
+  <div>
+    <permission type="camera"></permission>
+  </div>
+</body>
+</html>
\ No newline at end of file
Loading diff…

Original Bug Report

reported by [email protected]

Permission element inner div with style text-decoration-line: line-through; and text-decoration-thickness can be abused if no element in the parent chain has any text-decoration-line: line-through; and text-decoration-thickness are set.

This bug is similar to https://issues.chromium.org/issues/398803201, when text-decoration-line: line-through; and text-decoration-thickness: are embedded in a tag above the <permission> tag, for example a div or something else, this affects the <permission> tag, thus covering the text in the <permission> tag. if style text-decoration-line: line-through; and text-decoration-thickness embedded directly in the <permission> tag are not affected. The impact is that sites can potentially trick users to trigger permission prompts even if the permission is currently in a DENY state for that origin. (It does not however bypass the permission prompt in any way)

references for some css that can and cannot be embedded in the <permission> tag: https://developer.chrome.com/blog/permission-element-origin-trial?hl=en

View on issue tracker