1. Subverting AJAX with Injected XML
1.1. Problem
Your application uses AJAX and it passes data back in XML format. To test
the client-side’s handling of bad XML data, you’ll need to generate bad
XML and have it parsed by your application.
1.2. Solution
Creating malicious XML is a topic unto itself. You can find additional guidance on testing for XML
injection via OWASP at http://www.owasp.org/index.php/Testing_for_XML_Injection.
Note that the same caveat that applies to HTML injection also
applies to XML injection: you may have to escape out of an XML tag prior
to inserting your own malicious XML string.
Except this time let’s assume that the
chat API on the server returns the chat messages in XML format, as shown
in Example 1.
Example 1. AJAX-based chat using XML
<messagelist>
<message user="jsmith">are you going to the show?</message>
<message user="mjones">yeah, mike's driving</message>
<message user="jsmith">can I hitch a ride?</message>
<message user="mjones">sure. be at mike's at 6</message>
</messagelist>
|
Since our user ID is our attack vector, we should try malicious
inputs there to test how the client-side code handles it. A user ID of
jsmith"><hr width="200 is
likely to have the same effect as our attack string in Example 10-2. The "> characters terminate the <message> tag so that the result is
<message user="jsmith"><hr width="200">are you going to the
show</message>.
1.3. Discussion
Our example is somewhat trivial in that it is obvious what the
browser will or won’t do with malicious XML.
This test is more useful when the client-side code performs some
interesting decision making, like hiding or displaying records, allowing
or denying actions, etc. Rather than customize attacks that are big and
random, use attack XML that has the potential to interfere with the
application’s functionality.
2. Subverting AJAX with Injected JSON
2.1. Problem
Your application’s AJAX components receive their input in JavaScript Object
Notation (JSON) format. You need to test how the client-side code reacts
when malicious JSON data is injected into it.
2.2. Solution
When an application evaluates a JSON string directly, anything
injected into the JSON executes immediately—without the need to embed
HTML script tags.
To inject into the JSON format, first identify the area where your
data rests in the JSON returned by the server. Once you’ve identified
the location of your input, supply escape characters for the data
structure itself and insert JSON formatted JavaScript. For example, say
you receive the following JSON:
{"menu": { "address": { "line1":"YOUR_INPUT_HERE", "line2": "", "line3":"" } }}
To inject JavaScript into this JSON string, you’d supply a string
such as ",arbitrary:alert('JavaScript
Executed'),continue:". Let’s examine this injected string
piece by piece, so that you can craft strings for your JSON data.
",
First we use double quotes to indicate a string delimiter,
ending the string encapsulating our user input. The comma
indicates that the rest of our input is a new JSON element in this
array. If you were providing an integer as the input, for example,
you wouldn’t need the double quotes, just the comma.
arbitrary:
Because this data structure is a mapping of labels to
elements, we need to provide another label prior to our injected
JavaScript. The label doesn’t matter, hence the name arbitrary. The colon indicates the
following data is the value paired to this name.
alert('JavaScript Executed')
This is the actual JavaScript injected into this JSON
object. When the page evaluates this JSON, an alert box will pop
up saying “JavaScript Executed.” This is an indication that our
test succeeded and the application failed.
,continue:"
Lastly, to complete the JSON data format and prevent syntax
errors from interrupting the injected JavaScript, provide a comma
to indicate the next JSON element, an arbitrary label, and a colon
and quotes to combine with the rest of the JSON string.
The final result of injecting this malicious input into the JSON
string is eval({"menu": { "address": {
"line1":"
",arbitrary:alert('JavaScript
Executed'),continue:"
", "line2": "", "line3":"" }
}});2.3. Discussion
The JSON format evolved as the easiest data serialization format to implement.
Evaluating the JSON string in Javascript will itself return a JavaScript
data object. It is elegant and simple, but it is very dangerous to
evaluate data directly, particularly data that the user just provided.
It’s preferable to use a JSON parser, such as the ones available (for
free!) from http://json.org/.
Be careful when sending JSON data via the query string. Evaluating JSON data directly from the
query string creates a reflected cross-site scripting vulnerability. |