CVE-2026-117645
Phoenix.HTML vulnerable to attribute injection via unvalidated attribute names in attributes_escape/1
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') vulnerability in phoenixframework phoenix_html allows an attacker who controls attribute names to inject attributes and script into rendered HTML via Phoenix.HTML.attributes_escape/1.
attributes_escape/1 in lib/phoenix_html.ex escapes attribute values but not attribute names. key_escape/1 passes a binary key through html_escape, which neutralizes quotes and angle brackets but not whitespace, so a key such as x onmouseover ends the attribute and starts a new one. An atom key is only dasherized, so any character passes, including quotes and >. Nested data, aria and phx keys take the same paths. An application is affected when it builds attribute keys from untrusted input and renders them through HEEx <tag {@attrs}>, content_tag/3, or a direct call. Before 3.0.0 the same code lived in Phoenix.HTML.Tag.
This issue affects phoenix_html: from 1.0.0 before 3.3.5 and from 4.0.0 before 4.4.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Passive
What an attacker can affect
- Confidentiality
- Low
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
5.3
Phoenix.HTML vulnerable to attribute injection via unvalidated attribute names in attributes_escape/1
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') vulnerability in phoenixframework phoenix_html allows an attacker who controls attribute names to inject attributes and script into rendered HTML via Phoenix.HTML.attributes_escape/1.
attributes_escape/1 in lib/phoenix_html.ex escapes attribute values but not attribute names. key_escape/1 passes a binary key through html_escape, which neutralizes quotes and angle brackets but not whitespace, so a key such as x onmouseover ends the attribute and starts a new one. An atom key is only dasherized, so any character passes, including quotes and >. Nested data, aria and phx keys take the same paths. An application is affected when it builds attribute keys from untrusted input and renders them through HEEx <tag {@attrs}>, content_tag/3, or a direct call. Before 3.0.0 the same code lived in Phoenix.HTML.Tag.
This issue affects phoenix_html: from 1.0.0 before 3.3.5 and from 4.0.0 before 4.4.0.
- Record
CVE-2026-117645- CVSS 4.0
- 5.3 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-79
- Updated
- 2026-11-06
EUVDEUVD-2026-114454
5.3
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') vulnerability in phoenixframework phoenix_html allows an attacker who controls attribute names to inject attributes and script into rendered HTML via Phoenix.HTML.attributes_escape/1.
attributes_escape/1 in lib/phoenix_html.ex escapes attribute values but not attribute names. key_escape/1 passes a binary key through html_escape, which neutralizes quotes and angle brackets but not whitespace, so a key such as x onmouseover ends the attribute and starts a new one. An atom key is only dasherized, so any character passes, including quotes and >. Nested data, aria and phx keys take the same paths. An application is affected when it builds attribute keys from untrusted input and renders them through HEEx <tag {@attrs}>, content_tag/3, or a direct call. Before 3.0.0 the same code lived in Phoenix.HTML.Tag.
This issue affects phoenix_html: from 1.0.0 before 3.3.5 and from 4.0.0 before 4.4.0.
- Record
EUVD-2026-114454- CVSS 4.0
- 5.3 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N - Updated
- 2026-11-06
GitHub AdvisoriesGHSA-jwcv-27cf-c7j5
5.3
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')...
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') vulnerability in phoenixframework phoenix_html allows an attacker who controls attribute names to inject attributes and script into rendered HTML via Phoenix.HTML.attributes_escape/1.
attributes_escape/1 in lib/phoenix_html.ex escapes attribute values but not attribute names. key_escape/1 passes a binary key through html_escape, which neutralizes quotes and angle brackets but not whitespace, so a key such as x onmouseover ends the attribute and starts a new one. An atom key is only dasherized, so any character passes, including quotes and >. Nested data, aria and phx keys take the same paths. An application is affected when it builds attribute keys from untrusted input and renders them through HEEx <tag {@attrs}>, content_tag/3, or a direct call. Before 3.0.0 the same code lived in Phoenix.HTML.Tag.
This issue affects phoenix_html: from 1.0.0 before 3.3.5 and from 4.0.0 before 4.4.0.
- Record
GHSA-jwcv-27cf-c7j5- CVSS 4.0
- 5.3 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-79
- Updated
- 2026-11-02
NVD
5.3
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') vulnerability in phoenixframework phoenix_html allows an attacker who controls attribute names to inject attributes and script into rendered HTML via Phoenix.HTML.attributes_escape/1.
attributes_escape/1 in lib/phoenix_html.ex escapes attribute values but not attribute names. key_escape/1 passes a binary key through html_escape, which neutralizes quotes and angle brackets but not whitespace, so a key such as x onmouseover ends the attribute and starts a new one. An atom key is only dasherized, so any character passes, including quotes and >. Nested data, aria and phx keys take the same paths. An application is affected when it builds attribute keys from untrusted input and renders them through HEEx <tag {@attrs}>, content_tag/3, or a direct call. Before 3.0.0 the same code lived in Phoenix.HTML.Tag.
This issue affects phoenix_html: from 1.0.0 before 3.3.5 and from 4.0.0 before 4.4.0.
- Record
CVE-2026-117645- CVSS 4.0
- 5.3 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-79
- Updated
- 2026-11-06
OSV
5.3
Phoenix.HTML vulnerable to attribute injection via unvalidated attribute names in attributes_escape/1
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') vulnerability in phoenixframework phoenix_html allows an attacker who controls attribute names to inject attributes and script into rendered HTML via Phoenix.HTML.attributes_escape/1.
attributes_escape/1 in lib/phoenix_html.ex escapes attribute values but not attribute names. key_escape/1 passes a binary key through html_escape, which neutralizes quotes and angle brackets but not whitespace, so a key such as x onmouseover ends the attribute and starts a new one. An atom key is only dasherized, so any character passes, including quotes and >. Nested data, aria and phx keys take the same paths. An application is affected when it builds attribute keys from untrusted input and renders them through HEEx <tag {@attrs}>, content_tag/3, or a direct call. Before 3.0.0 the same code lived in Phoenix.HTML.Tag.
This issue affects phoenix_html: from 1.0.0 before 3.3.5 and from 4.0.0 before 4.4.0.
- Record
CVE-2026-117645- CVSS 4.0
- 5.3 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-79
- Updated
- 2026-11-07
OSVEEF-CVE-2026-117645
5.3
Phoenix.HTML vulnerable to attribute injection via unvalidated attribute names in attributes_escape/1
Summary
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') vulnerability in phoenixframework phoenix_html allows an attacker who controls attribute names to inject attributes and script into rendered HTML via Phoenix.HTML.attributes_escape/1.
attributes_escape/1 in lib/phoenix_html.ex escapes attribute values but not attribute names. key_escape/1 passes a binary key through html_escape, which neutralizes quotes and angle brackets but not whitespace, so a key such as x onmouseover ends the attribute and starts a new one. An atom key is only dasherized, so any character passes, including quotes and >. Nested data, aria and phx keys take the same paths. An application is affected when it builds attribute keys from untrusted input and renders them through HEEx <tag {@attrs}>, content_tag/3, or a direct call. Before 3.0.0 the same code lived in Phoenix.HTML.Tag.
This issue affects phoenix_html: from 1.0.0 before 3.3.5 and from 4.0.0 before 4.4.0.
Details
1. Attribute rendering. Phoenix.HTML.attributes_escape/1 walks the key-value pairs through build_attrs/1 and nested_attrs/3 and emits each as key_escape(k)="attr_escape(v)". Values are escaped. Names are not checked against the HTML attribute-name grammar.
2. Binary names. key_escape/1 sends a binary through Phoenix.HTML.Engine.html_escape/1, which replaces &, <, >, " and '. Whitespace passes. HTML uses whitespace to separate attributes, so %{"x onmouseover" => "alert(1)"} renders x onmouseover="alert(1)": a harmless x attribute followed by an attacker-chosen event handler.
3. Atom names. key_escape/1 converts an atom with Atom.to_string/1 and replaces _ with -. Nothing is escaped, so [{:"x\" onclick=\"alert(1)", "y"}] renders x" onclick="alert(1)="y" and aria: [{:"x\"><script>", "y"}] renders aria-x"><script>="y", which leaves the tag entirely. This path needs the application to create atoms from untrusted input, for example Jason.decode!(body, keys: :atoms) or String.to_atom/1 on a parameter.
4. Reachability. HEEx compiles <div {@attrs}> to a call to Phoenix.HTML.attributes_escape/1 through Phoenix.LiveView.HTMLEngine and Phoenix.LiveView.TagEngine. tag/2 and content_tag/3 in Phoenix.HTML.Tag (phoenix_html 1.x to 3.x) and in PhoenixHTMLHelpers.Tag (4.x) render attributes the same way. Versions before 3.0.0 emitted the dasherized name without any escaping at all.
Proof of concept
- Install a vulnerable release, for example
Mix.install([{:phoenix_html, "== 4.3.0"}]). - Render a binary name containing a space:
Phoenix.HTML.attributes_escape(%{"x onmouseover" => "alert(1)"}) |> Phoenix.HTML.safe_to_string()returnsx onmouseover="alert(1)". - Render an atom name containing a quote:
Phoenix.HTML.attributes_escape([{:"x\" onclick=\"alert(1)", "y"}]) |> Phoenix.HTML.safe_to_string()returnsx" onclick="alert(1)="y". - Render a nested atom name:
Phoenix.HTML.attributes_escape(aria: [{:"x\"><script>", "y"}]) |> Phoenix.HTML.safe_to_string()returnsaria-x"><script>="y". - Place any of these maps in a HEEx template as
<div {@attrs}>to deliver the injected attribute to a browser.
Impact
An attacker who can influence the attribute names an application renders can add event-handler attributes or close the tag and run script in the browser of every user who views the page.
Workarounds
Do not derive attribute names from untrusted input. Where dynamic attribute keys are needed, check each key against an allow list, or against a pattern such as ^[a-zA-Z][a-zA-Z0-9:._-]*$, before passing the map to attributes_escape/1 or a HEEx {@attrs} expression. Do not create atoms from request data.
- Record
EEF-CVE-2026-117645- CVSS 4.0
- 5.3 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-79
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
phoenix_htmlHex |
1.0.0 up to 3.3.5, 4.0.0 up to 4.4.0, plus listed versions 1.0.11.1.01.2.01.2.11.3.0 Show 45 moreShow less1.4.02.0.02.0.0-dev2.0.12.1.02.1.12.1.22.10.02.10.12.10.22.10.32.10.42.10.52.11.02.11.12.11.22.12.02.13.02.13.12.13.22.13.32.13.42.14.02.14.12.14.22.14.32.2.02.3.02.3.12.4.02.4.0-dev2.5.02.5.12.6.02.6.12.6.22.7.02.7.0-dev2.8.02.9.02.9.12.9.22.9.33.0.03.0.1 |
3.3.54.4.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| facts | NVD, OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-117645 is a medium vulnerability (CVSS 5.3) in Phoenixframework Phoenix Html, published October 30, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.32%, the 24th percentile. Fixed in phoenix_html 3.3.5.
References
cna.erlef.org/cves/CVE-2026-117645.html
osv.dev/vulnerability/EEF-CVE-2026-117645
github.com/phoenixframework/phoenix_html/commit/6ad3a1d7960891a468d54636054a98e11dfb5111
github.com/phoenixframework/phoenix_html/commit/d9e4e6b2d9be49e25fb6d6b4fdbb2008174f01a6
github.com/phoenixframework/phoenix_html/commit/a47dc8944a773b7e9273d9691dc6744ec793f1de
nvd.nist.gov/vuln/detail/CVE-2026-117645
Left out here: 15 versions. The JSON record has them.