We’re building a web service for which we aim to charge money. Further, the data being pushed around may be confidential or otherwise of a sensitive nature. We have good reasons to do everything we can to ensure that the service is secured “properly”:
- We don’t want to have customers charged for work that is requested by a bad actor exploiting a security hole (of course, we’d issue a refund and an apology in such a case, but the impact to our business through unnecessary processing could be sizable).
- We don’t want our customers’ data exposed; common vectors for this include sniffing, replay attacks, or simply the use of compromised credentials.
Of course, the impact on our relationship with our customers due to any security breach could be significant and devastating – to our business, our reputation, and potentially even to our customers’ affairs completely outside of their use of our web service. So again, we have a lot of reasons to be highly-motivated when it comes to security.
By way of context, let’s set the stage with regard to the moving pieces. The web service in question:
- is built on a JVM stack (with the application itself built with Clojure, of course, using the Compojure framework)
- has a user-facing, HTML browser interface as well as a “RESTful” API surface (“RESTful”, as in, pretty darn close to ROA “style”, so the set of URIs involved in delivering the user-facing interface vs. those delivering the REST API are nearly identical).
- the user-facing interface offers standard form-based authentication, as well as OpenID authentication (which will be recommended only for more casual users and usage).
- will always, always delivered over SSL. We assume that every bit of data transferred is confidential, so cleartext is an absolute no-no.
OK, let’s go find an expert
It is with this mindset that I’ve been digging into how to approach web service security. Note that I’m no specialist or expert in this area – I’m merely a practitioner that is usually focused on things far, far away from anything security-related. (It may not surprise you that I’m coming to appreciate that fact more and more as I learn about the “state of the art” in web service security.)
Given this, I set out a few weeks ago to see where things stand on the web service security front. Of course, that realm is just as full of cliques and posturing and strawmen and ad hominem attacks as the broader software development world is, so finding a clear path forward is not easy. First, a bit of literature review, as it were, drawn in particular from a flurry of web service security chatter a few years ago (emphasis here and there is mine, I wish I had noticed and grokked the indicated bits earlier, I’ll explain below):
- I started by finding Gunnar Peterson’s pair of posts where he compares “REST security” with WS-Security stuffs, where the former (especially approaches like HTTP Basic authentication over SSL) come out sounding like a pretty bad choice:
people who say REST is simpler than SOAP with WS-Security conveniently ignore things like, oh message level security
Some people in the REST community are able to see the need for message level security so this is heartening somewhat. If the data is distributed and the security model is point to point (at best), we have a problem.
- Pete Lacey lays out the counterpoint, saying that SSL works just fine for tons and tons of use cases, thankyouverymuch.
In summary, RESTful security, that is SSL and HTTP Basic/Digest, provides a stable and mature solution that addresses transport level credential passing, encryption, and integrity. It is ubiquitous, simple, and interoperable. It requires no out-of-band contract negotiation or a priori knowledge of how the resource (okay, service) is secured. It leverages your existing security infrastructure and expertise. And it addresses 99% of the use cases you are likely to encounter. SSL does not support message level security, and if that’s a requirement, then leveraging SOAP and WSS makes sense.
- Unsurprisingly, Sam Ruby backs up Pete Lacey, but the comments on that post are interesting:
- From Gunnar Peterson:
I am no way suggesting there is only way to do this or that WS-Security came down on stone tablets. I am also not suggesting that a NSA level of security is appropriate for Google Maps. There are many shades of gray. “good enough” security is a big challenge, and it isnt about black and white security models, it is about risk management
- From Bill de hÓra:
I think this is where quantative analysis comes in and a measured assessement of the risk is taken. What has to be protected and what’s the worthwhile cost of doing so? Being software people, that’s beyond the general state of the art. We do gut feelings, flames and opinions.
- From Gunnar Peterson:
- There’s a variety of “REST security ‘best practices’” posts out there, but a question from StackOverflow links to a variety of additional discussions there that serve as good an indication as any that the accepted way of securing REST web services is Basic auth over SSL.
Before moving on, I just want to point out that Bill de hÓra’s comment above is sadly representative of so many corners of software development. Let’s ponder that for a moment, while realizing that modern society and its continuation absolutely depends upon the software we build (I’m talking collectively, here).
Take a deep breath
Of course, the above is not an exhaustive survey, just the best tidbits I found over the course of a lot of browsing and searching. Here’s the upshot, as I see it:
- WS-Security et al. ostensibly provide message-level security that ensures that your service can be passed along by untrusted intermediaries.
- Standard HTTP authentication (generally Basic) over SSL transport is the de facto standard for securing REST services, but it does nothing for you if message security is important.
- More sophisticated authentication mechanisms are available – in particular HMAC, as exemplified by Amazon’s web services – which allow services to ensure that a message’s author has not been impersonated. This would resolve the potential holes of .
Unfortunately, I didn’t grok the whole message vs. transport security issue as quickly as I should have, where SSL provides the latter but the former would only be satisfied by something like WS-Security (again, ostensibly, I certainly can’t vouch for it) or HMAC-SHA1 if one were working in a REST environment. If I had come to grips with that point of tension earlier, I would have arrived at my two conclusions much faster:
- In our situation, message security is simply not relevant. As Peterson wrote (and I quoted above) “If the data is distributed and the security model is point to point (at best), [REST has] a problem.” Well, in our case, data is not distributed, it is transmitted point-to-point (between our customers and us, a third-party external web service), so transport security provided by SSL should be sufficient.
- Here’s the biggie: assuming we support form-based authentication (of course, over SSL) for browser-based UI interaction, supporting anything more sophisticated than HTTP Basic authentication over SSL for our REST API interactions would be a waste of resources. We could go full-tilt and require HMAC-SHA1 for the REST API or provide only a SOAP API that used WS-Security (and whatever else goes into that), but that would mean nothing if an attacker has the “REST API” provided for browser use available to him. Given this, transport security provided by SSL, and that alone, is simply all we can do. Put another way: when browser-level security mechanisms improve, then so will our APIs’.
An alternative path would be to host a parallel service, available via a REST API secured via HMAC-SHA1 or a WS-Security-enabled SOAP API, that did not provide any kind of browser-capable entry point. Customers could opt into this if they thought the tradeoff was important. Doing this would be technically trivial (or, perhaps only moderately difficult w.r.t. the SOAP option ), but I’ve no idea whether the additional degree of security provided by such a parallel service would be of any interest to anyone.
By the way, if I’m totally blowing this, and my conclusions are completely broken, do speak up.
Coming soon: Part II of my investigation/thinking on the subject of web service security, related to OpenID and the management of credentials in general…which should give me all sorts of new opportunities to say foolish things!