Manual string replacement with a hardcoded list of cases for escaping as suggested by the article isn't good advice for the use case of 'support inserting arbitrary text'.
Do use CDATA nodes, but only work on XML with an actual XML DOM library instead of string manipulation. Browsers have these built-in (DOMParser).
I totally understand the general advice of using actual XML DOM library for making DOM. But for my own understanding, I want to ask why the 5 escapes the OP suggests (&, <, >, " and ') aren't good enough? Do you see anyway to exploit it if these 5 are escaped? Someone kind enough to enlighten me?
i never really liked CDATA but i'm not buying the argument here since you can do the escaping with replaceAll("]]>", "]]]]><![CDATA[>") instead of four replaceAlls. (assuming you are writing your own xml serializer in javascript in 2026 for some reason)
Just out of curiosity, I looked at the HN RSS feed and they still use regular escape for titles (and some other things, except description). It means they use 2 versions of escape instead of 1. So why not just use 1?
That assumes that you don't have anything else to escape or sanitize.
I see people stuffing all sorts of HTML tags and nonstandard attributes in an RSS <description>, just because CDATA allows them to do so without breaking the parser. Images, videos, inline SVGs with maybe some scripts inside...
The RSS spec should never have allowed this. Reading a feed would have been much more pleasant (not to mention safer for everyone!) if the contents were required to be in plain text.
The worst use of the <BLINK> tag ever was the discussion held in the early days of RSS about escaping HTML in titles, whose attention-grabbing title went something like this: "Hey, what happens when you put a <BLINK> tag in the title???!!!"
The content of that notorious discussion went on and off and on and off for weeks, giving all the netizens of the RSS community blogosphere terrible headaches, with people's entire blogs disappearing and reappearing every second, until it finally reached a flashing point, when Dave Winer humbly conceded that it wasn't the user's fault for being an idiot, and maybe just maybe there was tiny teeny little design flaw in RSS, and it wasn't actually such a great idea to allow HTML tags in RSS titles.
I Wanna Be <![CDATA[
Sung to the tune of “I Wanna Be Sedated”, with apologies to The Ramones.
Twenty-twenty-twenty four escapes to go, I wanna be <![CDATA[
Nothin’ to markup and no where to quo-o-ote, I wanna be <![CDATA[
Just get me through the parser, put me in a node
Hurry hurry hurry before I go inline
I can’t control my syntax, I can’t control my name
Oh no no no no no
Twenty-twenty-twenty four escapes to go….
Just put me in a stylesheet, get me in a namespace
Hurry hurry hurry before I go inline
I can’t control my syntax, I can’t control my name
Oh no no no no no
Twenty-twenty-twenty four escapes to go, I wanna be <![CDATA[
Nothin’ to markup and no where to quo-o-ote, I wanna be <![CDATA[
Just get me through the parser, put me in a node
Hurry hurry hurry before I go loco
I can’t control my syntax I can’t control my name
Oh no no no no no
Twenty-twenty-twenty escapaes to go…
Just get me through the parser…
Ba-ba-bamp-ba ba-ba-ba-bamp-ba I wanna be <![CDATA[
Ba-ba-bamp-ba ba-ba-ba-bamp-ba I wanna be <![CDATA[
Ba-ba-bamp-ba ba-ba-ba-bamp-ba I wanna be <![CDATA[
Ba-ba-bamp-ba ba-ba-ba-bamp-ba I wanna be <![CDATA[
But are most people going to read raw RSS? Just out of curiosity, I checked HN RSS, it still escapes character in a regular way (without CDATA) for titles. So, just keep 2 versions of XML escape instead of one?
I would not follow this advice. The most trouble I’ve had with RSS was usually from not having it. I also have never used CDATA at a word level - just wrap the full text block in it.
I come from a very different, old-school perspective, because I hand-write my blog posts in HTML and also hand-write my RSS feed in XML.
I've found CDATA invaluable, because I can just copy and paste the content from the HTML file to the XML file. I've never used the CDATA terminator characters in a blog post, so that's a non-problem.
I recently became aware of RSS stylesheets. Apparently there is a specification for that called XSLT which is distinct from CSS in both form and function. However, there are plans by Google/Mozilla to remove XSLT from their browser engines for security/maintainability reasons. Apparently RSS supports javascript though, so it's possible to manipulate the RSS DOM that way. One could imagine a javascript polyfill that interprets XSLT, although I'm not sure if there's some cross-site security issues that would make that impractical.
CData's "ad-hoc escaping" by closing and reopening a CData section always felt to me as if it could be a compatibility hazard - I think most examples of CData sections have a single section spanning the whole text node - so I wouldn't be surprised if some homegrown parsers didn't handle "edge cases" like multiple sections inside a text node correctly.
But I'd want to see evidence that this is actually the case. The OP seems to argue "don't use CData, because the escape sequence for ]]> looks confusing" - and that's just vibes, not a proper argument.
If it's for "looks" I think CData would actually be the much better choice. ]]> appears extremely rarely in RSS content while <>& are guaranteed to appear if your content is HTML. So in 99.99%, you won't need any escaping at all for CData and can just insert the HTML verbatim, while "regular" escaping will change every single angle bracket of your HTML.
> The OP seems to argue "don't use CData, because the escape sequence for ]]> looks confusing" - and that's just vibes, not a proper argument.
There are more arguments listed. One major one is about not being uniform. You still cannot use it for attribute values. CDATA might quickly become a footgun because it can give a false sense of security. Regular escaping is very universal and also works with HTML content and attribute values.
16 comments
[ 0.20 ms ] story [ 36.0 ms ] threadDo use CDATA nodes, but only work on XML with an actual XML DOM library instead of string manipulation. Browsers have these built-in (DOMParser).
I see people stuffing all sorts of HTML tags and nonstandard attributes in an RSS <description>, just because CDATA allows them to do so without breaking the parser. Images, videos, inline SVGs with maybe some scripts inside...
The RSS spec should never have allowed this. Reading a feed would have been much more pleasant (not to mention safer for everyone!) if the contents were required to be in plain text.
The content of that notorious discussion went on and off and on and off for weeks, giving all the netizens of the RSS community blogosphere terrible headaches, with people's entire blogs disappearing and reappearing every second, until it finally reached a flashing point, when Dave Winer humbly conceded that it wasn't the user's fault for being an idiot, and maybe just maybe there was tiny teeny little design flaw in RSS, and it wasn't actually such a great idea to allow HTML tags in RSS titles.
I Wanna Be <![CDATA[
Sung to the tune of “I Wanna Be Sedated”, with apologies to The Ramones.
Whether it's efficient is a far second to whether it successfully imports the data.
Looking at you, WP All Import...
I've found CDATA invaluable, because I can just copy and paste the content from the HTML file to the XML file. I've never used the CDATA terminator characters in a blog post, so that's a non-problem.
I recently became aware of RSS stylesheets. Apparently there is a specification for that called XSLT which is distinct from CSS in both form and function. However, there are plans by Google/Mozilla to remove XSLT from their browser engines for security/maintainability reasons. Apparently RSS supports javascript though, so it's possible to manipulate the RSS DOM that way. One could imagine a javascript polyfill that interprets XSLT, although I'm not sure if there's some cross-site security issues that would make that impractical.
But I'd want to see evidence that this is actually the case. The OP seems to argue "don't use CData, because the escape sequence for ]]> looks confusing" - and that's just vibes, not a proper argument.
If it's for "looks" I think CData would actually be the much better choice. ]]> appears extremely rarely in RSS content while <>& are guaranteed to appear if your content is HTML. So in 99.99%, you won't need any escaping at all for CData and can just insert the HTML verbatim, while "regular" escaping will change every single angle bracket of your HTML.
There are more arguments listed. One major one is about not being uniform. You still cannot use it for attribute values. CDATA might quickly become a footgun because it can give a false sense of security. Regular escaping is very universal and also works with HTML content and attribute values.