Overview
About vulnerability
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
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
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:
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:
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/[email protected].
Details
- Affected product:
- Express , arcjet-js , arcjet-logger , arcjet-skills , astro , astro-expressive-code , astrojs-cloudflare , astrojs-internal-helpers , astrojs-markdoc , astrojs-markdown-remark , astrojs-mdx , astrojs-netlify , astrojs-node , astrojs-preact , astrojs-prism , astrojs-solid-js , astrojs-starlight , astrojs-studio , astrojs-svelte , astrojs-underscore-redirects , astrojs-upgrade , astrojs-vercel , astrojs-vue , clerk-astro , create-zephyr-apps , elements , lucide , lucide-astro , lucide-icons , lucide-preact , lucide-react-native , lucide-solid , lucide-static , lucide-svelte , lucide-vue , mux-mux-player-react , octanejs-astro , orama-orama , panda , pandacss-mcp , pandacss-types , rehype-expressive-code , rollup-plugin-zephyr , scalar-astro , scalar-starlight , sentry-astro , sentry-deno , sentry-effect , sentry-elysia , sentry-ember , sentry-eslint-config-sdk , sentry-eslint-plugin-sdk , sentry-gatsby , sentry-google-cloud-serverless , sentry-hono , sentry-javascript , sentry-nitro , sentry-node-native , sentry-replay , sentry-server-runtime-injection , sentry-server-utils , sentry-solid , sentry-solidstart , sentry-tanstackstart , sentry-tanstackstart-react , sentry-wasm , tabler-icons , tabler-icons-angular , tabler-icons-astro , tabler-icons-png , tabler-icons-preact , tabler-icons-solidjs , tabler-icons-sprite , tabler-icons-vue , tabler-icons-webfont , vite-plugin-tanstack-start-zephyr , vite-plugin-vinext-zephyr , vite-plugin-zephyr , with-zephyr , zbsearch , zbsearch-docs-index , zbsearch-edge-core , zbsearch-edge-index-builder , zbsearch-highlight , zbsearch-plugin-data-persistence , zbsearch-plugin-docusaurus , zbsearch-plugin-embeddings , zbsearch-plugin-match-highlight , zbsearch-plugin-parsedoc , zbsearch-plugin-pt15 , zbsearch-plugin-qps , zbsearch-plugin-starlight , zbsearch-plugin-vitepress , zbsearch-runtime-cloudflare , zbsearch-searchbox-core , zbsearch-searchbox-react , zbsearch-searchbox-vue , zbsearch-static , zbsearch-stemmers , zbsearch-stopwords , zbsearch-tokenizers , zephyr-agent , zephyr-astro-integration , zephyr-edge-contract , zephyr-metro-plugin , zephyr-modernjs-plugin , zephyr-native-cache , zephyr-nuxt-module , zephyr-packages , zephyr-repack-plugin , zephyr-rolldown-plugin , zephyr-rsbuild-plugin , zephyr-rspack-plugin , zephyr-rspress-plugin , zephyr-tap-runtime , zephyr-webpack-plugin , zephyr-xpack-internal
- Affected packages:
- astro @ 1.9.2 (+1308 more)