---
id: "CVE-2026-117645"
kind: "vulnerability"
aliases: ["CVE-2026-117645"]
title: "Phoenix HTML: attribute names unescaped, letting untrusted input inject scripts"
severity: "medium"
cvss: 5.3
epss: null
exploited: false
status: "open"
category: "package"
products: []
ecosystems: []
tags: ["elixir", "package", "phoenix", "phoenix-html"]
not_affected_if: ["attribute-keys-hardcoded", "fixed-version"]
published_at: "2026-10-30T21:16:51+00:00"
first_seen_at: "2026-10-30T21:25:52+00:00"
updated_at: "2026-10-30T21:27:00+00:00"
sources: [{"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-117645", "first_seen_at": "2026-10-30T21:25:52+00:00"}]
---

# Phoenix HTML: attribute names unescaped, letting untrusted input inject scripts

Phoenix.HTML.attributes_escape/1 escapes attribute values but not attribute names, so a key containing whitespace or quotes can end an attribute and start a new one. An attacker who controls attribute keys can inject event handlers and script into rendered pages.

_Summary, check and fix written by a model from the sources; labelled as such._

## How to check

- Look for `phoenix_html` in `mix.lock` and check the resolved version.
- Search the codebase for HEEx `{@attrs}` spreads, `content_tag/3` and direct `attributes_escape` calls where attribute keys come from user input.

## Fix

- `phoenix_html` from `3.3.5` in the 1.x/3.x line
- `phoenix_html` from `4.4.0` in the 4.x line

## Timeline

- 2026-10-30T21:25:52+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-117645

## From the sources

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.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
