If you’ve been following my Twitter account at all, you’ve probably noticed by now that I’ve become an avid mobile device (i.e. smartphone) user, and a fan of Android in particular. This isn’t just a passing phase for me, nor is this a technology fad that’s just going to fade away. Mobile technology is really taking off, and I wouldn’t be surprised if a paradigm shift won’t occur—if it hasn’t already—where more people will be using smartphones and mobile devices to access the Internet and other online services than using a full desktop or laptop. There are other contenders vying to be our one-and-only window to the digital world, like set-top boxes, digital TVs, and such, but nothing is as personal and portable as the smartphone and its bigger brother, the tablet.
That said, I’m not in the camp that believes that the Web is dead and that mobile apps are the way of the future. I’ve expressed my feelings on that here before. Apps won’t and can’t be the end-all, be-all interface to data and the mobile Web will always have a place. Thus the mobile browser is one of the most important apps a smartphone can have. That said, most browsers on smartphones are anemic, underpowered, and severely lacking in important functionality. Smartphone manufacturers and OS authors want us to believe that we can leave the laptop behind and work entirely from that wondrous miracle in our pocket, but fail to deliver the tools we need to make that dream a reality.
My case in point: client-certificate authentication. As a very brief summary, the entire industry of e-commerce rests entirely on a set of encryption technologies such as HTTPS, SSL, TLS, etc., that allow secure, private communication between a client (such as an online shopper) and a server (an online store). The server authenticates itself to the client by using a digital certificate, signed by a trusted certificate authority which has investigated and authenticated the server as a legitimate entity. The client can rest assured that the server belongs to the authenticated entity because the certificate uses strong public-key cryptography to provide a chain of trust back to the authenticating authority. Without this technology in place, we wouldn’t be able to tell legitimate businesses such as online retailers and banks from the phishing scams so prevalent on the Web. (This doesn’t always solve problems between the keyboard and the chair, of course, but it is effective as long as the wetware interface is working properly.)
But digital certificates can be used to authenticate the client as well as the server. Many businesses and governments use client certificates to authenticate users to secure systems. For example, I use a government-issued Smart Card to authenticate with my client’s servers. On this card is chip that contains my digital certificate, signed by a private certificate authority. When I authenticate with the client’s services, the private key on the card creates a digital signature which the server can authenticate against my public key, the inverse of what happens between the online shopper and the store front. Thus, I can trust the validity of the government’s certificate and know I’m connecting to their servers and no one else, and they in turn can validate that I (or the person who has my card) am who I say I am and let me in. I use a similar technology with GPF, although I import my certificates directly into the browser rather than use an external card. I created my own private certificate authority and issue client certificates to each browser I wish to use to access my admin interfaces. That way, I know only certain machines can access those portions of the site, offering a lot more security than just a simple password can provide.
This isn’t a new technology. SSL has been around almost as long as the Web itself, and it wasn’t long before the model was flipped around to authenticate clients to servers as well as servers to clients. This is a tool used by businesses every day all over the world. Every desktop browser supports client certificates because they are a standard. Any browser that doesn’t support them is likely to be overlooked or ignored in favor of browsers that do.
Yet the support for client certificates on mobile devices is appallingly absent. I know the built-in Android browser doesn’t support it, and I created an issue in Google’s official Android issue tracker to complain about it. Android supports client certs for WiFi authentication, but not in the browser, e-mail, or any other key service vital to secure business communications. Supposedly support for this functionality is going to be added in future versions of Android, but that doesn’t help me or any of the millions of current Android users until it comes time to upgrade our devices. I’ve read in various places that the iPhone supports client certs, but I’ve never been able to get any of the solutions to work with my iPod Touch (essentially an iPhone minus the annoying contract and poor service of AT&T). The only success I’ve had in this area has been with Firefox Mobile, which is pretty much a Firefox 4 release candidate smooshed and crunched down to fit on a mobile device. It’s bloated and a lot slower than Android’s built in browser and there’s no handy UI for importing certs like there is on the desktop, but if you take a sledgehammer to it and do some manual file tweaking, you can import your client and CA certs into the certificate database and use it effectively.
Seriously, guys… you want your devices and mobile OSes to be taken seriously by businesses as tools to take our work out of the office and on the road. Yet, you don’t give us the essential tools required to take advantage of this amazing freedom. Sure, you tell us “there’s an app for that”, but frankly, there isn’t. I’ve looked, and they’re not there. Apple won’t let third-party browsers compete with Safari on iOS and none of the Android add-on browsers support client certs either. Only Firefox, a desktop browser masquerading as a mobile app, comes close, and it takes a bit of technical wizardry to do something that should be a quick five second import. Someone’s got to step up to the plate and make some progress here, or no business that really understands security is going to take the mobile space seriously.
By now, I’m assuming most of you have read Mondays GPF News item. (If you haven’t, shame on you.) GPF is leaving Keenspot, and I’m neck-deep in unit testing the new site with hopes of releasing it to beta testers soon. If you’re interested in beta testing, you can volunteer in this thread on the old forum.
However, I’ve hit upon one little programming snag, so I thought I’d put out an appeal for help. I thought the blog would be more appropriate venue for this than the forum; that assumption could be wrong, but I’ll go with it anyway. For those of you with some Web-based programming knowledge, especially in the areas of PHP and cookies, please put on your thinking caps.
As part of the new site, I’m implementing my own version of Keenspot’s PREMIUM service, reusing the old relabeling of GPF Premium. Keenspot PREMIUM is going away (for several reasons I won’t go into here), but as the service’s biggest proponent and largest beneficiary, I’d hate to lose that functionality. So the new site will launch with its own independent Premium functionality including all the old service’s features (optional ad-free surfing, weekly archives, High-Def archives, tons of exclusives like Jeff’s Sketchbook, etc.) plus a few new features that I’ve been wanting to implement but haven’t had the time or technological hoop-jumping expertise to work on at Keen.
For security reasons, I want to secure Premium sign-ups and account management via secure HTTP (HTTPS). The benefits should be obvious. By encrypting account creation & management pages, you eliminate sniffing attacks and protect user privacy. While these pages may still be susceptible to other forms of attacks (and I’ve coded them to be as resilient as I know how), encrypting the traffic end-to-end can go a long way to cutting off those vectors of attack.
However, I seem to have hit a brick wall when it comes to setting the Premium authentication cookie. Like Keenspot’s implementation, the subscriber’s browser will be “enabled” by “branding” it with a cookie, which will be read and authenticated each time the page is loaded. If valid, Premium features for that page will be turned on; if invalid, the page will default to a non-enabled state, which could be a simple as showing all ads or as complex as denying access to the content within. Unlike Keenspot’s implementation, which was JavaScript based, mine is scripted server-side in PHP, meaning it should be more accessible to a wider range of browsers and in theory more secure (no Premium content is sent at all if Premium is not enabled, rather than letting the client browser decide). My implementation has been thoroughly tested and appears to work pretty much flawlessly… with one hitch.
The problem occurs when I set the cookie over the encrypted HTTPS connection, then try to read it over unencrypted HTTP. I appears that none of my test browsers send the cookie back when the encryption state changes. The reverse is the same; if I change the URL and set the cookie over HTTP, then try to access a page via HTTPS, the encrypted page can’t see the cookie either. It works like an either-or situation, when what I really want is both. If I set a cookie over HTTPS, I want to see it in both HTTP and HTTPS mode.
PHP’s primary cookie interface is the setcookie() method (for setting) and the $_COOKIE array (for reading). setcookie() includes a boolean parameter for secure cookies, i.e. cookies that will only be sent via HTTPS. What’s annoying is that even when I set this flag to false to force it to be insecure, the scripts continue to exhibit the same behavior: cookies set via HTTP can only be read via HTTP and vice versa. I’ve also tried setting the same cookie both ways–first in one protocol, then the other, without erasing the first cookie–but that didn’t seem to work. The second cookie overwrites the first one, effectively turning it off.
I had heard that IE 6 exhibited this behavior as a bug. However, I tried the exact same tests in Firefox 2.0.0.11, Opera 9.24, and Safari 3.0.4 (all on Windows) as well as IE 7, and all reacted the same way. Cookies set over HTTP could not be read over HTTPS and vice versa. It’s a bit frustrating. Obviously, I don’t want my Premium folks to be forced to use the new site in encrypted mode all the time, as this would slow down all the pages and put a significant extra load on the server as the number of subscribers increases. But I want to protect my users’ privacy and settings (and one of my important revenue streams) by encrypting their account access.
So I guess I’m looking for answers to two questions:
Any responses via e-mail or (preferred) comments below will be appreciated.
Update March 5, 2008: Thanks to the input of many commentors below, it looks like I’ve got a solution. The problem, as usual, was somewhere between the chair and the keyboard and the faulty component has been sufficiently flogged with a wet noodle. Immense thanks to everyone who provided feedback and suggestions.