2

My web-app takes some configs from the user and saves into an XML file (it was not done to stop XSS). The input is XML encoded so that the ",& ... and such characters don't break the XML structure.

So is there a need to have another layer of XSS filter or will this way of saving the data automatically stops XSS attacks.

I'm aware of the fact that this attack depends on lots and lots of other factors such as rendering the webpage but lets confine the discussion to the following code snippet, however since the way I'm going to print the data very from time to time you are free to modify echo "<h1> Hello ".$name."</h1>" to show me any wrong ways of printing data.

$data = $_POST['malicious_user_supplied_data'];
$xml_encoded_data = xml_encode($data);
write_to_xml_as($xml_encoded_data,"config.xml");

------ config.xml --------
<user>
   <name>&lt;script&gt;alert(&quot;BigBang&quot;)&lt;/script&gt;</name>
</user>
--------------------------    

$name = get_name("config.xml") // would return &lt;script&gt;alert(&quot;BigBang&quot;)&lt;/script&gt;

echo "<h1> Hello ".$name."</h1>" // which on the browser would print &lt;script&gt;alert(&quot;BigBang&quot;)&lt;/script&gt;

Please show me some working examples where the above XML filter can be broken, if there are any.

  • 1
    Assuming get_name returns the XML decoded version of name, you will need to HTML encode it for output in your page (echo statement). – SilverlightFox Aug 6 '14 at 12:17
  • @SilverlightFox I've made some edits, the get_name does not decode anything – vikkyhacks Aug 6 '14 at 12:23
  • Keep it simple.... make get_name XML decode because you expect that to return a name in plain text. Then HTML encode when output to HTML (e.g. inline on your echo call). – SilverlightFox Aug 6 '14 at 12:32
  • With what headers is the HTML served? If you don't have any <meta charset="..."> or equivalent header, then encoding-level attacks might be possible. – Mike Samuel Aug 6 '14 at 17:13
  • Writing and reading from a file is subject to race conditions. Does the kind of file system you're on make it impossible for get_name see the beginning of one write from write_to_xml_as and the end of another? – Mike Samuel Aug 6 '14 at 17:16
1

I'd rather use JSON instead of XML. It is easier to understand how the parser works and so the security risks are much lower. For example you have to turn off loading external entities with libxml_disable_entity_loader(true) if you don't want an XXE attack, and so on.

The other part of the question is the generation of HTML, SVG etc. in the browser. For example with innerHTML = "..." it is easy to inject javascript. With data tags it is possible to inject javascript into firefox, so filtering only script tags is not enough... You have to use always DOM functions like createTextNode() instead of innerHTML. You don't need a server side storage to inject javascript. Displaying cookie or query parameters using javascript is more than enough. On server side you have to use DOM functions either, I am uncertain how secure they really are, but they are much better than concatenating strings... Ofc. you have to filter against HTML elements, etc... But if you need a rich text editor then you have a big problem...

I think one layer of security is never enough, and in this case it is certainly not enough. This is because HTML parsers are very complex piece of technology, and most developer (including me) only understands the basics of them. What you really need in this case are some security headers, like Content-Security-Policy. So the injected script won't be able to communicate with the attacker domain. (Ofc. this does not work in old browsers like ie6.)

  • +1 for XXE. That's dangerously underestimated stuff. – Mints97 Feb 19 '15 at 8:13
0

It's hard to say, if above code is fully secured, as you didn't provide us the definition of xml_encode function. Basing on your input/output samples, it looks, that xml_encode is similar to htmlspecialchars which could be used to sanitize your XML data too.

If I were you, I'd decide to use htmlspecialchars with correct flags (ENT_QUOTES) or libraries for building XML docs (e.g. DOMDocument::createTextNode will do encoding for you).

As there is no definition of xml_encode function, let's play with black-box guessing, what could go wrong here.

  • Incorrect encoding: You need to make sure that webapplication sets the correct charset (e.g. UTF-8). Otherwise, your webapp could be vulnerable to XSS UTF-7 attacks. This problem concerns only old browsers.

  • UTF-8 characters: Does xml_encode encode UTF-8 characters? How they are displayed after encoding process?

  • CDATA section: This one could be the tricky one, if your xml_encode ignores CDATA sections. These sections inform the parser, that there is no markup in the characters inside CDATA. You have to make sure, that < > " & are also encoded inside CDATA.

  • Single apostrophe: Is single apostrophe also encoded? If no, then you have to take care, while displaying data from XML. <input type='text' value='<?php echo get_name("config.xml"); ?>' />. Above example shows vulnerable code, as an attacker, could inject aa' autofocus='on' onfocus='alert(1) as his payload.

  • Tag names: Are you planning to allow the user, to control tag-names too? If yes, then you have to be aware, that there is a chance to perform XSS directly from .xml file. Take a look here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.