CSS :is()/:where()/:not() selector nesting causes content process stack overflow
Categories
(Core :: CSS Parsing and Computation, defect)
Tracking
()
People
(Reporter: nohsecbug, Unassigned)
Details
(Keywords: ai-involved, reporter-external, Whiteboard: [client-bounty-form])
Attachments
(1 file)
|
2.78 KB,
text/html
|
Details |
Description
Deeply nested :is(), :where(), or :not() CSS selectors crash the content process via stack overflow in the selector parser. No user interaction required — visiting a page with the malicious CSS is sufficient.
Steps to reproduce:
- Save attached
poc.htmlto disk - Open in Firefox:
firefox --no-remote poc.html - Tab crashes: "Gah. Your tab just crashed."
ASan output (mozilla-central, macOS 26.3, aarch64):
==67176==ERROR: AddressSanitizer: stack-overflow on address 0x00016ef1f980
#0 smallvec::SmallVecData::from_inline
#1 selectors::parser::parse_selector
#2 selectors::SelectorList::parse_with_state
#3 selectors::parser::parse_is_where
#4 selectors::parser::parse_functional_pseudo_class
#5 selectors::parser::parse_one_simple_selector
#6 selectors::parser::parse_selector
... (cycle repeats 100+ times)
SUMMARY: AddressSanitizer: stack-overflow in SmallVecData::from_inline
Root cause: parse_selector() in servo/components/selectors/parser.rs calls parse_one_simple_selector() → parse_functional_pseudo_class() → parse_is_where() → SelectorList::parse_with_state() → parse_selector(). No depth counter exists. Input like div:is(:is(:is(...))) recurses until stack exhaustion. Affects :is(), :where(), and :not().
Suggested fix: Add a nesting depth counter to the selector parsing state, checked in parse_is_where(), with a limit of 32.
Severity: sec-high — reliable zero-click content process crash. All Firefox versions using Stylo (57+), all platforms.
URL
(n/a — local HTML file)
Updated•3 months ago
|
Updated•3 months ago
|
Updated•3 months ago
|
Description
•