Feed Security
Ok, so it’s been about a month I guess since I started talking about scripting exploits in feeds. I put together a whole bunch of Atom test cases based on an initial set of RSS tests produced by James Holderness. Several Feed Reader developers took those tests and plugged holes in their implementations. Now that implementors have had plenty of time to review the tests and check to see if they’re vulnerable, it’s time to start talking a bit about what those specific vulnerabilities are.
The suite of tests I put together can be found at the following URLs.
- http://www.snellspace.com/public/everything.atom
- http://www.snellspace.com/public/everything2.atom
- http://www.snellspace.com/public/everything3.atom
- http://www.snellspace.com/public/everything4.atom
- http://www.snellspace.com/public/everything5.atom
The first thing that you should notice when looking at these is that the overwhelming majority are based on well-known XSS exploits. For instance, Test #2 of everything.atom uses the simple trick of introducing line breaks and extra characters in script elements to fool sanitation filters.
<entry>
<title>2. Obfuscated script</title>
<id>http://www.snellspace.com/public/everything.atom#2</id>
<link href="http://www.snellspace.com/public/everything.atom#2" />
<content type="html"><script
x >
window.alert('Security Test #2')
</script
x ></content>
<updated>2006-08-09T12:12:12Z</updated>
</entry>
This simple technique was able to fool many Feed Readers regardless of whether or not the atom:content element was marked as type=”html”, type=”xhtml” or type=”text”… which brings up the next problem I found.
Many feed readers fail to properly handle <content type=”text”>…</content> and <title type=”text”>…</title>. The specification says that characters such as “<” and “&” in type=”text” elements MUST NOT be treated as markup. Feed Readers are required to interpret <content type=”text”><b>Foo</b></content> as the literal string “<b>Foo</b>” and not as escaped markup for “Foo“. If Feed Readers would simply treat plain text elements as plain text, many of the security vulnerabilities would go away.
Consider Test 10 of everything5.atom, for instance:
<entry>
<title>10. atom:author with script name</title>
<id>http://www.snellspace.com/public/everything5.atom#10</id>
<link href="http://www.snellspace.com/public/everything5.atom#10"/>
<content>blank</content>
<updated>2006-08-09T12:12:12Z</updated>
<author><name><script>alert('Security Alert #10');</script></name></author>
</entry>
The Atom specification defines the author/name element as being plain text, not markup. Implementations that inappropriately treat the value of the name element as markup will be vulnerable to the XSS attack. Surprising, there are actually quite a few readers that do so.
Also consider Test #6 of everything5.atom:
<entry>
<title>6. atom:category with script term</title>
<id>http://www.snellspace.com/public/everything5.atom#6</id>
<link href="http://www.snellspace.com/public/everything5.atom#6"/>
<category term="<script>alert('Security Test #6');</script>"/>
<content>blank</content>
<updated>2006-08-09T12:12:12Z</updated>
</entry>
Some feed readers will take the value of the category term and will drop it directly into a browser view as markup without sanitizing the value. The term attribute is defined as being plain text.
As a general rule, implementations need to properly support the difference between plain text and markup and be careful to look for XSS exploits anywhere text or URIs can be included in a feed. These include elements such as atom:title, atom:rights, atom:subtitle, atom:summary, atom:content, atom:link, atom:category, atom:icon, atom:logo, atom:author, atom:generator, atom:contributor, etc.
The xml:base attribute is another interesting way of injecting script into a feed. Consider, for instance, the feed-level alternate link of everything5.atom:
<link xml:base="javascript:alert('alternate_link_test')//" href="" />
Implementations that are not careful to scan for unsafe URI schemes in xml:base will end up resolving the relative href attribute reference against the javascript URI.
Another way of screwing with folks is to use doctype declarations to redefine standard HTML entities as shown in everything5.atom:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE feed [
<!ENTITY pwned "javascript:alert('Security Test #31')">
<!ENTITY nbsp "<script>javascript:alert('Security Test #32')</script>">
<!ENTITY raquo SYSTEM "http://www.snellspace.com/public/33.html">
]>
...
<entry>
<title>32. Redeclared DTD Entity</title>
<id>http://www.snellspace.com/public/everything5.atom#32</id>
<updated>2006-08-09T12:12:12Z</updated>
<link href="http://www.snellspace.com/public/everything5.atom#32"/>
<content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> </div></content>
</entry>
Parsers that allow doctype entity declarations will expand the “ ” entity in the content element into “<script>javascript:alert(’Security Test #32′)</script>” rather than the standard non-breaking space.
In my testing I tried a number of techniques that would allow me to target specific individual feed readers. Based on the User-Agent header sent with most feed requests, I was able to inject script exploits against specific feed readers that would not show up in other agents. That is, you could load a feed in Feed Demon and see a XSS exploit but load that same feed in Firefox or IE to view the source and the exploit would not be there, making it very difficult to actually spot the problem.
Further, some feed readers (e.g. FeedDemon, RSS Bandit, etc) that incorporate browser-widgets in their UI to display entries use implementation specific URI schemes to inject functionality into the browser view. The “fdaction” URI scheme provides direct access to a variety of Feed Demon functions, such as toggling an entries read status, triggering the subscribe/unsubscribe dialogs, deleting entries or subscriptions, prompting users to bookmark links on del.icio.us, etc. If a malicious script does get through the sanitation filter, it is possible for those script to use the fdaction URI scheme to seriously annoy users.
It needs to be pointed out that these issues are not limited to Atom. The XSS exploits tested in my suite came originally from a set of RSS tests.
Update: It should be noted that a Feed Demon update has been released that resolves all of the issues uncovered by these tests. Many kudos to Nick Bradbury for the swift attention to these issue.
September 7th, 2006 at 10:56 am
FWIW, I viewed all of these ATOM feeds in IE7 RC1 on XP SP2 and it appeared to pass all the tests. However, #5 did not display as IE7 does not handle feeds with DTD’s.
September 7th, 2006 at 12:25 pm
Feed Security and FeedDemon, Part III…
Last month I promised to talk about the exploits that James Snell uncovered which left feed readers vulnerable to some very annoying script-based attacks. I didn’t want to provide details of the exploits until other feed readers had patched them,…
September 7th, 2006 at 1:52 pm
Other than FeedDemon, do you know of any other aggregators that have released updates that fix these problems? Even the latest version of FeedDemon is vulnerable to trivial vartiations of these attacks.
Personally I think it was way too early to be talking about this stuff publically, but I guess there’s nothing that can be done about it now.
September 7th, 2006 at 10:09 pm
James Holderness:
Bloglines released an update two weeks ago address theses issues, and AFAIK, isn’t vulnerable to any of them now.
September 8th, 2006 at 4:49 am
Google Reader released an update late in August to address issues uncovered by James’s test suite.
September 8th, 2006 at 5:12 pm
To confirm Brent’s ad-hoc tests, IE7 is not vulnerable to these tests (you can get the rest of the tests in #5 to work by removing the entity declarations and the places they are used). We’ve posted about these results on our blog (http://blogs.msdn.com/rssteam/archive/2006/09/09/747111.aspx)
September 29th, 2006 at 8:00 am
[…] I happened accross a link at snellspace.com showing some interesting XSS tests he had done in RSS readers. Typically I’m not particularly interested in RSS reader security unless it applies to web applications, but he actually showed a vector that I hadn’t seen before. <link xml:base="javascript:alert('XSS')//" href="" /> […]
October 27th, 2006 at 2:49 pm
XSS in your RSS is ASS…
Well placed Javascript could bring the blog world to it’s knees….
December 2nd, 2006 at 8:31 pm
Awasu 2.2.5.alpha1 released…
The first 2.2.5 alpha release (what’s this?) is now available here.
This is one of those depressing releases where we’ve busted a gut changing how things work under the hood but you will probably not see too much different
Awasu has long …