This CVE demonstrates why regex-based XSS detection is a liability, not a layer. The vulnerability lives in Grav CMS's Security::detectXss() function, which uses a heuristic anchored at < with a non-greedy scan for [^>]*?. This fundamentally misrepresents how browsers parse HTML — the regex assumes anything between < and > is safe unless it contains >, but browsers maintain an open tag state in quoted attribute contexts past what looks like a closing delimiter. The bypass payload " onerror=alert exploits exactly this gap: the detector sees > and believes the tag is closed, but the browser remains inside the attribute until it sees the closing quote.
The real danger here isn't the bypass — it's the false confidence the function created. If other code paths began trusting detectXss() as their XSS safety guarantee, the function may have enabled riskier patterns in modules that were never audited because "Security::detectXss() handles that." This is the net-negative outcome: a custom security function that made the codebase less secure than if they'd invested in a battle-tested library like DOMPurify from the start.
Check your codebase for any input-handling paths that rely on a custom XSS detection function returning a boolean. Audit every call site — not to verify the function works, but to determine whether other code was written in the shadow of its assumed correctness. If your incident response only patched the regex without auditing dependent code paths, you've closed one hole while leaving the structural damage invisible. The temporal blast radius matters: this payload class has been documented since 2013. The existence of this bypass in 2025 suggests the project's threat model may not have included known XSS vectors, which warrants revisiting your broader input validation strategy.