Tuesday, October 21, 2008

DotNetOAuth source code to be released eminently

Microsoft attorneys have signed off on the open source release of the DotNetOAuth source code that I've been building in my spare time.  It should show up in the public git repo in the next 24 hours.  What's up there right now is several weeks old and tons of progress has been made that I'm eager to publish.

Once it's published I'd very much like to get some feedback on the public API, and any holes in what it supports. 

And now a review of what's coming...

I'll publish the DotNetOAuth source code first as a separate library just so you can get at it sooner, since that's its current form.  I'll eventually merge it into the DotNetOpenId library for its final release.  But I hope many of you will try it out in its separate library form and give lots of feedback, particularly on its public API including ease/difficulty of use and discovery, and scenarios that are not yet allowed or difficult given what I've exposed.

I have samples demonstrating both Service Provider and Consumer roles.  The Consumer sample demonstrates downloading your Gmail address book using OAuth.  Then both Consumer and SP samples work in tandem to show off WCF with OAuth authorization.  For those of us working more in the .NET or SOAP worlds, WCF is a great API for making data queries from one web site to another, and adding OAuth is really exciting.

And of course unit tests (currently 140 of them) verifying correct behavior.  The tests are written to use mstest.exe rather than NUnit.  Whether it stays that way is still flexible, but since I'm writing all the code at this point and find mstest to be more convenient and easier to measure code coverage for better testing, that's what I've chosen for now.  With the right set of #ifdefs, I just might be able to get compiles to work against either unit test library, but it hasn't been a priority yet.

As revealed before, this library takes dependencies on .NET 3.5.

Saturday, October 18, 2008

Your security is inversely proportional to the number of OpenID Providers you use

Just a quick note if you're familiar with OpenID's XRDS documents and how they allow you to have one 'omni-Identifier' that lists all your other OpenID providers and identifiers so that you can use this one Identifier to log in anywhere with any OP and yet maintain just a single identity.  Although there's great convenience in tying your several Identifiers into a single Identifier using an XRDS document, one should be cautious about just which Providers are listed inside your Identifier's XRDS document.

Any individual OP listed in your XRDS file has the capability of asserting your identity both through the identifier it assigned to you and through your omni-identifier.  If that OP was evil, or compromised, or just plain poorly written, your identity on all sites you log into with that Identifier is equally compromised. Your identity is only as secure as the weakest OP in your XRDS file.  Since you typically don't know which OP will fail first, a simple equation sums it up: the strength of your identity's security is inversely proportional to the number of Providers in your XRDS document.  Each one increases the surface area of your risk.

What does this mean?  Be cautious.  I would advise that you have no more than 3 Providers listed in your XRDS file.  One might be all you need.  In my case, I have a favorite OP, and then a couple of others I include with lower priority values so that RPs I sign into that have whitelists of OPs can still use my omni-Identifier.

You can be sure I won't add any community group's Provider to my XRDS file.  We should all keep only very reliable Providers as our identity providers.

Tuesday, October 14, 2008

Enable international characters in OpenID domain names

If you're using DotNetOpenId, you should consider enabling .NET to use IDN, or the International Domain Name scheme to enable users with international characters in the host name of their OpenID to log into your site.  Enabling IDN support requires .NET 3.5. 

First, add this to your web.config or machine.config file's <configuration><configSections> area.

<section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

Then within the <configuration> tag of your web.config file, add this snippet:

<uri>
	<idn enabled="All" />
	<iriParsing enabled="true" />
</uri>

And that's all there is to it.  Your dotnetopenid web site will automatically start supporting OpenIDs from around the world.

In DotNetOpenId 2.5.1 and later, these snippets will be included in the sample sites included in the distribution.

For more information, see read the section entitled "International Resource Identifier Support" in the MSDN Magazine article Get Connected With The .NET Framework 3.5

Monday, October 06, 2008

Why OAuth can't be ignored

Do you realize that your email password is probably your most sensitive piece of information?  You should never, ever give it away.  Not to another "trustworthy" web site, and not to a desktop app that wants to perform some service for you.  Web-based email these days is hosted by providers that offer many other services using the same user account.  For instance, if you use a desktop app to write blog posts and publish them to your Blogger account, do you realize you're giving that desktop app the full ability to read your email, write email as if it were you, download and publish your Google search history, and otherwise impersonate you on just about every web site you belong to?

Web sites and desktop apps like to offer services that extend or require the services on another web site, using your account.  It's your account!  Why do they need to impersonate you?  Likely because they need to access some data that is in your account and the web site holding that data will only let "you" access it, so obviously this new web site will need to pretend to be you to get to it.  This is what impersonation is about.

They don't need to impersonate you.  There are two reasons why trusting someone else to impersonate you is a Very Bad Idea:

  1. It usually involves giving away your password to that other web site.  Giving away your password is a free-for-all pass to your account.  It lets the other web site pretend to be you for an unlimited duration (or until you change your password, but that's a pain) and do unlimited things as you.  Oh, and they could publish your password to the world (yes, it actually happens!) either deliberately or on accident.
  2. Your password is very often the same password you use on many other sites.  Not only are you giving this arbitrary site the ability to impersonate you on just one site, but you're probably giving them the ability to impersonate you on many other sites as well.

There is a better way.  OAuth is a protocol that can give web sites and desktop applications the ability to access a constrained subset of your information or abilities on some web site, without giving away your password, and therefore without actually impersonating you, as the site holding your protected information knows that it's not really you, but some 3rd party you've authorized that is actually accessing your data.  Oh, and with OAuth you can revoke a 3rd party's privileges to access your protected data at any time without any inconvenience around changing your password.

Let's look at a couple of real-world scenarios:

Windows Live Writer Today

I love Windows Live Writer.  I'm using it now to write this post.  But it demands to know my Blogger username and password in order to publish posts when I'm done writing them.  So yes, Live Writer could theoretically read my email, write emails, read my address book, and ultimately break into all web sites that I have accounts on.  Oh, but Microsoft wrote Live Writer, so I'm safe, right?  Perhaps.  But suppose someone were to steal my laptop.  They could decrypt Live Writer's cache of my password and do all these Bad Things. 

Windows Live Writer Tomorrow

What I'd love to see is the next version of Live Writer to offer OAuth access to my Blogger account.  Google already supports OAuth so there's nothing stopping Live Writer from doing this.  Here's how it would work first setting up Live Writer to publish to my blog:

LW: What your blog URL?

Me: http://blog.nerdbank.net

LW: I see that that blog is hosted by Blogger.  I know how to work with that.  May I request permission to publish to it?

Me: Yes.

LW opens a browser window that I see google.com come up in.  I'm already logged into google.com since I read my email a lot, so I'm not asked to log in.

google.com: Live Writer says it wants to publish to your blog.  Is that ok with you?

Me: Yes.

google.com: Ok, LW has been authorized.  Close this window and return to LW.

Me: [I close the browser].  LW, Google.com has authorized you.

LW: Great.  You can start writing your first post now.

In this process neither I, nor Google, gave Live Writer my password.  Google generated a cryptographically strong token and token secret (essentially a username and password for computers to use) just for Live Writer to use, that is limited to just managing my blog. 

If someone were to steal my laptop now, the most they could do is update my blog.  But in that they would very likely fail because I could just log into google.com on any computer and revoke Live Writer's permission to publish to my blog and then the token that was stolen along with the laptop is worthless.

LinkedIn / Facebook

Social networking web sites are notorious for asking for your email password.  And they range from very reputable to downright nasty and people give their passwords away to all of them because we've trained them too.  Shame on us.

LinkedIn and Facebook should lead the way following this process:

LI: If you use any of the following email programs, click on one [list of logos].

Me: [click on Gmail]

LI: [quietly redirects me to google.com]

google: LinkedIn wants to download your address book.  Is that ok?

Me: Yes.

LI: Thanks!  We've spammed all your friends and recorded their email addresses so we can invite you to spam them again later if they don't join our web site. :)

You can see that this is even simpler for the user than the desktop client app example.  It is left as an exercise for the reader to justify giving away your friends' email addresses to some web site they may not want to join.

Why OAuth cannot be ignored

While the above are compelling reasons why OAuth should be used instead of impersonation, there is an unavoidable reason why OAuth will have to be used in the future: no passwords.  Passwords need to die, and are dying slowly already.  They can be phished, forgotten, lost, etc.  And they make impersonation too easy.  InfoCards and OpenID make great password replacements for logging into web sites.  But if there is no password, there is nothing for you to possibly share with these 3rd party apps that want to impersonate you.  Their only option left with be OAuth (or some similar technology) so they can get their own access token.  It's available today, so why wait?  Help train your users against being phished instead of training them to be phished, and future-proof your app today. 

Add OAuth support to your apps for accessing your users' data on other web sites!