Thursday, July 28, 2011

jQuery is a Sink!

What's a Sink in Application Security?
A sink can be described as a function or method that is potentially dangerous when it's (unexpectedly) called or if one of its arguments, coming from an untrusted input, is not correctly escaped according to the layer the function is going to communicate to.

The jQuery Sink
Suppose we have the following code:
var aVar=location.hash;
jQuery(aVar);

By looking at the DOMinator output, you'll see something like the following:

That means the jQuery, or its alias '$', method is trying to understand if hash contains some tags. In particular part of the JavaScript stack trace will be similar to the following:

4 14:44:40.306 :[ http://host/jQueryTest.html#aaaaa ]
Target: [ exec(^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)) CallCount: 1 ]
Data:
+ #aaaaaa
http://host/jquery-1.4.3
,Line:19
,1: function (selector, context) {
2: var match, elem, ret, doc;
3: if (!selector) {
4: return this;
5: }
6: if (selector.nodeType) {
7: this.context = this[0] = selector;
8: this.length = 1;
9: return this;
10: }
11: if (selector === "body" && !context && document.body) {
12: this.context = document;
13: this[0] = document.body;
14: this.selector = "body";
15: this.length = 1;
16: return this;
17: }
18: if (typeof selector === "string") {
19: match = quickExpr.exec(selector);
20: if (match && (match[1] || !context)) {
21: if (match[1])
...


So, by trying to put #<img/src/onerror=alert(1)> in the hash part, we'll see the following alert on DOMinator:
12 14:44:40.364 :[ http://host/jQueryTest.html ]
Target: [ DIV.innerHTML CallCount: 1 ]
Data:
+ <img src="" onerror="alert(1)" />
+ Stack Trace
http://host/jquery-1.4.3
,Line:20
,1: function (elems, context, fragment, scripts) {
2: context = context || document;
3: if (typeof context.createElement === "undefined") {
4: context = context.ownerDocument ||
5: context[0] && context[0].ownerDocument || document;
6: }
7: var ret = [];
8: for (var i = 0, elem; (elem = elems[i]) != null; i++) {
9: if (typeof elem === "number") {
10: elem += "";
11: }
12: if (!elem) {
13: continue;
14: }
15: if (typeof elem === "string" && !rhtml.test(elem)) {
16: elem = context.createTextNode(elem);
17: } else if (typeof elem === "string") {
18: elem = elem.replace(rxhtmlTag, "<$1>");
19: var tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase(), wrap = wrapMap[tag] || wrapMap._default, depth = wrap[0], div = context.createElement("div");
20: div.innerHTML = wrap[1] + elem + wrap[2];
21: while (depth--) {
22: div = div.lastChild;
23: }
.....

Which means that if the arguments of jQuery contains some kind of tag it'll be rendered using innerHTML, resulting in a potential DOM Based Xss.

Countermeasures
If you have to use some untrusted input, Data Validation and Output encoding should be performed before using it as a jQuery argument.

Wednesday, July 6, 2011

Athcon 2011 - Presentation

Athcon conference was really good and I had a wonderful time there.

My presentation was about Enterprise Sharing Portal (e.g. Microsoft Sharepoint, J2ee Liferay Portal) and the bad practice to not securing them enough before exposing them to the public. Unfortunately this ugly scenario is very frequent also for Sharepoint and Liferay portals which are exposed to the internet.

And more important, more and more frequently, Sharing Portals are the frameworks (that YOU ARE NOT aware of) that run your internet website! ... and they could even bridge external attacks to the Intranet

You can find it here:

http://www.mindedsecurity.com/fileshare/Fedon_Athcon_June11.pdf