Skip to content

v5: HTML-escape grapheme-cluster bypass (CVE-2026-27120) still present #147

Description

@vulgraph

Quick heads-up — Sources/LeafKit/String+HTMLEscape.swift on the v5 branch (sha 1a426bf2) still uses the old grapheme-cluster-based String.replacing(_:with:) / replacingOccurrences(of:with:) implementation:

self
    .replacing("&", with: "&")
    .replacing("\"", with: """)
    .replacing("'", with: "'")
    .replacing("<", with: "&lt;")
    .replacing(">", with: "&gt;")

The CVE-2026-27120 fix 8919e394 switched this to a per-unicodeScalar reduce so that, for example, "\u{0022}\u{0301}" (a quote with a combining accent — one extended grapheme cluster, but two scalars) escapes to &quot;\u{0301} instead of slipping through unchanged. The accompanying testExtendedGraphemeClusterBypass regression test is also absent in Tests/LeafKitTests/HTMLEscapeTests.swift on v5 (sha b21b7003).

So a payload like "\u{0301}=1 autofocus tabindex=0 onfocus=alert(1) survives htmlEscaped() on this branch when it doesn't on main. If v5 is still maintained for security I can put the cherry-pick together.

Cheers,
vulgraph

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions