<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dr Nic &#187; XSS</title>
	<atom:link href="http://drnicwilliams.com/category/javascript/xss/feed/" rel="self" type="application/rss+xml" />
	<link>http://drnicwilliams.com</link>
	<description>Ruby makes Rails, Javascript makes Ajax, Dr Nic makes Magic</description>
	<lastBuildDate>Sat, 12 Nov 2011 01:05:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>DIY widgets &#8211; How to embed your site on another site</title>
		<link>http://drnicwilliams.com/2006/11/21/diy-widgets/</link>
		<comments>http://drnicwilliams.com/2006/11/21/diy-widgets/#comments</comments>
		<pubDate>Tue, 21 Nov 2006 21:24:05 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[XSS]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/11/21/diy-widgets/</guid>
		<description><![CDATA[UPDATE: Demo and tutorial fixed for IE7. UPDATE: Opera-supporting code. I used to wonder how Google AdSense worked. How did those ads from over at Google get on another site over here? This article ignores how Google did it and shows you how you can do it. That is, shows you how to embed JavaScript [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2008/01/04/autotesting-javascript-in-rails/' rel='bookmark' title='Permanent Link: Autotesting Javascript in Rails'>Autotesting Javascript in Rails</a> <small>I used to love Javascript so much that it would...</small></li><li><a href='http://drnicwilliams.com/2007/03/08/syntax-highlighting-in-tumblr/' rel='bookmark' title='Permanent Link: Syntax Highlighting in Tumblr'>Syntax Highlighting in Tumblr</a> <small>I wrote an email to the lovely Tumblr people asking...</small></li><li><a href='http://drnicwilliams.com/2006/11/23/supporting-json-in-rails-or-anywhere/' rel='bookmark' title='Permanent Link: Supporting JSON callbacks in Rails'>Supporting JSON callbacks in Rails</a> <small>Now you know how to write JavaScript widgets, now you...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE:</strong> Demo and tutorial fixed for IE7.</p>
<p><strong>UPDATE:</strong> <a href="http://pastie.caboo.se/41097">Opera-supporting code</a>.</p>
<p>I used to wonder how Google AdSense worked. How did those ads from over at Google get on another site over here? This article ignores how Google did it and shows you how you can do it. That is, shows you how to embed JavaScript widgets on other people&#8217;s websites.</p>
<h3>Demonstration</h3>
<p>As a demonstration, the following yellow box and text is dynamically generated from a 3rd party web server without using Ajax:</p>
<div id="no_script"><a href="http://drnicwilliams.com/2006/11/21/diy-widgets/">Click to see Demo at site</a></div>
<p><script src="http://drnicwilliams.com/wp-content/uploads/2006/11/xss_magic.js"></script></p>
<h3>The embedded code</h3>
<p>Only one line of code is required to activate the widget to perform the preceding trick:</p>
<pre>
&lt;script src="http://drnicwilliams.com/wp-content/uploads/2006/11/xss_magic.js">&lt;/script>
</pre>
<p>You can copy that line into any HTML page (even a static file on your computer) and it will generate the same HTML view. Sexy magic.</p>
<h3>Cross Site Scripting</h3>
<p>The ability for Google and you to embed dynamic content on someone else&#8217;s site is called <a href="http://en.wikipedia.org/wiki/Cross_site_scripting">Cross Site Scripting</a> (XSS). If you read the Wikipedia <a href="http://en.wikipedia.org/wiki/Cross_site_scripting">page</a>, the first sentence announces warnings and dire consequences:</p>
<blockquote><p>Cross-site scripting (XSS) is a type of computer security vulnerability typically found in web applications which allow malicious web users to inject HTML or client-side script into the web pages viewed by other users.</p></blockquote>
<h3>XSS rocks and Wikipedia is wrong</h3>
<p>So, Wikipedia and Google differ in their thinking. I&#8217;m with Google. XSS rocks. Wikipedia is for 15 year olds who are too lazy to research their own essays.</p>
<p>Its one thing to provide users of your sites with a REST API or include <a href="http://microformats.org/">microformats</a> into your HTML, and let them get their dirty hands on your data.</p>
<p>But its another level of mutual lovey-dovey-ness entirely between for users to be able to embed something from your site into their site. Not just images, but dynamic, sex-on-a-stick content. Like Google <a href="http://www.google.com/services/adsense_tour/">AdSense</a>, or <a href="http://www.sphere.com/">Sphere</a> (see the &#8220;Sphereit&#8221; icon at the bottom of any <a href="http://www.techcrunch.com">TechCrunch</a> article), or all the various wacky <a href="http://digg.com/tools">Digg tools</a> (where you can embed &#8220;Digg this&#8221; etc into your page and look supercool).</p>
<h3>How to do this</h3>
<p>If you&#8217;ve been diligent enough to learn Javascript, you too can do this at home without parental supervision.</p>
<h3>Things you&#8217;ll need</h3>
<p>The following things are lying around on the internet for you to use:</p>
<ol>
<li>A copy of someone else&#8217;s website, say like an article from <a href="http://ajaxian.com/">Ajaxian</a> [<a href="#xss-1">1</a>]. This will be called the <em>mock</em> page.</li>
<li>Some data you want to embed into the site. Relax, it will look pretty when the users sees it. Your data <strong>must</strong> be in <a href="http://en.wikipedia.org/wiki/JSON">JSON</a> format. But I&#8217;ll explain this later on.</li>
</ol>
<h3>The run-thru of what will happen</h3>
<p>The user will load up the webpage (e.g. Ajaxian mock page) that has a small <code>&lt;script src="http://<em>yoursite.com</em>/magic_xss.js">&lt;/script></code> snippet in it [<a href="#xss-2">2</a>]. When the page is loaded, the <code>magic_xss.js</code> file is loaded too. The user doesn&#8217;t know nor care.</p>
<p>When the <code>magic_xss.js</code> file is loaded it will do a couple of things:</p>
<ol>
<li>Install any stylesheets it needs</li>
<li>Insert an empty, invisible HTML element into the page (e.g. <code>&lt;div id="my_magic_xss" /></code>). </li>
<li>Read in any variables (e.g. Google Adsense requires the website owner to specify a number of variables, such as <code>google_ad_format</code>)</li>
<li>Fetch any additional Javascript files or data. This is where even more dynamic magic can be performed. When requesting the additional data, you could pass back the current document&#8217;s URL or the current users&#8217;s IP address, and the webserver could return data that is relevant to that URL or IP address/geographic location. Clever, eh.</li>
<li>Insert new HTML into the <code>#my_magic_xss</code> element based on the data that is returned from your own server. Your server &#8211; not the host website&#8217;s server.</li>
</ol>
<h3>XSS is not Ajax</h3>
<p>Technically speaking, Ajax uses the XmlHttpRequest object within the browser to fetch content. Unfortunately, in all browsers, it can only fetch content from the same server as the webpage.</p>
<p>That&#8217;s why XSS is interesting &#8211; we&#8217;re fetching data from a 3rd party server. Your server. So, we can&#8217;t use XmlHttpRequest.</p>
<h3>The tutorial</h3>
<p>Hereafter is the tutorial to explain all this. No specific webserver is required for the tutorial &#8211; the data returned will be a static file, though you will implement this with your own webapp to be dynamic.</p>
<h3>The data</h3>
<p>Later on in the tutorial we&#8217;ll need some data to represent the dynamic content from your server.  For the sake of the demo, you can use my data: <a href="http://drnicwilliams.com/wp-content/uploads/2006/11/people_list.js">http://drnicwilliams.com/wp-content/uploads/2006/11/people_list.js</a></p>
<p>Remember, in real life this would be a dynamic server request returning dynamic JSON data.</p>
<p>Here&#8217;s the JSON we&#8217;re going to be using:</p>
<pre>
MyMagicXss.serverResponse(['Dr Nic', 'Banjo', 'Angus']);
</pre>
<p>Down the track, this bit of Javascript will be invoked on the browser. It will look for the function <code>MyMagicXss.serverResponse</code> and invoke it with the Array <code>['Dr Nic', 'Banjo', 'Angus']</code>. The server function would be the same each time. The data would be different.</p>
<h3>The embedded javascript</h3>
<p>The point of showing you the dynamic data first is to show us that we need 3 things:</p>
<ol>
<li>A way to fetch and evaluate remote javascript without using XmlHttpRequest</li>
<li>A function <code>MyMagicXss.serverResponse</code></li>
<li>A place to display these results on the host webpage</li>
</ol>
<p>These three things are done by the original page that is loaded into the host webpage when the user visits. For our tutorial, this is the <code>xss_magic.js</code> file: <a href="http://drnicwilliams.com/wp-content/uploads/2006/11/xss_magic.js">http://drnicwilliams.com/wp-content/uploads/2006/11/xss_magic.js</a></p>
<p>This file looks like:</p>
<pre>
MyXssMagic = new function() {
  var BASE_URL = 'http://drnicwilliams.com/wp-content/uploads/2006/11/';
  var STYLESHEET = BASE_URL + "xss_magic.css"
  var CONTENT_URL = BASE_URL + 'people_list.js';
  var ROOT = 'my_xss_magic';

  function requestStylesheet(stylesheet_url) {
    stylesheet = document.createElement("link");
    stylesheet.rel = "stylesheet";
    stylesheet.type = "text/css";
    stylesheet.href = stylesheet_url;
    stylesheet.media = "all";
    document.lastChild.firstChild.appendChild(stylesheet);
  }

  function requestContent( local ) {
    var script = document.createElement('script');
    // How you'd pass the current URL into the request
    // script.src = CONTENT_URL + '&#038;url=' + escape(local || location.href);
    script.src = CONTENT_URL;
    <span class="command">// IE7 doesn't like this: <strong>document.body.appendChild(script);</strong>
    // Instead use:</span>
    document.getElementsByTagName('head')[0].appendChild(script);
  }

  this.serverResponse = function( data ) {
    if (!data) return;
    var div = document.getElementById(ROOT);
    var txt = '';
    for (var i = 0; i < data.length; i++) {
      if (txt.length > 0) { txt += ", "; }
      txt += data[i];
    }
    div.innerHTML = "&lt;strong>Names:&lt;/strong> " + txt;  // assign new HTML into #ROOT
    div.style.display = 'block'; // make element visible
  }

  requestStylesheet(STYLESHEET);
  document.write("&lt;div id='" + ROOT + "' style='display: none'>&lt;/div>");
  requestContent();
}
</pre>
<p>For the most part you should be able to reuse that and modify it as necessary. </p>
<h3>No Javascript frameworks allowed</h3>
<p>First point &#8211; we should not rely upon any Javascript frameworks (e.g. prototype or jquery) as they might conflict with any Javascript already active in the host page. So, our code is encapsulated in an object <code>MyXssMagic</code> which we hope is unique on any host page.</p>
<h3>Step one &#8211; install stylesheets</h3>
<pre>
  requestStylesheet(STYLESHEET);
</pre>
<p>So that your embedded HTML looks pretty you might want to preinstall your own stylesheets.</p>
<h3>Step two &#8211; create the holder element</h3>
<pre>
  document.write("&lt;div id='" + ROOT + "' style='display: none'>&lt;/div>");
</pre>
<p>This allows the code to subsequently know where to insert HTML. Here we&#8217;re going to install the HTML at the same location where the host inserted our <code>&lt;script src="..."></code> code.</p>
<h3>Step three &#8211; request remote data</h3>
<pre>
   requestContent();
</pre>
<p>which invokes&#8230;</p>
<pre>
  function requestContent( local ) {
    var script = document.createElement('script');
    script.src = CONTENT_URL;
    <span class="command">// IE7 doesn't like this: <strong>document.body.appendChild(script);</strong>
    // Instead use:</span>
    document.getElementsByTagName('head')[0].appendChild(script);
  }
</pre>
<p>We&#8217;re going to load our data by creating a new <code>&lt;script src="..."></code> element into the page. We can&#8217;t use XmlHttpRequest, so this is all we have. This means that the response must be pure Javascript, and must invoke a callback function so that the browser does something with the data.</p>
<h3>Step four &#8211; process response</h3>
<p>The browser automatically executes the returned data (introduced earlier):</p>
<pre>
MyMagicXss.serverResponse(['Dr Nic', 'Banjo', 'Angus']);
</pre>
<p>This invokes our callback function:</p>
<pre>
  this.serverResponse = function( data ) {
    if (!data) return;
    var div = document.getElementById(ROOT);
    var txt = '';
    for (var i = 0; i < data.length; i++) {
      if (txt.length > 0) { txt += ", "; }
      txt += data[i];
    }
    div.innerHTML = "&lt;strong>Names:&lt;/strong> " + txt;  // assign new HTML into #ROOT
    div.style.display = 'block'; // make element visible
  }
</pre>
<p>This inserts &#8220;<strong>Names:</strong> Dr Nic, Banjo, Angus&#8221; into the element <code>#my_magic_xss</code>, as per the demostration at the start of the article.</p>
<p><strong>Magic!</strong></p>
<h3>Epilogue &#8211; dynamic interactions</h3>
<p>Loading dynamic data and adding HTML into a host page is easy, as shown. Supporting user interactions, where you dynamically load new data and show new HTML, is slightly more complicated.</p>
<p><strong>Remember the rule</strong>: the returned JSON data must be wrapped in a callback function (e.g. MyMagicXss.serverResponse(&#8230;data&#8230;)).</p>
<p></p>
<p><a name="xss-1">[1]</a> I suggest Ajaxian.com to you because I fancy they might give me something free for doing it. Here&#8217;s hoping.</p>
<p><a name="xss-2">[2]</a> This snippet got into the page because the authors of the site embedded it for you. You can&#8217;t make them. But copying a bit of text into a website template is common place thanks to Google AdSense etc, so unless your target audience is 1800th century quilting website owners, you should be fine. Write up some instructions, and give them the small chunk of HTML that they need to embed.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2008/01/04/autotesting-javascript-in-rails/' rel='bookmark' title='Permanent Link: Autotesting Javascript in Rails'>Autotesting Javascript in Rails</a> <small>I used to love Javascript so much that it would...</small></li><li><a href='http://drnicwilliams.com/2007/03/08/syntax-highlighting-in-tumblr/' rel='bookmark' title='Permanent Link: Syntax Highlighting in Tumblr'>Syntax Highlighting in Tumblr</a> <small>I wrote an email to the lovely Tumblr people asking...</small></li><li><a href='http://drnicwilliams.com/2006/11/23/supporting-json-in-rails-or-anywhere/' rel='bookmark' title='Permanent Link: Supporting JSON callbacks in Rails'>Supporting JSON callbacks in Rails</a> <small>Now you know how to write JavaScript widgets, now you...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/11/21/diy-widgets/feed/</wfw:commentRss>
		<slash:comments>80</slash:comments>
		</item>
	</channel>
</rss>

