<?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>Terence Eden has a Blog &#187; oauth</title> <atom:link href="http://shkspr.mobi/blog/index.php/tag/oauth/feed/" rel="self" type="application/rss+xml" /><link>http://shkspr.mobi/blog</link> <description>Mobiles, Shakespeare, Politics, Usability.</description> <lastBuildDate>Fri, 30 Jul 2010 08:28:19 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.0.1</generator> <item><title>HOWTO: Twitpic and OAuth</title><link>http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/</link> <comments>http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/#comments</comments> <pubDate>Mon, 31 May 2010 17:07:29 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[howto]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[php]]></category> <category><![CDATA[twitpic]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=2084</guid> <description><![CDATA[I am no longer confused!  Here is a quick tutorial in how to post images to Twitpic and Twitter when using OAuth.  I&#8217;m indebted to Steve Corona of Twitpic, for his help with this.
You can see the full code on Dabr&#8217;s Google Code page.
First of all, you&#8217;ll need to have enabled OAuth for ...]]></description> <content:encoded><![CDATA[<p>I am no longer <a
href="http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck">confused</a>!  Here is a quick tutorial in how to post images to Twitpic and Twitter when using OAuth.  I&#8217;m indebted to <a
href="http://twitter.com/stevencorona">Steve Corona of Twitpic</a>, for his help with this.</p><p>You can see the full code on <a
href="http://code.google.com/p/dabr/source/detail?r=318">Dabr&#8217;s Google Code page</a>.</p><p>First of all, you&#8217;ll need to have enabled OAuth for your Twitter client.  I use Abraham&#8217;s excellent <a
href="http://github.com/abraham/twitteroauth/tree/master/twitteroauth/">OAuth libraries for PHP</a>.</p><p>This tutorial assumes you already have OAuth working.  I&#8217;ll attempt to explain what I&#8217;m doing as I go along &#8211; but the code should be pretty readable.</p><p>Start by reading the <a
href="http://dev.twitpic.com/docs/2/upload/">Twitpic API documentation</a>.  You will also need to <a
href="http://dev.twitpic.com/apps/new">register for an API key</a> &#8211; this only takes a few seconds.</p><p>We start by setting CURL&#8217;s headers to those required by Twitpic</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1"><span
class="co1">//Has the user submitted an image and message?</span></div></li><li
class="li1"><div
class="de1"><span
class="kw1">if</span> <span
class="br0">&#40;</span><span
class="re1">$_POST</span><span
class="br0">&#91;</span><span
class="st0">&#39;message&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#41;</span></div></li><li
class="li1"><div
class="de1"><span
class="br0">&#123;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$twitpicURL</span> <span
class="sy0">=</span> <span
class="st0">&#39;http://api.twitpic.com/2/upload.json&#39;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//Set the initial headers</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span> <span
class="sy0">=</span> <span
class="kw3">array</span><span
class="br0">&#40;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span
class="st0">&#39;X-Auth-Service-Provider: https://api.twitter.com/1/account/verify_credentials.json&#39;</span><span
class="sy0">,</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span
class="st0">&#39;X-Verify-Credentials-Authorization: OAuth realm=&quot;http://api.twitter.com/&quot;&#39;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; <span
class="br0">&#41;</span><span
class="sy0">;</span></div></li></ol></div><p>Next, we create the OAuth credentials that we need.  Essentially, we&#8217;re signing a URL request. We then pass that on to Twitpic and they verify it with Twitter.  We <em>never</em> pass our OAUTH_CONSUMER_SECRET &#8211; so Twitpic can&#8217;t impersonate us.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//Using Abraham&#39;s OAuth library</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="kw1">require_once</span><span
class="br0">&#40;</span><span
class="st0">&#39;OAuth.php&#39;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">// instantiating OAuth customer </span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$consumer</span> <span
class="sy0">=</span> <span
class="kw2">new</span> OAuthConsumer<span
class="br0">&#40;</span>OAUTH_CONSUMER_KEY<span
class="sy0">,</span> OAUTH_CONSUMER_SECRET<span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">// instantiating signer</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$sha1_method</span> <span
class="sy0">=</span> <span
class="kw2">new</span> OAuthSignatureMethod_HMAC_SHA1<span
class="br0">&#40;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">// user&#39;s token</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="kw3">list</span><span
class="br0">&#40;</span><span
class="re1">$oauth_token</span><span
class="sy0">,</span> <span
class="re1">$oauth_token_secret</span><span
class="br0">&#41;</span> <span
class="sy0">=</span> <span
class="kw3">explode</span><span
class="br0">&#40;</span><span
class="st0">&#39;|&#39;</span><span
class="sy0">,</span> <span
class="re1">$GLOBALS</span><span
class="br0">&#91;</span><span
class="st0">&#39;user&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#91;</span><span
class="st0">&#39;password&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$token</span> <span
class="sy0">=</span> <span
class="kw2">new</span> OAuthConsumer<span
class="br0">&#40;</span><span
class="re1">$oauth_token</span><span
class="sy0">,</span> <span
class="re1">$oauth_token_secret</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">// Generate all the OAuth parameters needed</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$signingURL</span> <span
class="sy0">=</span> <span
class="st0">&#39;https://api.twitter.com/1/account/verify_credentials.json&#39;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$request</span> <span
class="sy0">=</span> OAuthRequest<span
class="sy0">::</span><span
class="me2">from_consumer_and_token</span><span
class="br0">&#40;</span><span
class="re1">$consumer</span><span
class="sy0">,</span> <span
class="re1">$token</span><span
class="sy0">,</span> <span
class="st0">&#39;GET&#39;</span><span
class="sy0">,</span> <span
class="re1">$signingURL</span><span
class="sy0">,</span> <span
class="kw3">array</span><span
class="br0">&#40;</span><span
class="br0">&#41;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">sign_request</span><span
class="br0">&#40;</span><span
class="re1">$sha1_method</span><span
class="sy0">,</span> <span
class="re1">$consumer</span><span
class="sy0">,</span> <span
class="re1">$token</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li></ol></div><p>We add these generated credentials into the header.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_consumer_key=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_consumer_key&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_signature_method=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_signature_method&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_token=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_token&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_timestamp=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_timestamp&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_nonce=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_nonce&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_version=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_version&#39;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$header</span><span
class="br0">&#91;</span><span
class="nu0">1</span><span
class="br0">&#93;</span> <span
class="sy0">.=</span> <span
class="st0">&quot;, oauth_signature=<span
class="es0">\&quot;</span>&quot;</span> <span
class="sy0">.</span> <span
class="kw3">urlencode</span><span
class="br0">&#40;</span><span
class="re1">$request</span><span
class="sy0">-&gt;</span><span
class="me1">get_parameter</span><span
class="br0">&#40;</span><span
class="st0">&#39;oauth_signature&#39;</span><span
class="br0">&#41;</span><span
class="br0">&#41;</span> <span
class="sy0">.</span><span
class="st0">&quot;<span
class="es0">\&quot;</span>&quot;</span><span
class="sy0">;</span></div></li></ol></div><p>Add everything into CURL</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//open connection</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$ch</span> <span
class="sy0">=</span> curl_init<span
class="br0">&#40;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//Set paramaters</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span> CURLOPT_HTTPHEADER<span
class="sy0">,</span> <span
class="re1">$header</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span> CURLOPT_RETURNTRANSFER<span
class="sy0">,</span> <span
class="kw2">TRUE</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span> CURLOPT_SSL_VERIFYPEER<span
class="sy0">,</span> <span
class="nu0">0</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//set the url, number of POST vars, POST data</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span>CURLOPT_URL<span
class="sy0">,</span><span
class="re1">$twitpicURL</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li></ol></div><p>The data we send to Twitpic (message text, image and key) have to go via POST.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//TwitPic requires the data to be sent as POST</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$media_data</span> <span
class="sy0">=</span> <span
class="kw3">array</span><span
class="br0">&#40;</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; &nbsp;<span
class="st0">&#39;media&#39;</span> <span
class="sy0">=&gt;</span> <span
class="st0">&#39;@&#39;</span><span
class="sy0">.</span><span
class="re1">$_FILES</span><span
class="br0">&#91;</span><span
class="st0">&#39;media&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#91;</span><span
class="st0">&#39;tmp_name&#39;</span><span
class="br0">&#93;</span><span
class="sy0">,</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span
class="st0">&#39;message&#39;</span> <span
class="sy0">=&gt;</span> <span
class="st0">&#39; &#39;</span> <span
class="sy0">.</span> <span
class="kw3">stripslashes</span><span
class="br0">&#40;</span><span
class="re1">$_POST</span><span
class="br0">&#91;</span><span
class="st0">&#39;message&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#41;</span><span
class="sy0">,</span> <span
class="co1">//A space is needed because twitpic b0rks if first char is an @</span></div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span
class="st0">&#39;key&#39;</span><span
class="sy0">=&gt;</span>TWITPIC_API_KEY</div></li><li
class="li1"><div
class="de1">&nbsp; &nbsp; &nbsp; <span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span> CURLOPT_POST<span
class="sy0">,</span> <span
class="kw2">true</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_setopt<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="sy0">,</span>CURLOPT_POSTFIELDS<span
class="sy0">,</span><span
class="re1">$media_data</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li></ol></div><p>All done, we now send the data to Twitpic.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//execute post</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$result</span> <span
class="sy0">=</span> curl_exec<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="re1">$response_info</span><span
class="sy0">=</span>curl_getinfo<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="co1">//close connection</span></div></li><li
class="li1"><div
class="de1">&nbsp;curl_close<span
class="br0">&#40;</span><span
class="re1">$ch</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li></ol></div><p>If this has worked, Twitpic will pass back the URL of the image we posted.  We then need to post the entire message to Twitter ourselves (Twitpic can&#8217;t do it for us).</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="kw1">if</span> <span
class="br0">&#40;</span><span
class="re1">$response_info</span><span
class="br0">&#91;</span><span
class="st0">&#39;http_code&#39;</span><span
class="br0">&#93;</span> <span
class="sy0">==</span> <span
class="nu0">200</span><span
class="br0">&#41;</span> <span
class="co1">//Success</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="br0">&#123;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="co1">//Decode the response</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$json</span> <span
class="sy0">=</span> json_decode<span
class="br0">&#40;</span><span
class="re1">$result</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$id</span> <span
class="sy0">=</span> <span
class="re1">$json</span><span
class="sy0">-&gt;</span><span
class="me1">id</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$twitpicURL</span> <span
class="sy0">=</span> <span
class="re1">$json</span><span
class="sy0">-&gt;</span><span
class="me1">url</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$text</span> <span
class="sy0">=</span> <span
class="re1">$json</span><span
class="sy0">-&gt;</span><span
class="me1">text</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$message</span> <span
class="sy0">=</span> <span
class="kw3">trim</span><span
class="br0">&#40;</span><span
class="re1">$text</span><span
class="br0">&#41;</span> <span
class="sy0">.</span> <span
class="st0">&quot; &quot;</span> <span
class="sy0">.</span> <span
class="re1">$twitpicURL</span><span
class="sy0">;</span></div></li></ol></div><p>This next part is specific to Dabr &#8211; your client may post things differently.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp; <span
class="co1">//Send the user&#39;s message to twitter</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$request</span> <span
class="sy0">=</span> API_URL<span
class="sy0">.</span><span
class="st0">&#39;statuses/update.json&#39;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$post_data</span> <span
class="sy0">=</span> <span
class="kw3">array</span><span
class="br0">&#40;</span><span
class="st0">&#39;source&#39;</span> <span
class="sy0">=&gt;</span> <span
class="st0">&#39;dabr&#39;</span><span
class="sy0">,</span> <span
class="st0">&#39;status&#39;</span> <span
class="sy0">=&gt;</span> <span
class="re1">$message</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$status</span> <span
class="sy0">=</span> twitter_process<span
class="br0">&#40;</span><span
class="re1">$request</span><span
class="sy0">,</span> <span
class="re1">$post_data</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;</div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="co1">//Back to the timeline</span></div></li><li
class="li1"><div
class="de1">&nbsp; twitter_refresh<span
class="br0">&#40;</span><span
class="st0">&quot;twitpic/confirm/$id&quot;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="br0">&#125;</span></div></li></ol></div><p>If it didn&#8217;t work, Twitpic will tell us why.</p><div
class="geshi no php"><ol><li
class="li1"><div
class="de1">&nbsp;<span
class="kw1">else</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="br0">&#123;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">=</span> <span
class="st0">&quot;&lt;p&gt;Twitpic upload failed. No idea why!&lt;/p&gt;&quot;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$json</span> <span
class="sy0">=</span> json_decode<span
class="br0">&#40;</span><span
class="re1">$result</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br / /&gt;&lt;b&gt;message&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="kw3">urlencode</span><span
class="br0">&#40;</span><span
class="re1">$_POST</span><span
class="br0">&#91;</span><span
class="st0">&#39;message&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br / /&gt;&lt;b&gt;json&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="kw3">print_r</span><span
class="br0">&#40;</span><span
class="re1">$json</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br / /&gt;&lt;b&gt;Response&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="kw3">print_r</span><span
class="br0">&#40;</span><span
class="re1">$response_info</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br / /&gt;&lt;b&gt;header&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="kw3">print_r</span><span
class="br0">&#40;</span><span
class="re1">$header</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br / /&gt;&lt;b&gt;media_data&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="kw3">print_r</span><span
class="br0">&#40;</span><span
class="re1">$media_data</span><span
class="br0">&#41;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br /&gt;&lt;b&gt;URL was&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="re1">$twitpicURL</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp; <span
class="re1">$content</span> <span
class="sy0">.=</span> <span
class="st0">&quot;&lt;br /&gt;&lt;b&gt;File uploaded was&lt;/b&gt; &quot;</span> <span
class="sy0">.</span> <span
class="re1">$_FILES</span><span
class="br0">&#91;</span><span
class="st0">&#39;media&#39;</span><span
class="br0">&#93;</span><span
class="br0">&#91;</span><span
class="st0">&#39;tmp_name&#39;</span><span
class="br0">&#93;</span><span
class="sy0">;</span></div></li><li
class="li1"><div
class="de1">&nbsp;<span
class="br0">&#125;</span></div></li><li
class="li1"><div
class="de1"><span
class="br0">&#125;</span></div></li></ol></div><div
class="social_bookmark"><em>Share This</em><br
/><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/&amp;title=HOWTO%3A+Twitpic+and+OAuth" title="Add 'HOWTO: Twitpic and OAuth' to Del.icio.us"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="Add 'HOWTO: Twitpic and OAuth' to Del.icio.us" alt="Add 'HOWTO: Twitpic and OAuth' to Del.icio.us" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/&amp;title=HOWTO%3A+Twitpic+and+OAuth" title="Add 'HOWTO: Twitpic and OAuth' to digg"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="Add 'HOWTO: Twitpic and OAuth' to digg" alt="Add 'HOWTO: Twitpic and OAuth' to digg" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/&amp;title=HOWTO%3A+Twitpic+and+OAuth" title="Add 'HOWTO: Twitpic and OAuth' to reddit"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/reddit.png" title="Add 'HOWTO: Twitpic and OAuth' to reddit" alt="Add 'HOWTO: Twitpic and OAuth' to reddit" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/" title="Add 'HOWTO: Twitpic and OAuth' to Technorati"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="Add 'HOWTO: Twitpic and OAuth' to Technorati" alt="Add 'HOWTO: Twitpic and OAuth' to Technorati" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/&amp;title=HOWTO%3A+Twitpic+and+OAuth" title="Add 'HOWTO: Twitpic and OAuth' to Stumble Upon"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="Add 'HOWTO: Twitpic and OAuth' to Stumble Upon" alt="Add 'HOWTO: Twitpic and OAuth' to Stumble Upon" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/&amp;title=HOWTO%3A+Twitpic+and+OAuth" title="Add 'HOWTO: Twitpic and OAuth' to Google Bookmarks"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/google.png" title="Add 'HOWTO: Twitpic and OAuth' to Google Bookmarks" alt="Add 'HOWTO: Twitpic and OAuth' to Google Bookmarks" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.bloglines.com/sub/http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/" title="Add 'HOWTO: Twitpic and OAuth' to Bloglines"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/bloglines.png" title="Add 'HOWTO: Twitpic and OAuth' to Bloglines" alt="Add 'HOWTO: Twitpic and OAuth' to Bloglines" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?title=HOWTO%3A+Twitpic+and+OAuth&amp;url=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/" title="Add 'HOWTO: Twitpic and OAuth' to SlashDot"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/slashdot.png" title="Add 'HOWTO: Twitpic and OAuth' to SlashDot" alt="Add 'HOWTO: Twitpic and OAuth' to SlashDot" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/&amp;t=HOWTO%3A+Twitpic+and+OAuth" title="Add 'HOWTO: Twitpic and OAuth' to FaceBook"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="Add 'HOWTO: Twitpic and OAuth' to FaceBook" alt="Add 'HOWTO: Twitpic and OAuth' to FaceBook" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wikio.it/vote?url=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/" title="Add 'HOWTO: Twitpic and OAuth' to Wikio"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/wikio.png" title="Add 'HOWTO: Twitpic and OAuth' to Wikio" alt="Add 'HOWTO: Twitpic and OAuth' to Wikio" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home?status=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/" title="Add 'HOWTO: Twitpic and OAuth' to Twitter"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/twitter.png" title="Add 'HOWTO: Twitpic and OAuth' to Twitter" alt="Add 'HOWTO: Twitpic and OAuth' to Twitter" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://friendfeed.com/share/bookmarklet/frame#title=HOWTO%3A+Twitpic+and+OAuth&amp;url=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/" title="Add 'HOWTO: Twitpic and OAuth' to FriendFeed"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/friendfeed.png" title="Add 'HOWTO: Twitpic and OAuth' to FriendFeed" alt="Add 'HOWTO: Twitpic and OAuth' to FriendFeed" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/reader/link?url=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/&amp;title=HOWTO%3A+Twitpic+and+OAuth&amp;srcURL=http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/" title="Add 'HOWTO: Twitpic and OAuth' to Google Buzz"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/googlebuzz.png" title="Add 'HOWTO: Twitpic and OAuth' to Google Buzz" alt="Add 'HOWTO: Twitpic and OAuth' to Google Buzz" /></a></div> ]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/05/howto-twitpic-and-oauth/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Twitpic OAuth &#8211; I&#8217;m Stuck</title><link>http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/</link> <comments>http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/#comments</comments> <pubDate>Sun, 23 May 2010 20:15:18 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[/etc/]]></category> <category><![CDATA[api]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[php]]></category> <category><![CDATA[programming]]></category> <category><![CDATA[twitpic]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=2073</guid> <description><![CDATA[Twitpic has implemented an OAuth API. No more having to hand out passwords to all and sundy.  Only I&#8217;m too much of a dunderhead to get it working.  Perhaps it&#8217;s a combination of heatstroke or this rotten head-cold, but I just can&#8217;t see what I&#8217;m doing wrong.  Any help much appreciated.
The easy ...]]></description> <content:encoded><![CDATA[<p>Twitpic has implemented an <a
href="http://dev.twitpic.com/docs/2/upload/">OAuth API</a>. No more having to hand out passwords to all and sundy.  Only I&#8217;m too much of a dunderhead to get it working.  Perhaps it&#8217;s a combination of heatstroke or this rotten head-cold, but I just can&#8217;t see what I&#8217;m doing wrong.  Any help much appreciated.</p><h2>The easy bit.</h2><p>It&#8217;s easy to post the data to Twitpic</p><pre>$media_data = array(
	'media' =&gt; '@'.$_FILES['media']['tmp_name'],
	'message' =&gt; html_entity_decode($_POST['message']),
	'key'=&gt;'123465789132465'
);
curl_setopt($ch,CURLOPT_POSTFIELDS,$media_data);
</pre><h2>OAuth Credentials</h2><p>Using <a
href="http://twitter.com/abraham">Abrahams</a> <a
href="http://github.com/abraham/twitteroauth">OAuth library for PHP</a>, it&#8217;s easy to get the required OAuth data.</p><pre>require_once('OAuth.php');
// instantiating OAuth customer
$consumer = new OAuthConsumer(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET);
// instantiating signer
$sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
// user's token
list($oauth_token, $oauth_token_secret) = explode('|', $GLOBALS['user']['password']);
$token = new OAuthConsumer($oauth_token, $oauth_token_secret);

// signing URL
$fakeurl = 'https://twitter.com/account/verify_credentials.xml';
$request = OAuthRequest::from_consumer_and_token($consumer, $token, 'GET', $fakeurl, array());
$request-&gt;sign_request($sha1_method, $consumer, $token);
$OAuthurl = $request-&gt;to_url();
</pre><h2>The Tricky Bit</h2><p>I&#8217;m following the header example in the <a
href="http://dev.twitpic.com/docs/2/upload/">API documentation</a>. Passing these variable to Twitpic is where I seem to go wrong.<br
/> <code><br
/> $header = array(<br
/> 'X-Auth-Service-Provider: https://api.twitter.com/1/account/verify_credentials.json',<br
/> 'X-Verify-Credentials-Authorization: OAuth realm="http://api.twitter.com/"'<br
/> );<br
/> </code><br
/> I then modify the second header so it reads</p><pre>
"X-Verify-Credentials-Authorization: OAuth realm="http://api.twitter.com/",
oauth_consumer_key="aaaaaaa",
oauth_nonce="bbbbbbbbbbb",
oauth_signature="ccccccccccccc%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="123456798",
oauth_token="15948715-dddddddddd",
oauth_version="1.0""
</pre><h2>The Error</h2><p>401 &#8220;Could not authenticate you (header rejected by twitter).&#8221;</p><p>GAH!</p><div
class="social_bookmark"><em>Share This</em><br
/><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/&amp;title=Twitpic+OAuth+%26%238211%3B+I%26%238217%3Bm+Stuck" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Del.icio.us"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Del.icio.us" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Del.icio.us" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/&amp;title=Twitpic+OAuth+%26%238211%3B+I%26%238217%3Bm+Stuck" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to digg"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to digg" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to digg" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/&amp;title=Twitpic+OAuth+%26%238211%3B+I%26%238217%3Bm+Stuck" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to reddit"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/reddit.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to reddit" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to reddit" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Technorati"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Technorati" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Technorati" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/&amp;title=Twitpic+OAuth+%26%238211%3B+I%26%238217%3Bm+Stuck" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Stumble Upon"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Stumble Upon" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Stumble Upon" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/&amp;title=Twitpic+OAuth+%26%238211%3B+I%26%238217%3Bm+Stuck" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Google Bookmarks"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/google.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Google Bookmarks" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Google Bookmarks" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.bloglines.com/sub/http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Bloglines"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/bloglines.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Bloglines" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Bloglines" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?title=Twitpic+OAuth+%26%238211%3B+I%26%238217%3Bm+Stuck&amp;url=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to SlashDot"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/slashdot.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to SlashDot" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to SlashDot" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/&amp;t=Twitpic+OAuth+%26%238211%3B+I%26%238217%3Bm+Stuck" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to FaceBook"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to FaceBook" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to FaceBook" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wikio.it/vote?url=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Wikio"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/wikio.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Wikio" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Wikio" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home?status=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Twitter"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/twitter.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Twitter" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Twitter" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://friendfeed.com/share/bookmarklet/frame#title=Twitpic+OAuth+%26%238211%3B+I%26%238217%3Bm+Stuck&amp;url=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to FriendFeed"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/friendfeed.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to FriendFeed" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to FriendFeed" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/reader/link?url=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/&amp;title=Twitpic+OAuth+%26%238211%3B+I%26%238217%3Bm+Stuck&amp;srcURL=http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Google Buzz"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/googlebuzz.png" title="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Google Buzz" alt="Add 'Twitpic OAuth &#8211; I&#8217;m Stuck' to Google Buzz" /></a></div> ]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/05/twitpic-oauth-im-stuck/feed/</wfw:commentRss> <slash:comments>14</slash:comments> </item> <item><title>The Perfect Twitter Spam Attack?</title><link>http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/</link> <comments>http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/#comments</comments> <pubDate>Sun, 07 Mar 2010 09:59:03 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[usability]]></category> <category><![CDATA[evil genius]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[passwords]]></category> <category><![CDATA[security]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1796</guid> <description><![CDATA[This morning, when I logged on to Twitter, I saw a user who I didn&#8217;t recognise tweeting away in my timeline.
I wracked my brains thinking about how they could have gotten in there before I realised it was a long-dormant friend who had changed their name and avatar.
But, in thinking about how a spammer could ...]]></description> <content:encoded><![CDATA[<p>This morning, when I logged on to Twitter, I saw a user who I didn&#8217;t recognise tweeting away in my timeline.</p><p>I wracked my brains thinking about how they could have gotten in there before I realised it was a long-dormant friend who had changed their name and avatar.</p><p>But, in thinking about how a spammer could infiltrate one&#8217;s timeline, I think I came up with a fairly bullet-proof method to spam Twitter users.</p><p>I present this as an exercise in devious thinking &#8211; and also to show how our assumptions about security can play against us. Remember, hacking and impersonation are likely to be illegal in your jurisdiction.  This information is designed to help you understand how security weaknesses can occur.</p><h2>Being Evil</h2><p>Imagine you are a nasty, evil Twitter spammer.  Your own mother wouldn&#8217;t spit on you if you were on fire &#8211; that&#8217;s how mean you are.  Here&#8217;s what you do.</p><ol><li>Obtain a user&#8217;s password.  Admittedly, this is the hardest part of the process. You might use a dictionary attack, use the same password they use to log in to another site, or somehow steal it.</li><li>Log on to Twitter.</li><li>Go to &#8220;Connections&#8221; and see which services they have connected to using OAuth.  For the purposes of this experiment, let&#8217;s assume they use Example.com.</li><li>Go to Example.com and OAuth yourself with Twitter using your mark&#8217;s credentials.</li><li>Here&#8217;s where the ordinary spammer falls down.  The ordinary spammer will start sending out messages from the mark&#8217;s account.  That&#8217;s <strong>not</strong> the aim of this weakness.</li><li>From the mark&#8217;s account, through Example.com, make your victim follow one of your spam accounts.  An account which exists solely to show adverts to your victim.</li></ol><p>Your victim now sees your adverts for pills, poker and porn in their timeline.  With any luck, they&#8217;ll just assume that one of their true friends is promoting your illicit wares.</p><h2>Counter Attack</h2><p>Most victims will assume that they accidentally followed your spam account &#8211; or that one of their friends has been hacked.</p><p>Worst case scenario, they unfollow your spam account.</p><p><strong><em>So you just make them follow you again!</em></strong> Remember, you are <strong>still</strong> OAuth&#8217;d to Example.com. You can make them follow as many of your spam accounts as you think you can get away with.</p><p>At this point, the intelligent victim will think that their account may be compromised and change their password.</p><p><strong><em>It doesn&#8217;t matter</em>!</strong> Because you have used OAuth, password changes <em>don&#8217;t affect you</em>.  You can continue make them follow as many of your spam accounts as you think you can get away with.</p><p>At this point, the <em>really</em> intelligent victim will go through their OAuth connections to look for something suspicious.  They won&#8217;t find it.  Remember steps 3 and 4?  <strong>You are OAuth&#8217;d to a service that your victim trusts</strong>.</p><p>Because of the way Twitter displays OAuth information, there&#8217;s no way for a victim to know when a service was last authorised.</p><div
id="attachment_1798" class="wp-caption aligncenter" style="width: 460px"><img
class="size-full wp-image-1798" title="Twitter OAuth Connections" src="http://shkspr.mobi/blog/wp-content/uploads/2010/03/Twitter-OAuth-Connections.png" alt="Twitter OAuth Connections" width="450" height="501" /><p
class="wp-caption-text">Twitter OAuth Connections</p></div><p>There is no information other than the <em>first time</em> the OAuth was set up.  No last accessed date, no IP addresses, nothing useful.</p><p>When following an account, the victim gets no notification of what has happened, when it has happened or how it has happened.  There is no way of them knowing which of their OAuth&#8217;d connections have been compromised, nor when it happened.</p><p>Their only safe option is to revoke <em>every single </em>OAuth connection.  Then reauthorise.  A time consuming and annoying prospect.</p><h2>Conclusion</h2><p>I hope I&#8217;ve demonstrated two things.</p><p>Firstly, there&#8217;s more to spam then just sending out messages.  Forcing someone to read a message is just as annoying.</p><p>Secondly, our understanding of security and usability haven&#8217;t quite caught up with the new tools which are available to us.  OAuth is still better than giving your password to an untrusted site &#8211; but without essential usability changes, a compromised account is a lot more dangerous than the user would suspect.</p><p>This &#8220;attack&#8221; still relies on a victim having their original password compromised.  That&#8217;s not a trivial matter.  But security is like sexual health &#8211; it only takes one little accident&#8230;</p><div
class="social_bookmark"><em>Share This</em><br
/><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/&amp;title=The+Perfect+Twitter+Spam+Attack%3F" title="Add 'The Perfect Twitter Spam Attack?' to Del.icio.us"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="Add 'The Perfect Twitter Spam Attack?' to Del.icio.us" alt="Add 'The Perfect Twitter Spam Attack?' to Del.icio.us" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/&amp;title=The+Perfect+Twitter+Spam+Attack%3F" title="Add 'The Perfect Twitter Spam Attack?' to digg"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="Add 'The Perfect Twitter Spam Attack?' to digg" alt="Add 'The Perfect Twitter Spam Attack?' to digg" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/&amp;title=The+Perfect+Twitter+Spam+Attack%3F" title="Add 'The Perfect Twitter Spam Attack?' to reddit"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/reddit.png" title="Add 'The Perfect Twitter Spam Attack?' to reddit" alt="Add 'The Perfect Twitter Spam Attack?' to reddit" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/" title="Add 'The Perfect Twitter Spam Attack?' to Technorati"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="Add 'The Perfect Twitter Spam Attack?' to Technorati" alt="Add 'The Perfect Twitter Spam Attack?' to Technorati" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/&amp;title=The+Perfect+Twitter+Spam+Attack%3F" title="Add 'The Perfect Twitter Spam Attack?' to Stumble Upon"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="Add 'The Perfect Twitter Spam Attack?' to Stumble Upon" alt="Add 'The Perfect Twitter Spam Attack?' to Stumble Upon" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/&amp;title=The+Perfect+Twitter+Spam+Attack%3F" title="Add 'The Perfect Twitter Spam Attack?' to Google Bookmarks"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/google.png" title="Add 'The Perfect Twitter Spam Attack?' to Google Bookmarks" alt="Add 'The Perfect Twitter Spam Attack?' to Google Bookmarks" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.bloglines.com/sub/http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/" title="Add 'The Perfect Twitter Spam Attack?' to Bloglines"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/bloglines.png" title="Add 'The Perfect Twitter Spam Attack?' to Bloglines" alt="Add 'The Perfect Twitter Spam Attack?' to Bloglines" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?title=The+Perfect+Twitter+Spam+Attack%3F&amp;url=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/" title="Add 'The Perfect Twitter Spam Attack?' to SlashDot"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/slashdot.png" title="Add 'The Perfect Twitter Spam Attack?' to SlashDot" alt="Add 'The Perfect Twitter Spam Attack?' to SlashDot" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/&amp;t=The+Perfect+Twitter+Spam+Attack%3F" title="Add 'The Perfect Twitter Spam Attack?' to FaceBook"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="Add 'The Perfect Twitter Spam Attack?' to FaceBook" alt="Add 'The Perfect Twitter Spam Attack?' to FaceBook" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wikio.it/vote?url=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/" title="Add 'The Perfect Twitter Spam Attack?' to Wikio"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/wikio.png" title="Add 'The Perfect Twitter Spam Attack?' to Wikio" alt="Add 'The Perfect Twitter Spam Attack?' to Wikio" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home?status=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/" title="Add 'The Perfect Twitter Spam Attack?' to Twitter"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/twitter.png" title="Add 'The Perfect Twitter Spam Attack?' to Twitter" alt="Add 'The Perfect Twitter Spam Attack?' to Twitter" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://friendfeed.com/share/bookmarklet/frame#title=The+Perfect+Twitter+Spam+Attack%3F&amp;url=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/" title="Add 'The Perfect Twitter Spam Attack?' to FriendFeed"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/friendfeed.png" title="Add 'The Perfect Twitter Spam Attack?' to FriendFeed" alt="Add 'The Perfect Twitter Spam Attack?' to FriendFeed" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/reader/link?url=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/&amp;title=The+Perfect+Twitter+Spam+Attack%3F&amp;srcURL=http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/" title="Add 'The Perfect Twitter Spam Attack?' to Google Buzz"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/googlebuzz.png" title="Add 'The Perfect Twitter Spam Attack?' to Google Buzz" alt="Add 'The Perfect Twitter Spam Attack?' to Google Buzz" /></a></div> ]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/03/the-perfect-twitter-spam-attack/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Twitter&#8217;s new OAuth Problem</title><link>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/</link> <comments>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/#comments</comments> <pubDate>Fri, 12 Feb 2010 12:10:07 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[politics]]></category> <category><![CDATA[usability]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[security]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1627</guid> <description><![CDATA[Twitter have announced that all third party site will have to use OAuth.  You will no longer be able to just type in your username and password to get access to Twitter via your favourite web client.
Usually, I would be a big fan of this move &#8211; especially if it forces password anti-pattern sites like ...]]></description> <content:encoded><![CDATA[<p><a
href="http://groups.google.com/group/twitter-api-announce/browse_thread/thread/c2c4963061422f28?hl=en&amp;pli=1">Twitter have announced that all third party site will have to use OAuth</a>.  You will no longer be able to just type in your username and password to get access to Twitter via your favourite web client.</p><p>Usually, I would be a big fan of this move &#8211; especially if it forces <a
href="http://adactio.com/journal/1357">password anti-pattern</a> sites like <a
href="http://getsatisfaction.com/twitpic/topics/when_will_twitpic_implement_oauth">TwitPic to implement the new, secure standard</a>.</p><p>This means that you won&#8217;t be able to log in to a third party site by giving them your username and  password.  You will have to use OAuth to securely validate with the main Twitter site.</p><p>But &#8211; as ever &#8211; there&#8217;s a dark side to OAuth.</p><h2>Repressive Regimes</h2><p>One of the joys of Twitter is that its clients are decentralised from the main site.</p><p>This means that if Twitter is blocked in your country, you can use a third party client (like <a
href="http://dabr.co.uk/">Dabr</a>) to access it.</p><blockquote><pre>Twitter User -&gt; Dabr -&gt; Twitter API -&gt; Dabr -&gt; User</pre></blockquote><p>If Dabr became sufficiently popular to be blocked by an oppressive regime, you can switch to any one of the thousands of Twitter web clients.</p><p>OAuth <strong>forces </strong>you to the main Twitter site.  While you may visit Dabr to start with, you would be redirected to Twitter to complete OAuth.  If Twitter is blocked, you can&#8217;t connect.</p><h3>At a stroke, Twitter has shut itself off to anyone in a repressive country.</h3><p><a
href="http://groups.google.com/group/twitter-development-talk/browse_thread/thread/39b8b326d8b679c6">This has been picked up by some concerned users</a>.</p><h2>A (Hacky) Way Around It</h2><p>There&#8217;s really only one way around this problem.  The third party web client has to act as a man-in-the-middle.  There&#8217;s a patch for Dabr &#8211; developed by <a
href="http://code.google.com/u/cnyegle/">cnyegle</a> &#8211; which will ask for a username and password, then proxy it to Twitter, get the OAuth token and tweet on behalf of the user.</p><p>From the user&#8217;s point of view, they are still giving the (potentially untrusted) site the username and password.</p><h2>Challenge Response</h2><p>This could be solved by implemented a challenge / response system.</p><ol><li>Alice visits the Dabr website.</li><li>Dabr asks Alice for her username (and <em>only</em> her username)</li><li>Dabr asks Twitter for the challenge associated with Alice&#8217;s username.</li><li>Twitter checks that Dabr is an authorised website (i.e. has signed up for OAuth).</li><li>Twitter returns the response:  A secret phrase which Alice has previously chosen.</li><li>Dabr displays this phrase to Alice.</li><li>Alice knows that Twitter trusts Dabr</li><li>Dabr asks Twitter for the password challenge.</li><li>Twitter returns that it requires the 3rd, 5th and last character from Alice&#8217;s password (the characters requested change randomly).</li><li>Dabr asks Alice for <em>only</em> those characters.</li><li>If Alice provides the correct characters, an OAuth token is granted to Dabr to tweet on behalf of Alice.</li></ol><p>This has the advantage of proving that Dabr is trusted (by displaying Alice&#8217;s pre-defined secret phrase) and mitigating the risk that Dabr is untrusted (by only revealing part of the password).</p><h2>Conclusion</h2><p>This is a very new area, and I&#8217;ve not had a chance to read through all of the proposals.  Nevertheless, it remains a fundamental problem that, if you can&#8217;t access a site, you need to delegate your trust to someone else.</p><p>I&#8217;m not a security expert &#8211; so I would appreciate someone pointing out the flaws in my reasoning.</p><div
class="social_bookmark"><em>Share This</em><br
/><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/&amp;title=Twitter%26%238217%3Bs+new+OAuth+Problem" title="Add 'Twitter&#8217;s new OAuth Problem' to Del.icio.us"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="Add 'Twitter&#8217;s new OAuth Problem' to Del.icio.us" alt="Add 'Twitter&#8217;s new OAuth Problem' to Del.icio.us" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/&amp;title=Twitter%26%238217%3Bs+new+OAuth+Problem" title="Add 'Twitter&#8217;s new OAuth Problem' to digg"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="Add 'Twitter&#8217;s new OAuth Problem' to digg" alt="Add 'Twitter&#8217;s new OAuth Problem' to digg" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/&amp;title=Twitter%26%238217%3Bs+new+OAuth+Problem" title="Add 'Twitter&#8217;s new OAuth Problem' to reddit"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/reddit.png" title="Add 'Twitter&#8217;s new OAuth Problem' to reddit" alt="Add 'Twitter&#8217;s new OAuth Problem' to reddit" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/" title="Add 'Twitter&#8217;s new OAuth Problem' to Technorati"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="Add 'Twitter&#8217;s new OAuth Problem' to Technorati" alt="Add 'Twitter&#8217;s new OAuth Problem' to Technorati" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/&amp;title=Twitter%26%238217%3Bs+new+OAuth+Problem" title="Add 'Twitter&#8217;s new OAuth Problem' to Stumble Upon"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="Add 'Twitter&#8217;s new OAuth Problem' to Stumble Upon" alt="Add 'Twitter&#8217;s new OAuth Problem' to Stumble Upon" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/&amp;title=Twitter%26%238217%3Bs+new+OAuth+Problem" title="Add 'Twitter&#8217;s new OAuth Problem' to Google Bookmarks"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/google.png" title="Add 'Twitter&#8217;s new OAuth Problem' to Google Bookmarks" alt="Add 'Twitter&#8217;s new OAuth Problem' to Google Bookmarks" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.bloglines.com/sub/http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/" title="Add 'Twitter&#8217;s new OAuth Problem' to Bloglines"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/bloglines.png" title="Add 'Twitter&#8217;s new OAuth Problem' to Bloglines" alt="Add 'Twitter&#8217;s new OAuth Problem' to Bloglines" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?title=Twitter%26%238217%3Bs+new+OAuth+Problem&amp;url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/" title="Add 'Twitter&#8217;s new OAuth Problem' to SlashDot"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/slashdot.png" title="Add 'Twitter&#8217;s new OAuth Problem' to SlashDot" alt="Add 'Twitter&#8217;s new OAuth Problem' to SlashDot" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/&amp;t=Twitter%26%238217%3Bs+new+OAuth+Problem" title="Add 'Twitter&#8217;s new OAuth Problem' to FaceBook"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="Add 'Twitter&#8217;s new OAuth Problem' to FaceBook" alt="Add 'Twitter&#8217;s new OAuth Problem' to FaceBook" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wikio.it/vote?url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/" title="Add 'Twitter&#8217;s new OAuth Problem' to Wikio"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/wikio.png" title="Add 'Twitter&#8217;s new OAuth Problem' to Wikio" alt="Add 'Twitter&#8217;s new OAuth Problem' to Wikio" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home?status=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/" title="Add 'Twitter&#8217;s new OAuth Problem' to Twitter"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/twitter.png" title="Add 'Twitter&#8217;s new OAuth Problem' to Twitter" alt="Add 'Twitter&#8217;s new OAuth Problem' to Twitter" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://friendfeed.com/share/bookmarklet/frame#title=Twitter%26%238217%3Bs+new+OAuth+Problem&amp;url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/" title="Add 'Twitter&#8217;s new OAuth Problem' to FriendFeed"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/friendfeed.png" title="Add 'Twitter&#8217;s new OAuth Problem' to FriendFeed" alt="Add 'Twitter&#8217;s new OAuth Problem' to FriendFeed" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/reader/link?url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/&amp;title=Twitter%26%238217%3Bs+new+OAuth+Problem&amp;srcURL=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/" title="Add 'Twitter&#8217;s new OAuth Problem' to Google Buzz"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/googlebuzz.png" title="Add 'Twitter&#8217;s new OAuth Problem' to Google Buzz" alt="Add 'Twitter&#8217;s new OAuth Problem' to Google Buzz" /></a></div> ]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-problem/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Twitter OAuth &#8211; Mobile Failures</title><link>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/</link> <comments>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/#comments</comments> <pubDate>Sun, 07 Feb 2010 15:06:26 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[mobile]]></category> <category><![CDATA[usability]]></category> <category><![CDATA[dabr]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[security]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=1606</guid> <description><![CDATA[I&#8217;m a big fan of OAuth &#8211; despite some claims to the contrary.  It&#8217;s an excellent way of teaching people not to stick their username and password into any old site which asks for it.  Which is why I&#8217;m so incredibly disappointed in Twitter&#8217;s implementation of mobile OAuth.
For a service which started out ...]]></description> <content:encoded><![CDATA[<p>I&#8217;m a big fan of OAuth &#8211; <a
href="http://www.theregister.co.uk/2009/11/04/oauth_dark_side/">despite some claims to the contrary</a>.  It&#8217;s an excellent way of teaching people not to stick their username and password into any old site which asks for it.  Which is why I&#8217;m so incredibly disappointed in Twitter&#8217;s implementation of mobile OAuth.</p><p>For a service which started out operating by SMS, Twitter takes a surprisingly unenlightened view of mobile.  It&#8217;s main mobile service &#8211; <a
href="http://m.twitter.com/">http://m.twitter.com/</a> &#8211; is almost completely devoid of useful features.  That&#8217;s one of the main impetuses behind the development of <a
href="http://dabr.co.uk/">Dabr</a>.  Their latest mobile site &#8211; <a
href="http://mobile.twitter.com/">http://mobile.twitter.com/</a> &#8211; is really only suitable for the tiny minority of people who have smartphones.</p><p>So, understandably, many people use 3rd party sites like Dabr.  They are now faced with a dilemma &#8211; give an untrusted site their username and password or try to use OAuth on the mobile.</p><p>A few weeks ago came the <a
href="http://groups.google.com/group/twitter-development-talk/browse_thread/thread/084f57349587b3d2/">announcement that OAuth was finally ready for mobile</a>&#8230; Was it? No.  Once again a &#8220;mobile friendly&#8221; site designed with masses of JavaScript and guaranteed not to work with the majority of phones on the market.</p><p>Here&#8217;s how mobile OAuth looks on a variety of popular mobile phones.</p><h2>BlackBerry</h2><div
id="attachment_1607" class="wp-caption aligncenter" style="width: 480px"><img
class="size-full wp-image-1607" title="BlackBerry Twitter OAuth" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/BlackBerry-Twitter-OAuth.png" alt="BlackBerry Twitter OAuth" width="470" height="695" /><p
class="wp-caption-text">BlackBerry Twitter OAuth</p></div><p>While this looks pretty enough, it doesn&#8217;t work.  The buttons <em>aren&#8217;t clickable</em>.  I&#8217;ve tried with and without JavaScript.  No matter where I click, nothing happens.</p><h2>Android</h2><p>The Android&#8217;s User-Agent isn&#8217;t detected by Twitter as being a mobile phone.  While it&#8217;s true that the browser is very capable &#8211; the OAuth screen is a lot more usable when it&#8217;s in mobile mode.</p><div
id="attachment_1610" class="wp-caption aligncenter" style="width: 330px"><img
class="size-full wp-image-1610" title="Android Twitter OAuth" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/android2.png" alt="Android Twitter OAuth" width="320" height="480" /><p
class="wp-caption-text">Android Twitter OAuth</p></div><p>So, it works, but it doesn&#8217;t look nice.</p><h2>N95</h2><p>The N95 makes a good test phone because it&#8217;s popular.  Probably more popular than the iPhone.</p><div
id="attachment_1612" class="wp-caption aligncenter" style="width: 250px"><img
class="size-full wp-image-1612" title="N95 Twitter OAuth" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Screenshot0106.png" alt="N95 Twitter OAuth" width="240" height="320" /><p
class="wp-caption-text">N95 Twitter OAuth</p></div><div
id="attachment_1613" class="wp-caption aligncenter" style="width: 250px"><img
class="size-full wp-image-1613" title="N95 Twitter OAuth" src="http://shkspr.mobi/blog/wp-content/uploads/2010/02/Screenshot0108.png" alt="N95 Twitter OAuth" width="240" height="320" /><p
class="wp-caption-text">N95 Twitter OAuth</p></div><p>It&#8217;s not pretty &#8211; but at least it works.</p><h2>Others</h2><p>The Sharp GX-10 is my default test phone.  One of the first phones with a colour HTML browser.  If your site can work on this phone, it will work on any phone.  There are no screenshot capabilities for this phone &#8211; but rest assured, it does not work.</p><p>The three phones I&#8217;ve demo&#8217;d above are very popular modern phones &#8211; AKA the minority.  If they don&#8217;t work well, what chance for the people using older phones?</p><p>Useless!  How hard can it be?  All it needs is a username field, a password field and a button.  That&#8217;s just about the most basic page imaginable.  It should be child&#8217;s play to make it work on mobile.</p><p>This was <a
href="http://code.google.com/p/twitter-api/issues/detail?id=395">first raised in March 2009 on Twitter&#8217;s issues list</a>. It&#8217;s currently the <em>most popular</em> bug.</p><p>So, we&#8217;re stuck in a dire situation.  Third-Party mobile sites get access to Twitter users&#8217; passwords because Twitter are unable or unwilling to develop a <em>simple</em> OAuth form.  It would be fascinating to know how many of Twitter&#8217;s security breaches are down to corrupt or insecure 3rd party sites which leak passwords.</p><div
class="social_bookmark"><em>Share This</em><br
/><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/&amp;title=Twitter+OAuth+%26%238211%3B+Mobile+Failures" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Del.icio.us"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Del.icio.us" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to Del.icio.us" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/&amp;title=Twitter+OAuth+%26%238211%3B+Mobile+Failures" title="Add 'Twitter OAuth &#8211; Mobile Failures' to digg"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to digg" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to digg" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/&amp;title=Twitter+OAuth+%26%238211%3B+Mobile+Failures" title="Add 'Twitter OAuth &#8211; Mobile Failures' to reddit"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/reddit.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to reddit" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to reddit" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Technorati"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Technorati" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to Technorati" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/&amp;title=Twitter+OAuth+%26%238211%3B+Mobile+Failures" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Stumble Upon"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Stumble Upon" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to Stumble Upon" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/&amp;title=Twitter+OAuth+%26%238211%3B+Mobile+Failures" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Google Bookmarks"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/google.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Google Bookmarks" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to Google Bookmarks" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.bloglines.com/sub/http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Bloglines"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/bloglines.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Bloglines" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to Bloglines" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?title=Twitter+OAuth+%26%238211%3B+Mobile+Failures&amp;url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/" title="Add 'Twitter OAuth &#8211; Mobile Failures' to SlashDot"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/slashdot.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to SlashDot" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to SlashDot" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/&amp;t=Twitter+OAuth+%26%238211%3B+Mobile+Failures" title="Add 'Twitter OAuth &#8211; Mobile Failures' to FaceBook"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to FaceBook" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to FaceBook" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wikio.it/vote?url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Wikio"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/wikio.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Wikio" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to Wikio" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home?status=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Twitter"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/twitter.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Twitter" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to Twitter" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://friendfeed.com/share/bookmarklet/frame#title=Twitter+OAuth+%26%238211%3B+Mobile+Failures&amp;url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/" title="Add 'Twitter OAuth &#8211; Mobile Failures' to FriendFeed"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/friendfeed.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to FriendFeed" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to FriendFeed" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/reader/link?url=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/&amp;title=Twitter+OAuth+%26%238211%3B+Mobile+Failures&amp;srcURL=http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Google Buzz"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/googlebuzz.png" title="Add 'Twitter OAuth &#8211; Mobile Failures' to Google Buzz" alt="Add 'Twitter OAuth &#8211; Mobile Failures' to Google Buzz" /></a></div> ]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2010/02/twitter-oauth-mobile-failures/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Twitter, OAuth and Passwords &#8211; Oh My!</title><link>http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/</link> <comments>http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/#comments</comments> <pubDate>Wed, 04 Nov 2009 13:04:57 +0000</pubDate> <dc:creator>Terence Eden</dc:creator> <category><![CDATA[usability]]></category> <category><![CDATA[nablopomo]]></category> <category><![CDATA[oauth]]></category> <category><![CDATA[security]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://shkspr.mobi/blog/?p=994</guid> <description><![CDATA[Twitter has a gaping security hole.  Changing your password won&#8217;t stop malicious users logging in as you!
I received a rather worrying email from Twitter.  Apparently they thought my password had been compromised and needed to be reset.
After checking to see if it was valid, I went and changed my password.  Any site which relied on ...]]></description> <content:encoded><![CDATA[<p>Twitter has a gaping security hole.  Changing your password <strong>won&#8217;t stop malicious users logging in as you!</strong></p><p>I received a rather worrying email from Twitter.  Apparently they thought my password had been compromised and needed to be reset.</p><div
id="attachment_996" class="wp-caption aligncenter" style="width: 310px"><img
class="size-medium wp-image-996" title="twitpass" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/twitpass-300x192.jpg" alt="Reset Your Twitter Password" width="300" height="192" /><p
class="wp-caption-text">Reset Your Twitter Password</p></div><p>After checking to see if it was valid, I went and changed my password.  Any site which relied on a cookie to post to Twitter would have been blocked out. Ha! Gotcha, suckers!</p><h2>The OAuth Problem</h2><p>OAuth tokens are <strong>not</strong> revoked when the master password is changed.</p><p><a
href="http://oauth.net/">OAuth </a>is a great idea &#8211; rather than give your username and password to any random site, you log on to Twitter and tell them that you authorise the refering site.  The site gets an OAuth token and never gets to see your password.  Great! Right? Not really.</p><p>Let&#8217;s consider the following scenario.</p><p>Alice has a Twitter username and password.</p><p>Bob runs a Twitter site.</p><p>Alice visits Bob&#8217;s site.  Alice is security conscious and uses OAuth.</p><p>Eve somehow discovers Alice&#8217;s password.</p><p>Eve also visits Bob&#8217;s site and uses OAuth.</p><p>Alice gets suspicious about strange activity on her account and changes her password.</p><p>Because Bob&#8217;s site uses OAuth, it <strong>does not require</strong> either Alice <em>or</em> Eve to re-enter Alice&#8217;s password.</p><p>In this scenario, Alice has to visit <a
href="http://twitter.com/account/connections">Twitter&#8217;s OAuth Connections page</a> and revoke access to <em>all</em> the sites she has previously connected to.  Alice has no way of knowing when each site was last accessed.  She also doesn&#8217;t know which site Eve is using.</p><div
id="attachment_995" class="wp-caption aligncenter" style="width: 310px"><img
class="size-medium wp-image-995" title="twitoauth" src="http://shkspr.mobi/blog/wp-content/uploads/2009/11/twitoauth-300x192.jpg" alt="Twitter's OAuth Page" width="300" height="192" /><p
class="wp-caption-text">Twitter&#39;s OAuth Page</p></div><h2>The Problem</h2><p>Changing a password should &#8211; in the minds of most people &#8211; mean that you need to re-enter your password even if you have previously authenticated yourself.</p><p>In this scenario, changing the password does not revoke access to malicious users who have previously used your credentials.</p><p>Twitter should revoke all OAuth tokens when a user&#8217;s password is changed. It is the only way to ensure that stolen credentials cannot continue to be used after a user has changed their password.</p><h2>Addendum</h2><p>As I&#8217;ve made clear in the comments &#8211; this <em>isn&#8217;t</em> a vulnerability within OAuth per se.  It&#8217;s a usability issue which has strong security implications.</p><p>I spoke to Eran Hammer-Lahav (listed as <a
href="http://oauth.net/advisories">OAuth&#8217;s advisory contact</a>) who said:</p><blockquote><p>If you suspect someone stole your password, you should revoke any tokens you did not personally authorized. But there is no reason to revoke tokens just because you are changing password.</p></blockquote><p>While I appreciate this as the official line from those in the know, it does nothing to prevent a user who uses the same sites as you.  For example, I can see on every tweet that you use Dabr.  Therefore, I can safely OAuth myself as you on Dabr.  You&#8217;ll change your password, but you <em>won&#8217;t</em> revoke Dabr&#8217;s token because <strong>you personally authorised it</strong>.</p><h2>Continuing The Conversation</h2><p>Heise Online <a
href="http://www.heise.de/newsticker/meldung/Hintertuer-bei-Twitter-schliessen-850287.html">provides comentary in German</a> (<a
href="http://www.h-online.com/security/news/item/Shutting-Twitter-backdoors-850717.html">English version</a>)</p><p>El Reg has a <a
href="http://www.theregister.co.uk/2009/11/04/oauth_dark_side/">feature about Twitter and OAuth</a>.</p><p>There&#8217;s also an <a
href="http://news.ycombinator.com/item?id=921619">interesting discussion over at Hacker News</a>.</p><div
class="social_bookmark"><em>Share This</em><br
/><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/&amp;title=Twitter%2C+OAuth+and+Passwords+%26%238211%3B+Oh+My%21" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Del.icio.us"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Del.icio.us" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Del.icio.us" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/&amp;title=Twitter%2C+OAuth+and+Passwords+%26%238211%3B+Oh+My%21" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to digg"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to digg" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to digg" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/&amp;title=Twitter%2C+OAuth+and+Passwords+%26%238211%3B+Oh+My%21" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to reddit"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/reddit.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to reddit" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to reddit" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Technorati"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Technorati" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Technorati" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/&amp;title=Twitter%2C+OAuth+and+Passwords+%26%238211%3B+Oh+My%21" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Stumble Upon"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Stumble Upon" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Stumble Upon" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/&amp;title=Twitter%2C+OAuth+and+Passwords+%26%238211%3B+Oh+My%21" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Google Bookmarks"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/google.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Google Bookmarks" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Google Bookmarks" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.bloglines.com/sub/http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Bloglines"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/bloglines.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Bloglines" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Bloglines" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?title=Twitter%2C+OAuth+and+Passwords+%26%238211%3B+Oh+My%21&amp;url=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to SlashDot"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/slashdot.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to SlashDot" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to SlashDot" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/&amp;t=Twitter%2C+OAuth+and+Passwords+%26%238211%3B+Oh+My%21" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to FaceBook"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to FaceBook" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to FaceBook" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wikio.it/vote?url=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Wikio"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/wikio.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Wikio" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Wikio" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home?status=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Twitter"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/twitter.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Twitter" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Twitter" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://friendfeed.com/share/bookmarklet/frame#title=Twitter%2C+OAuth+and+Passwords+%26%238211%3B+Oh+My%21&amp;url=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to FriendFeed"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/friendfeed.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to FriendFeed" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to FriendFeed" /></a><a
class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/reader/link?url=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/&amp;title=Twitter%2C+OAuth+and+Passwords+%26%238211%3B+Oh+My%21&amp;srcURL=http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Google Buzz"><img
src="http://shkspr.mobi/blog/wp-content/plugins/social-bookmarking-reloaded/googlebuzz.png" title="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Google Buzz" alt="Add 'Twitter, OAuth and Passwords &#8211; Oh My!' to Google Buzz" /></a></div> ]]></content:encoded> <wfw:commentRss>http://shkspr.mobi/blog/index.php/2009/11/twitter-oauth-and-passwords-oh-my/feed/</wfw:commentRss> <slash:comments>36</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced) (request URI is rejected)

Served from: shkspr.mobi @ 2010-08-01 01:22:10 -->