Skip to main content

@astrojs/rss CVE-2026-59728

| EUVDEUVD-2026-49584 MEDIUM
XML Injection (aka Blind XPath Injection) (CWE-91)
2026-07-20 https://github.com/withastro/astro GHSA-8j5q-mfj2-5q9q
4.3
CVSS 3.1 · Vendor: https://github.com/withastro/astro
Share

Severity by source

Vendor (https://github.com/withastro/astro) PRIMARY
4.3 MEDIUM
AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N
vuln.today AI
4.3 MEDIUM

Network-delivered feed injection requiring no app-level auth (PR:N), but feed subscriber must parse the result (UI:R); impact limited to feed integrity corruption only.

3.1 AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N
4.0 AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N

Primary rating from Vendor (https://github.com/withastro/astro).

CVSS VectorVendor: https://github.com/withastro/astro

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Unchanged
Confidentiality
None
Integrity
Low
Availability
None

Lifecycle Timeline

2
Source Code Evidence Fetched
Jul 20, 2026 - 23:47 vuln.today
Analysis Generated
Jul 20, 2026 - 23:47 vuln.today

DescriptionCVE.org

Summary

In @astrojs/rss, the source.title and enclosure.type item fields are interpolated directly into XML template strings without XML-character escaping before being parsed by fast-xml-parser. An attacker who controls these field values can inject arbitrary XML elements into the generated RSS feed.

Details

Two fields in packages/astro-rss/src/index.ts are affected:

source.title

typescript
item.source = parser.parse(
  `<source url="${result.source.url}">${result.source.title}</source>`,
).source;

source.title is validated only as z.string(), with no restriction on XML special characters. A value containing </source> followed by arbitrary XML is parsed as real XML elements, merging injected nodes into the RSS item.

enclosure.type

typescript
item.enclosure = parser.parse(
  `<enclosure url="${enclosureURL}" length="${result.enclosure.length}" type="${result.enclosure.type}"/>`,
).enclosure;

enclosure.type is also z.string() and is interpolated into an XML attribute without escaping. A value containing " followed by additional XML can break out of the attribute and inject extra elements.

Proof of Concept

source.title injection:

javascript
source: {
  url: 'https://legit.example.com',
  title: '</source><item><title>INJECTED</title><link>https://evil.com</link></item><source>',
}
// Result: RSS feed contains an injected <item> element with an evil.com link

enclosure.type injection:

javascript
enclosure: {
  url: 'https://example.com/a.mp3',
  length: 0,
  type: 'audio/mpeg" /><link>https://evil.example.com</link><enclosure fake="',
}
// Result: RSS feed contains an injected <link> element

Both injections were confirmed with fast-xml-parser: the injected "link": "https://evil.com" appears in the parsed output.

Impact

An attacker who can control source.title or enclosure.type values (e.g., via a CMS, database, or user-submitted content that populates RSSFeedItem) can inject arbitrary XML into the generated RSS feed. This corrupts feed structure, injects false metadata (e.g., a fake <link> pointing to a malicious URL), and can cause feed readers to misparse or display attacker-controlled content. In SSR mode (output: 'server'), the poisoned feed is served on every request to all subscribers.

Patches

Fixed in @astrojs/rss@4.0.19.

AnalysisAI

XML injection in @astrojs/rss (all versions from 1.0.0 through 4.0.18) allows an attacker who can supply content to the source.title or enclosure.type RSS feed item fields to break out of XML string templates and inject arbitrary XML elements into the generated feed. The root issue is that both fields are interpolated directly into raw XML strings before fast-xml-parser processes them, with no escaping applied, so XML metacharacters are treated as markup rather than text. A public proof-of-concept is confirmed in the GitHub Security Advisory; no CISA KEV listing is indicated, and EPSS data was not provided in the available intelligence.

Technical ContextAI

The @astrojs/rss npm package (pkg:npm/@astrojs_rss) is the official RSS feed generation library for the Astro web framework. It constructs RSS XML by interpolating user-supplied field values into template literal strings and then passing those strings to fast-xml-parser for parsing. The vulnerability (CWE-91, XML Injection) arises in packages/astro-rss/src/index.ts: source.title is inserted between <source ...> and </source> tags with no escaping, and enclosure.type is inserted into an XML attribute value with no quoting or entity encoding. Because fast-xml-parser then parses these strings as real XML, any injected elements become part of the parsed object and are subsequently serialized into the output feed. The Zod schema validates both fields only as z.string(), placing no restriction on XML special characters. The fix (PR #17209) eliminates string interpolation entirely and replaces it with structured object assignment ({ '#text': value, '@_attr': value }), letting fast-xml-parser's builder handle proper serialization.

RemediationAI

Upgrade @astrojs/rss to version 4.0.19 or later - the first patched release per the vendor advisory at https://github.com/withastro/astro/security/advisories/GHSA-8j5q-mfj2-5q9q and the release tag at https://github.com/withastro/astro/releases/tag/@astrojs/rss@4.0.19. The fix (https://github.com/withastro/astro/pull/17209) replaces string-interpolated XML construction with structured object assignment, so fast-xml-parser's own builder handles character escaping. If an immediate upgrade is not feasible, the most effective workaround is to sanitize or reject source.title and enclosure.type input values before they reach the RSS generator by stripping or entity-encoding the characters <, >, &, and ". This can be applied in the data layer (CMS validation, database input sanitization) or as a thin wrapper around the getRssString / rss() call. Note that blocking these characters may truncate legitimate content containing ampersands or angle brackets in titles, so the trade-off is mild content fidelity loss versus injection risk.

Share

CVE-2026-59728 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy