Wednesday, February 27, 2013

Frame busting

More and more websites don't want them to be iframed in other websites, so they added frame busting setting or codes to their websites. Our web clipper can clip website URLs as a bookmark, so we need to deal with this frame busting thing - which is called anti-frame-busting or preventing frame busting.

Three ways if you don't want your website iframed in other websites:
1. X-Frame-Options: deny
In http header, and implemented by most browsers. iOS UIWebView seems to have not implemented this as of writing.

2. Traditional Javascript code
if (top != self) { top.location.replace(self.location.href); }

3. Javascript to show/hide body due to clickjack security concern
<body style="display:none" ...>
try {
  if (top.location.hostname != self.location.hostname)
    throw 1; = 'block';
} catch (e) {
  // possible clickjack attack, leave content hidden

Then how to prevent frame busting?
Check out for the discussions.

Javascript detects if browser extension is installed

There is no easy or standard way for all browsers, but it is possible to use Javascript to detect if certain extension is installed or not. Today I quickly looked at Chrome/Firefox/Safari for this requirement (the list below is also in this browser order).

List all installed extensions

Find installed extensions on Mac OSX
~/Library/Application Support/Google/Chrome/Default/Extensions/
~/Library/Application\ Support/Firefox/Profiles/[profile name]/extensions/

Image URL to detect if extension is installed
chrome-extension://[extension-id]/[image_file], I am not sure if chrome needs web_accessible_resources in manifest.json. However, something like chrome-extension://hojdhekmpemkfjblemnmefjjocededbe/image.png always works even when the extension is disabled.

chrome://[extension-name]/content/[image_file], firefox needs contentaccessible=yes in chrome.manifest and also needs the extension is enabled.

Unfortunately I could not find how to use image URL for Safari (safari.extension.baseURI is a dynamic value after safari restart). One possible way is to inject a HTML node from extension to your target website, if you have control of the extension source code.

How to do image URL based detection?
In your website, add one hidden image element
hidden_img.addEventListener("load", function(e){
   console.log('extension installed');
}, false);
hidden_img.addEventListener("error", function(e){
   console.log('extension not installed');
}, false);

Friday, February 22, 2013

Change meta tag content using Javascript?

Instead of server side rendering, can I dynamically change meta tag content using Javascript or jQuery? The answer is yes and no.

Why yes?
Literally, jQuery can change meta tag content like below:
$('meta[name=author]').attr('content', 'new_name');
$('meta[name=og\\:url]').attr('content', 'new_url');

Some browsers and plugins parse meta elements and change their behavior for different values.
Viewport definition for mobile devices
<meta name="viewport" content="width=device-width, initial-scale=1.0">

iPhone: Switch off phone number parser
<meta name="format-detection" content="telephone=no">

Google Chrome Frame
<meta http-equiv="X-UA-Compatible" content="chrome=1">

Some user agents use the description for bookmarks
<meta name="description" content="this is description">

Why no?
Search engine (e.g. Googlebot), Social indexer (e.g. Facebook Scrapper, twitterbot) always get the meta elements that are in the source HTML, never observe meta tag added or changed with client side JavaScript. Search engines will ignore javascript to alter the meta values. Facebook scrapper sees crawled page the same way that search engine robots do, so changing open graph meta tags with Javascript will be invisible to the Facebook linter either. The solution is to do server side rendering with correct meta tags.

First look at Facebook Platform

To be honest, I don't use facebook (I use twitter every day), but recently we need integration facebook to our web app for few features:
1. Facebook login
2. Facebook invite friends
3. Facebook social like button

With that, I head to for an overview of Facebook platform. And I am thrilled to see how well it is designed, built, organized and documented. Here are my takeaways to a great platform.

Developer friendly
Built for developers is very important to thrive platform ecosystem. Google is always doing in this way and appears very developer-friendly, and I believe Facebook is doing the same way after I initial overview of this developer portal. The value of "Platform" is to have 3rd party applications developed on top of it, or integrated with it. Whether it is developing app or integrating existing system with the platform, developers are the main resources to make it happen. Therefore, developer friendly is vital to a successful platform.

Well-designed API
API (application programming interface) is the interfaces between platform and integration applications. Developers always like lightweight, standard, straightforward API. REST, Open Social, Open graph etc are popular ones. Based on these standard or mature protocol, design carefully for developers, so that developers can easily understand your API design principle. Also API should be backward compatible and versioning enabled.

SDK (software development kit) brings "developer friendly" goal a step further on top of well-designed APIs. With SDK, developers can focus on business and integration efforts while using local imported SDK. It is no difference to invoke other local classes/methods/interfaces. Facebook Javascript SDK provides both FB.api (pure open graph api) and FB.ui (dialog/widget) which are really developer-friendly to give developers more flexibility.

Documentation and Tools
Most developers don't read through API documents before coding, instead they look for sample codes and try out, and reference to API user guide or SDK documentation when meet issues. Therefore well-indexed and organized documentations are most developers want. Besides documentation, developer tools are another plus to help developers to build app on top of the platform, or integrate system with the platform. We all need tools, just like we need IDE when writing/debugging codes.

Forum, FAQ, email, or phone call to support developers to get through their obstacle when they use your platforms. The platform providers know more than any one else, so don't hesitate to listen to developers and provide timely support.

This is what I resonated when I go through from Facebook. Years ago, when we started API, we didn't realize "developer friendly" and only worked on API and User reference guide. 2 years ago, when we redesign a new system, we want "developer friendly" but still could not implement all of above key items. Now, when we have the chance to develop a new platform, we definitely will move in this way.

Tuesday, February 19, 2013

Canon Printer: Failed to read module Re-install.:20600

After upgraded Mac OSX to 10.8.x, previous printer cannot work, and it always show "Failed to read module Re-install.:20600" when do print from preview or other application.

The quick and easy solution is to download the latest driver for corresponding OS and printer model from canon website.

From this support site, browser your canon printer and find the download links. After updated the printer driver to correct version of your OS and printer model, then it comes to work again.

Friday, February 1, 2013

Javascript RSA

In terms of crypto in Javascript, from google search result, pidcrypt seems to be the most mentioned library. pidCrypt is a crypto library offering modular cryptographic functions in JavaScript. Supports: AES (CBC & CTR Mode), RSA, MD5, SHA-1, SHA-256, SHA-384, SHA-512, ASN.1, Base64, UTF-8. The AES-CBC mode is compatible to OpenSSL.

In my current project, I am looking for a lightweight library or Javascript class to do Javascript RSA encryption, so I found from github. Before I included them into my project, I tested the performance on Mac OSX for 3 different browsers. And the result is: Google Chrome 24.0.1312.56 is much faster than Safari 6.0.2 and Firefox 18.0.1. Chrome is around 6ms, while Safari/Firefox is around 20ms per encryption.

For test, we need first to generate a keypair using OpenSSL, and it is straightforward on Mac OSX.
openssl genrsa -out private_key.pem 1024
openssl rsa -pubout -in private_key.pem -out public_key.pem
openssl rsa -text -in private_key.pem

Update: 2/24/2013
After evaluating the implementation effort, we decided to change to HMAC from original planned RSA. It is also straightforward when there is existing crypto libraries for hmac.

<script type="text/javascript" src=""></script>
<script type="text/javascript" src=""></script>

hmacString = Crypto.HMAC(Crypto.SHA1, message, secret-passphrase, { asString: true })
base64String = $.base64.encode(hmacString);