Securely execute XSLT stylesheets?

I did not find very much information about security concerns of untrustworthy XSLT stylesheets I would like to execute on a server, so I write down some of my issues.

Following problem: you write a web application multiple users use, just imagine a twitter page or something like that. Now you would like to give each user the opportunity to customize the look and feel how they like. How to solve if you can’t trust the userbase? We could give an opportunity to customize the CSS stylesheets, but that would not result in a huge degree of freedom, because users are unable to add text and so on if you don’t code it.

XSLT seems to handle such a problem. It would be great if we could let users customize their own xslt stylesheets which transform XML we generate into HTML. Everyone could customize their design like they want. In addition we would be able to fully separate our code logic from design, but xslt is a programming language and untrusted users would be able to execute arbitrary XSLT code on the server. Would that be a security issue? Generally spoken: yes, but any specfic problems of XSLT?

Suppose we are using some kind of library like xslt for ruby for example. We produce XML through a script and want to read in a stylesheet (the user can customize) to transform it into HTML through the library. A first obvious security problem of XSLT is the document() function:

<xsl:value-of select="document('/home/otheruser/secret.xml')/secrect/text()"/>

This function lets us access secret data. With Some libraries we are unable to deny the use of this function. More comfortable libraries are able to use some kind of Security Framework, like xslt for perl which uses the security framework of libxslt. We register callback functions to deny some security issues, like read_file, read_net, create_dir, and so on.

$security->register_callback(read_file  => $read_cb);
$security->register_callback(write_file => $write_cb);
$security->register_callback(create_dir => $create_cb);
$security->register_callback(read_net   => $read_net_cb);
$security->register_callback(write_net  => $write_net_cb);

Quite satisfying, but unfortunatly this does not remove all concerns. XSLT has a

<xsl:import href="/home/otheruser/secret.xsl"/>

or

<xsl:include href="/home/otheruser/secret.xsl"/>

Well, we would guess that our callback function would deny such an access, because we are denying any kind of read actions to our hdd or the network, but we are wrong, because it does not and I did not find a solution for that. This could potentially lead to a security issue if we let untrustworthy users execute arbitrary stylesheets, because users would be able to access arbitrary stylesheets from our hdd which contain sensitive data. Well it looks rather library specifc, but libxslt is very common, so the same issues apply to php’s xslt functionality for example. I did not find very much security related documentation for other libraries yet, too (xalan, saxon). See the libxslt mailing list as well.

We could place a sanitizing function between it. When the user customizes the stylesheet we check it for correctness and disallow stylesheets containing insecure behaviour, but imo a sanitizing function is always the most insecure and buggy option, because errors in sanitizing functions result in a flaw at most.

If the client, aka browser, is able to execute stylesheets for its own we could push the security responsibility away from our side, but using xslt functionality of browsers is not yet feasible imo, because xslt is not old enough yet.

While these obvious issues can be solved through adding the adequate checks within the libraries, general security issues remain: users can execute arbitrary code on your server, so if the code runs wild, your server runs wild too (inifinite loops resulting in denial of service, security flaws through bugs which will be exploited immediatly, because everyone is able to execute the code neccessary for exploitation, …).

Leave a Reply

CAPTCHA Image Audio Version
Reload Image