<?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>Software and Opinions &#187; json</title>
	<atom:link href="http://ianloic.com/tag/json/feed/" rel="self" type="application/rss+xml" />
	<link>http://ianloic.com</link>
	<description>from Ian McKellar</description>
	<lastBuildDate>Thu, 19 Nov 2009 22:05:43 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Making dynamic static pages</title>
		<link>http://ianloic.com/2007/03/05/making_dynamic_static_pages/</link>
		<comments>http://ianloic.com/2007/03/05/making_dynamic_static_pages/#comments</comments>
		<pubDate>Wed, 30 Nov -0001 00:00:00 +0000</pubDate>
		<dc:creator>Ian McKellar</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[feedburner]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[rss]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[UPDATE: I changed how this works and blogged about it.
I wanted my home page to reflect what was going on in my life, or at least what content I was generating. There&#8217;s the concept of a lifestream floating around at the moment, but I was happy just to have a few sources (a couple of [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE: I changed how this works and <a href="http://ianloic.com/out_with_the_old_in_with_the_google">blogged about it</a></strong>.<br />
I wanted my <a href="http://ian.mckellar.org/">home page</a> to reflect what was going on in my life, or at least what content I was generating. There&#8217;s the concept of a lifestream floating around at the moment, but I was happy just to have a few sources (a couple of blogs, my bookmarks, my twitters and my flickr stream) shown, split out my source. The catch was I wanted to do it without implementing a web service to back it.</p>
<p>If you want to pull content from a bunch of different servers without writing any server-side code your only options are Flash and JSON. They&#8217;re both ways of getting around the web security model that&#8217;s protected us for so long. Flash is kind of complicated, requires proprietary, expensive tools to work with while JSON comes for free.  The idea behind JSON is that we can use the browser&#8217;s <code language="html"><script src="..."></script></code> tag to load a script from another serve that contains data encoded as JavaScript data structures rather than code.</p>
<p>A few key services like <a href="http://www.flickr.com/">Flickr</a> and <a href="http://del.icio.us/">del.icio.us</a> offer JSON versions of their feeds, but most do not. In steps <a href="http://www.feedburner.com/">FeedBurner</a> who in January <a href="http://blogs.feedburner.com/feedburner/archives/2007/01/hackathon_episode_iv_a_new_hac.php">added a JSON version</a> of the feeds they serve, and since you can ask FeedBurner to host any feed you please we can use them as our high-availability, standardizing, caching feed proxy. I\&#8217;d <a href="http://ianloic.com/drupal_feedburner">already</a> set up FeedBurner for this blog, so I just added feeds for my <a href="http://loic.livejournal.com/">LiveJournal</a> and <a href="http://www.twitter.com/ian_mckellar">twitter</a> accounts and looked up how to get access to the JSON feeds for my <a href="http://www.flickr.com/photos/ianloic/">Flickr</a> and <a href="http://del.icio.us/ianloic">del.icio.us</a> accounts.</p>
<p>When you call a JSON script you can often pass in the name of a callback function to be called when the data is returned. I wrote a simple one to process a JSON response from FeedBurner and turn some of the most recent items into HTML list items:</p>
<pre class="prettyprint">
var max_items = 3;
var target = null;
var filter = null;
function fb(o) {
  if (!target) return;
  for (var i=0; i&lt;o.feed.items.length &amp;&amp; i&lt;max_items; i++) {
    var item = o.feed.items[i];
    var li = document.createElement('li');
    var a = document.createElement('a');
    if (!item.title) item.title = item.date;
    if (filter) item.title = filter(item.title)
    a.appendChild(document.createTextNode(item.title));
    a.setAttribute('href', item.link);
    li.appendChild(a);
    target.appendChild(li);
  }
}</pre>
<p>The function depends on a couple of external variables that are set before the JSON feed is called. They are <code>target</code>, the DOM object to append the list items to and <code>filter</code> an optional function to post-process titles. I had to add <code>filter</code> since my twitter feed comes back a little weird.</p>
<p>Getting the most recent posts from this blog into a bullet list is now pretty straight-forward:</p>
<pre class="prettyprint">
&lt;ul id="ianloic-list" /&gt;
&lt;script type="text/javascript"&gt;
target = document.getElementById('ianloic-list');
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://api.feedburner.com/format/1.0/JSONP?uri=ianloic&amp;callback=fb"&gt;
&lt;/script&gt;</pre>
<p>Getting my LiveJournal in was identical and twitter just required me to write a filter function to chop up the title a little and do some unescaping. For some reason the twitter feed is both HTML entity encoded and JavaScript string escaped when I get it back from FeedBurner.</p>
<p>Flickr and del.icio.us each require some custom code since I want to handle each of them specially. For del.icio.us I link to the tag pages of each tag on each bookmark and for Flickr I embed a thumbnail for each image. Take a look at the source code of <a href="http://ian.mckellar.org/">ian.mckellar.org</a> to see how that&#8217;s done or drop me if you&#8217;d like more explanation.</p>
]]></content:encoded>
			<wfw:commentRss>http://ianloic.com/2007/03/05/making_dynamic_static_pages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flickr for Dojo</title>
		<link>http://ianloic.com/2007/02/10/flickr_for_dojo/</link>
		<comments>http://ianloic.com/2007/02/10/flickr_for_dojo/#comments</comments>
		<pubDate>Wed, 30 Nov -0001 00:00:00 +0000</pubDate>
		<dc:creator>Ian McKellar</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[json]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[I&#8217;ve been working on a little Dojo based application which talks to Flickr, so I put together a little library which uses Dojo to talk to Flickr using it&#8217;s rest JSON interface.
Use
It&#8217;s pretty simple to use, just include the JavaScript file:

&#60;script src="flickr.js"&#62;&#60;/script&#62;
Tell the library what your keys are:

flickr.keys(API_KEY, SECRET_KEY);
And you&#8217;re set to go.
The main entry-point [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a little <a href="http://www.dojotoolkit.org/">Dojo</a> based application which talks to <a href="http://www.flickr.com/">Flickr</a>, so I put together a little library which uses Dojo to talk to Flickr using it&#8217;s rest <a href="http://www.json.org/">JSON</a> interface.</p>
<p><strong>Use</strong><br />
It&#8217;s pretty simple to use, just include the JavaScript file:</p>
<pre class="prettyprint">
&lt;script src="flickr.js"&gt;&lt;/script&gt;</pre>
<p>Tell the library what your <a href="http://www.flickr.com/services/api/keys/">keys</a> are:</p>
<pre class="prettyprint">
flickr.keys(API_KEY, SECRET_KEY);</pre>
<p>And you&#8217;re set to go.</p>
<p>The main entry-point is <code language="js">flickr.call</code>. As the first argument, you pass in a hash of arguments, as described in the <a href="http://www.flickr.com/services/api/">Flickr API documentation</a>. The method you&#8217;re calling is included in this hash. The second argument is optional and is a callback to be called with the response from the Flickr servers. The response will come back in JSON format so it is easy to handle it in JavaScript. The Flickr JSON response format is discussed in detail <a href="http://www.flickr.com/services/api/response.json.html">on the Flickr site</a>.</p>
<p>So what would all this look like? Something like this will load interesting photos from Flickr and add them to the current document:</p>
<pre class="prettyprint">
flickr.keys(API_KEY, SECRET_KEY);
var pagenum = 1;
function interesting () {
    flickr.call({method:'flickr.interestingness.getList',
            page: pagenum, per_page: 10}, interesting_cb);
    pagenum++;
}
function interesting_cb (response) {
    if (response.stat != 'ok') {
        var error = document.createElement('div');
        error.appendChild(document.createTextNode(response.message));
        document.body.appendChild(error);
        return;
    }
    for (var i in response.photos.photo) {
        var photo = response.photos.photo[i];
        var img = document.createElement('img');
        img.classname = 'interesting';
        img.setAttribute('src', 'http://farm'+photo.farm+
                '.static.flickr.com/'+photo.server+'/'+photo.id+
                '_'+photo.secret+'_s.jpg');
        img.setAttribute('width', '75');
        img.setAttribute('height', '75');

        var a = document.createElement('a');
        a.setAttribute('href', 'http://www.flickr.com/photos/'+
                photo.owner+'/'+photo.id);
        a.appendChild(img);

        document.body.appendChild(a)
    }
}</pre>
<p><strong>Implementation</strong><br />
I&#8217;m not actually using all that much from Dojo. The main thing I&#8217;m taking is the crypto library, specifically <a href="http://dojotoolkit.org/api/#dojo.crypto.MD5">dojo.crypto.MD5</a>. The way I&#8217;m making the actual JSON calls is by appending <code language="html"><script src="http://api.flickr.com/services/..."></script></code> elements to the page. Perhaps at some point I&#8217;ll move to using Dojo&#8217;s ScriptSrcIO but right now I&#8217;m not.</p>
<p>The current version of the code is attached: <a href="http://scratch.ianloic.com/wordpress/wp-content/uploads/2008/01/flickrjs.txt" title="flickr.js">flickr.js</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ianloic.com/2007/02/10/flickr_for_dojo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flickr Authentication Security</title>
		<link>http://ianloic.com/2006/12/23/flickr_authentication_security/</link>
		<comments>http://ianloic.com/2006/12/23/flickr_authentication_security/#comments</comments>
		<pubDate>Wed, 30 Nov -0001 00:00:00 +0000</pubDate>
		<dc:creator>Ian McKellar</dc:creator>
				<category><![CDATA[Default]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[xss]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[[flickr-photo:id=1187679,size=m] Recently <a href="http://www.flickr.com/">Flickr</a> closed a little security hole I found in their API authentication. I was able to convince their servers to hand out a token to me based on a user's cookies and the <a href="http://www.flickr.com/services/api/keys/">API key and secret key</a> of an application the user had used. Then with the <a href="http://www.flickr.com/services/api/response.json.html">JSON</a> form of the Flickr API I had full access to the user's account. 

The there two flaws in Flickr's security that exposed this problem. The first was that the security is based on the assumption that applications can keep a key secret. This is easy for web applications that make server to server API calls, but for anything that a user downloads and especially open source software it's impossible to keep the key secret. My experiment used the secret key from <a href="http://www.flock.com/">Flock</a> which is open source - the secret key can be found in <a href="http://svn-mirror.flock.com/">subversion</a>, and the secret key from Flickr's own MacOS X uploader application which can be easilly extracted from the download from their site. Secondly the Flickr server was giving out new authentication tokens without requiring user approval.

The exploit itself is a little state-machine making a series of Flickr API calls and using one IFRAME. It goes like this:
<ul>
<li>Request a frob (via JSON)</li>
<li>Request authentication (via an IFRAME)</li>
<li>Request the auth token (via JSON)</li>
<li>Do evil (via JSON)</li>
</ul>
In my case the evil consisted of posting a comment on the user's most recent photo.

The security hole is now closed, but if you're interested in seeing how to access the Flickr API entirely from JavaScript in a web page take a look at the attached exploit. You'll also need the MD5 library.]]></description>
			<content:encoded><![CDATA[<p>Recently <a href="http://www.flickr.com/">Flickr</a> closed a little security hole I found in their API authentication. I was able to convince their servers to hand out a token to me based on a user&#8217;s cookies and the <a href="http://www.flickr.com/services/api/keys/">API key and secret key</a> of an application the user had used. Then with the <a href="http://www.flickr.com/services/api/response.json.html">JSON</a> form of the Flickr API I had full access to the user&#8217;s account.</p>
<p>The there two flaws in Flickr&#8217;s security that exposed this problem. The first was that the security is based on the assumption that applications can keep a key secret. This is easy for web applications that make server to server API calls, but for anything that a user downloads and especially open source software it&#8217;s impossible to keep the key secret. My experiment used the secret key from <a href="http://www.flock.com/">Flock</a> which is open source &#8211; the secret key can be found in <a href="http://svn-mirror.flock.com/">subversion</a>, and the secret key from Flickr&#8217;s own MacOS X uploader application which can be easilly extracted from the download from their site. Secondly the Flickr server was giving out new authentication tokens without requiring user approval.</p>
<p>The exploit itself is a little state-machine making a series of Flickr API calls and using one IFRAME. It goes like this:</p>
<ul>
<li>Request a frob (via JSON)</li>
<li>Request authentication (via an IFRAME)</li>
<li>Request the auth token (via JSON)</li>
<li>Do evil (via JSON)</li>
</ul>
<p>In my case the evil consisted of posting a comment on the user&#8217;s most recent photo.</p>
<p>The security hole is now closed, but if you&#8217;re interested in seeing how to access the Flickr API entirely from JavaScript in a web page take a look at the attached exploit: <a href="http://scratch.ianloic.com/wordpress/wp-content/uploads/2008/01/sploitr.html" title="sploitr.html">sploitr.html</a> and the md5 library: <a href="http://scratch.ianloic.com/wordpress/wp-content/uploads/2008/01/md5js.txt" title="md5.js">md5.js</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ianloic.com/2006/12/23/flickr_authentication_security/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
