The Password Anti-Pattern

September 3, 2009, 1:06pm
0 comments


This post/article was written by Chris Shiflett and myself a while ago. Both of us forgot about it until recently. I decided, as I don't have too much content on my blog, to post it here with Chris' consent.

------


We are all connected, and with recent trends in social networking and mashups, our personal identities are becoming more distributed than ever before. Because a chain is only as strong as its weakest link, this trend can have dangerous consequences. Instead of doing everything they can to help us protect our identities, some developers are utlizing a new technique that has been dubbed the password anti-pattern. This article explains the password anti-pattern and provides a brief introduction to OAuth, a possible solution.

The Problem

Imagine yourself as a CEO of a company, and instead of keeping all your important business contacts on your cell phone or computer, you keep it all in a five dollar address book from Staples. You like things old school, those crazy computers just make things more complicated. Last night you brought your address book home and forgot to bring it with you to work today. You decide that you are too busy to run back home for it and call your asssistant into the office. You hand over a set of spare keys to your house to your assistant, who, by the way isn't too fond of you after having been told he makes horrible coffee. You tell him to grab your address book from your home office, and to come straight back. Your assistant comes back with your address book and a suspicious grin on his face. Later that night, you get home and realize that someone has eaten the piece of apple pie you were saving. Thinking back you realize how foolish it was of you to give that amount of trust to your assistant. You should have never handed over the keys to something so valuable and private. You now consider yourself lucky that a piece of pie was the only thing you were robbed of. But man, you were really looking forward to that piece of pie...


A similar situation has arisen in the fast growing internet world. With the increasing number of web services out there today and their respective API's, it was bound to happen that they would want to share information with each other. There are plenty of examples of such situations. One of the more common being Facebook, or some other social communication service, such as Twitter wanting to access your e-mail address book in hopes to find 'friends'.

The following screenshot demonstrates an example of TwitPic which is not affiliated with Twitter wanting to connect to Twitter to provide a feature for Twitter users.


Twitpic


Somewhere along the way when this idea of sharing resources across web services crossed over into the implementation phase, someone got lazy and decided the easiest way to access these resources would be to have the user give up their credentials so that the web service could act as the user to retrieve the resource they wanted. It seemed as though other web services caught wind of the sharing web resources idea and proceeded in copying this bad implementation.


In the previous example of sharing a web resource, Facebook or Twitter will not only have access to my address book, but will have control over the entire e-mail service. They could send out invitation e-mails for their service to everyone in my address book without my consent. What is worse is the information they may acquire from my actual e-mail messages. Many web services provide ways to retrieve lost passwords by e-mailing replacement passwords to me. If I give my e-mail provider credentials away, there is a very real threat of that convenience being compromised and even more of my online services become vulnerable. Even if their intentions are good, there is absolutely no reason to give anyone but the issuing service your credentials, ever. When you do so you are putting complete trust with that service. Just like the keys and the assistant.

Solving the problem

Let's take a look at a similar problem. In the world of online credit card purchases, it seems that you are indeed practicing the same bad practice of handing over too much information regarding your credit card. Many credit card companies have ways to combat the risk involved with online purchasing. They will issue a special credit card number for the internet transaction that will only authorize for a specific amount and for the specific online store you want to purchase from. This special number is uniquely linked to you, and if someone else did happen to steal it, it would not work anywhere but that online store and for a limited amount of money.


Our problem in the internet world can be solved in a very similar fashion. We shouldn't have to put trust in the web services, because really we should never have to hand over the keys to the kingdom. That being said, lets think about the original good idea of sharing resources. It would be great to allow Facebook or Twitter access to my address book and only to my address book upon my approval and without having to give up my credentials.
   

An available solution


So how can this be accomplished? Well, as you may have guessed, there is a fairly new protocol that works to prevent placing too much trust into web services. It is called OAuth. What OAuth does is create a request token from the 'Consumer' web service, in this example, Facebook or Twitter. This request token is passed to the 'Service Provider', which would be my e-mail provider, such as Gmail. The request token contains a consumer key and secret which uniquely identifies the 'Consumer', Facebook. I will be redirected to a Gmail login, where upon giving my proper credentials to Gmail, I will be directed yet again to a page asking if I want to grant access to my address book to Facebook. If I agree, the request token is authorized and sent back to Facebook who can now create an access token to retrieve the information from Gmail.
   

As a developer, this seems like a great way for API's to share user resources. There are, however, a couple of concerns. How will this process degrade the user experience? As someone who is security conscious, I would much rather be redirected to a couple of pages than give my Gmail credentials to Facebook. However that process of being redirected can seem like an annoyance and may have end-users giving up on using the Consumer's feature. This seems to be very much the case in a society where we want our information as quickly as possible, whether it be on an mobile device, laptop, or some other electronic device. It will be interesting to see the ways in which Consumers will try and make this a more user friendly experience and how it may possibly create venues of vulnerability by misuse of the protocol. One possible implementation I'm sure I will see somewhere is the ability to keep users on the Consumer's site by handling the OAuth process with AJAX and iframes. This would make it much more difficult for an end-user to spot a potential phishing attack.


Another concern is the granularity to which the Service Providers will provide for its users over the access scope of their resources. What if I am ok with sending my address book to Facebook from Gmail but don't want my work contacts included. It would seem that this granularity would be beneficial on the Consumer side, so that an appropriate request can be made to Gmail from the start. However, if that were the case how can I be assured that the Consumer is acting on the users behalf by providing Gmail with my filtered request for the requested resource? This is why it would be more legitimate to have this type of access scope control available on the Service Provider side that provides access to my resources.


There is also the previously mentioned possibility of phishing. Who is to say that the Consumer that wants our address book is not some evil web service that is unbeknownst to us? It appears that they are using OAuth as I have been redirected to what looks like a legitimate Gmail login form and not asked for my Gmail credentials within the evil web service. The problem is that this is a phishing site and not actually Gmail. I end up giving the evil web service my credentials and they fake an OAuth access request. Now they are sending e-mails willy nilly to everyone in my address book, posing as me, wanting to invite them to use the evil web service. Requiring these web services to use SSL during the OAuth process will definitely help prevent this type of scenario. In a perfect world, users would be more cautious with sites that want authentication and would be educated on how to identify a legitimate site.


In addition to OAuth there are some other complimenting services out there that help keep trust from breaking down across these web services. OpenID provides for a single identity for the web. Using this OpenID you will be able to access all the many web services we use today, provided that they support OpenID (the idea is growing in acceptance).
   
Conclusion

OAuth seems to be a great step in resolving the password anti-pattern issue by providing a more secure way to share resources among services. Hopefully, developers will realize the danger of being a 'cookie cutter' of poorly thought implementation, implement features while upholding secure practices, and help protocols like OAuth become a mature solution by contributing to its underlying purpose. Some web-sites currently using OAuth include Google, Netflix, Yahoo!, Photobucket and more. Many web development frameworks are also making it easy to implement OAuth by providing OAuth components. Currently the protocol is at version 1.0a. Within the proposal for 1.1, OAuth plans to make some improvements. Some of these improvements include defining error codes, language support, and adding a set of defined token attributes. Information about OAuth can be found at oauth.net.

--

Links

http://php.net/oauth
http://oauth.googlecode.com/svn/code/php/
http://googlecodesamples.com/oauth_playground/


Tags: PHP, Security

SolarPHP on Mosso

May 18, 2009, 7:47pm
0 comments


I use mosso for this site as well as a couple others and recently I wanted to use SolarPHP for one of them. Solar uses some symlinks near the base to reach deeper into the directory structure of Solar and your app to make things a little easier. Since mosso doesn't support symlinks I had to tweak Solar a bit. Here is what I did.


copy the main solar directories to web/ except for the docroot directory.

put solar/docroot contents in web/content

modify the .htaccess file in the web/content directory and add RewriteBase /  (needed for mod-rewrite with mosso)

make sure to chmod 777 -R on web/sqlite and web/tmp

in web/content/index.php change

set_include_path("$system/include");
TO
set_include_path($system);

AND

require_once "Solar.php";
TO
require_once "$system/source/solar/Solar.php";


change web/source/solar/Solar/Class/Stack.php _run() method from

include func_get_arg(0);
       
TO
       
$file = Solar_File::exists(func_get_arg(0));
include $file;


in web/source/solar/Solar/Path/Stack.php find() method

add

$spec = Solar_File::exists($spec); 

BEFORE

return $spec;


In web/source/solar/Solar/File exists() method

add

if ($file[0] !== '/') {
    $first = strtolower(substr($file, 0, strpos($file, '/')));
    $file = 'source' . DIRECTORY_SEPARATOR . $first . DIRECTORY_SEPARATOR .  $file;
} else {
    $file = str_ireplace(Solar_Config::get('Solar', 'system') . '/source/', 'source/', $file);
}

AFTER

// no file requested?
$file = trim($file);
if (! $file) {
    return false;
}

Then for web/content/public instead of having the Solar and/or whatever
your vendor name is be a symlink to web/source/solar/Solar/App/Public

delete it and create a folder named Solar (or whatever your vendor name is) and put your images, scripts, etc folders within it.


That's it. You should now have a working Solar setup in mosso.


Tags: PHP, SolarPHP

Ubuntu 9.04 font rendering and the ZCE Exam

May 8, 2009, 10:10pm
0 comments


Wednesday night I got around to installing Ubuntu 9.04 on my home laptop. I use a triple booted macbook pro at work, where I am using Ubuntu intrepid almost exclusively. It has really grown on me and I've become addicted to the small, but very nice visual effects. Needless to say, I was looking forward to see how my home laptop would run Jaunty Jackalope. I was pleasantly surprised by two things in particular. The boot speed is much quicker, which granted, I don't notice that often as my laptop rarely gets shut down. Secondly, the improved font rendering looks great. One thing I always have to give the mac fans credit for is the way type is rendered. Now, I feel like I am no longer lacking in that department. The difference is amazing, and I am really considering upgrading my work laptop just for the font rendering, even though I don't have the best record with my update manager, less strain on my eyes will be worth the effort. Plus, I notice the lack of awesome font rendering that much more now on XP and Ubuntu intrepid.


I also recently took the Zend Certified Engineer (PHP5) exam and passed! Woo! I didn't think it was that difficult to be honest. I bought the study guide and the ten practice tests. I passed the first practice test and then excellent on the subsequent three. The actual exam did have a few odd, trick-like questions...but nothing extremely difficult. I do need to learn more about stream and SimpleXML functions as I haven't really done too much with them and I'm sure I missed a couple of those questions. I do think I have learned a lot in the last year, having been able to work on many different kinds of projects and needing to quickly learn new things has definitely helped. I'd like to thank all the guys at the OmniTI office that I constantly badger with questions for their help. :D



Some Blog Changes

January 24, 2010, 11:42am
3 comments


So, I'm making some changes to my blog. The first change is switching from rackspace cloud sites to a linode VPS. My personal experience with rackspace cloud was not the best. It went down more often than I would've expected and I had ongoing security issues involving their ftp access. I also felt the need for more control over my environment which I simply wasn't going to get with shared hosting. So far linode has been wonderful and I hope it stays that way.


The second, more obvious change is that I am using a blog engine I have been developing in my spare time. The project is called foresmo and still has a ways to go, but I'm enjoying it so far. Why create yet another blog engine? Well, a couple reasons. First and foremost, many of the popular blogging engines out there have awful codebases and although they may be easily extended with plugins, working with the core is just a nightmare. There are some shining lights out there, such as Habari, however I personally feel the admin UI is too minimalistic. I also simply enjoy working on it as a real blogging engine has some interesting problems and I like solving them. I am building foresmo on top of the SolarPHP framework, which I must admit I am a fan of. It is definitely making things easier for the project. Being able to provide database abstraction, caching adapters, and better searching (using google, sphinx, lucene, or fulltext) straight out of the box are some of things I am aiming to provide and SolarPHP helps me do that.


Anyways, I'm sure this blog will see the effects of the ongoing development, so I apologize in advance for any weirdness you may encounter.


Tags: Foresmo