Recently a client was concerned that their SWF was “insecure” because the XML path was coming from Flashvars. This seems to me to be something that isn’t really a concern as the SWF is only displaying images / text and a few button links. I can understand how someone could path to the swf and add a remote XML path in to add javascript to the button url targets, but really what damage could this do?
Eg.
they could change
http://mysite.com/theflash.swf?xmlpath=xml/thedata.xml
to this
http://mysite.com/theflash.swf?xmlpath=http://dodgysite.com/thechangeddata.xml
Obviously they could build a fake wrapper html file around this but I still don’t see how they could do anything harmful with this. Am I missing something?
My next question is what is the best way to go about preventing this from happening?
So far I have in my XSS checking class:
- unescape the string and remove any
spaces or linebreaks (\t, \n, \r) - check the string for any of the
following (asfunction:, javascript:,
event:, vbscript:) - check for absolute or relative path
by looking for (http or https) - if absolute, check that the domain is
the same as the main movie.
Most of this process I found in this article: http://www.adobe.com/devnet/flashplayer/articles/secure_swf_apps_02.html
Is there a better way than this?
What else could be done to prevent XSS in flash?
Blacklisting is a terrible solution. The implicit assumption is that “I’ll be able to catch all attacks if I look for these substrings”; it’s often wrong:
http://example.com/theflash.swf?xmlpath=../../../../userUploads/innocent.xml.Ultimately, you’re trying to figure out how a URL parser will treat the string by looking for a few substrings. It’s much more effective to stick it through a URL parser and extract the relevant semantics yourself.
I think a potentially safe option is to ensure that the path starts with “xml/” and doesn’t contain “/../”, but it’s still a terrible “solution”.
A better option is a whitelist: The filename can only contain [a-z0-9_-]. You generate the path with “xml/$filename.xml”. This works provided you don’t make a “test.xml”.
An even better option is just to maintain a mapping from names to paths, e.g. “data” maps to “xml/data.xml”, but “exploit” has no mapping, so it returns an error. It means you can’t add files as easily, but also means that the user cannot specify arbitrary paths.
EDIT: Security problems like this arise because of unexpected interactions between different parts of the system (“all files on the filesystem can be trusted”) or incorrect assumptions (“URL resolution will give a URL under the same ‘directory'”, “concatenating paths can’t navigate up the directory hierarchy”, “all filenames are normal”, “checking whether a directory exists can’t create it”). I’ve given an example; no doubt there are others.
If you need to make the config different per deployment, then … use a config! foo.swf could fetch config.xml, which contains a list of allowed paths. Better is to have config.xml give a mapping from page name to XML path.
In general, exposing implementation details like “all paths happen to match
xml/.*\.xml” is icky, a layering violation, and looks a lot like bad security.