Any John Carpenter fan knows the only way you’ll escape from New York is if Snake Plissken is there to get you out. When it comes to web security, don’t bother waiting for Kurt Russell’s help. You’re on your own.
The setup is simple: An app has a search box; it accepts queries via parameter
q of a form, and rewrites the input box’s
value directly, which would be as trivial as the following (with “abc” as the search term):
<input id="searchResult" type="text" name="q" value="abc">
On the other hand, if you move the server-side string concatenation from the
<input> field to a
<script> tag, then you’ve shifted the problem without stepping towards a solution. The
Rather than strip apostrophes from the search variable’s value, the developers have decided to escape them with backslashes. Here’s how it’s expected to work when a user searches for abc’.
document.getElementById('searchResult').value = 'abc\\'';
document.getElementById('searchResult').value = 'abc\\\\'';
// ⬇ end of string token value = 'abc\\\\''; // ⬆ dangling apostrophe
\\ as a single backslash, accepts the apostrophe as the string terminator, and parses the rest of our payload.
document.getElementById('searchResult').value = 'abc\\\\';alert(9)//';
+) to glue the alert function to the value:
document.getElementById('searchResult').value = 'abc\\\\'+alert(9)//';
Or we could try a payload that uses the modulo operator (
%) between the String and our alert.
Maybe the developers added the
alert function to a denylist, e.g. a regex for
alert\(, by checking for an opening parenthesis. Look up the function in the
window object’s property list; this makes it look like a string:
What happens if the denylist contained the word alert altogether? Build the string character by character:
- Normalize the data, whether this entails character set conversion, character encoding, substitution, or removal.
- Apply security checks, preferring inclusion lists over exclusion lists (it’s a lot easier to guess what’s safe than assume what’s dangerous).
- In the design phase, be suspicious of string concatenation. Figure out if there’s a safer method to bind user-supplied data to HTML.
- In the design phase, make sure your security check’s assumptions match the context where the data will be written.
Normalization is an important first step. Any time you transform data you should reapply security checks. Snake Plissken was never one for offering advice. Instead, think of The Hitchhiker’s Guide to the Galaxy and recall Trillian’s report as the Infinite Improbability Drive powers down (p. 61):
“…we have normality, I repeat we have normality….Anything you still can’t cope with is therefore your own problem.”
Good luck with normality, and trying to escape the right characters. Security isn’t certain, but one thing is, at least according to Queen – there’s ”no escape from reality.”