Designing a Secure Service
It’s a popular pattern today to build a set of APIs (usually with JSON and HTTP) to expose functionality to various applications (mobile and single-page applications.) These services are often the heart of a start-up. Ensuring they are secure is difficult, but required.
Keep in mind, if you write a service that isn’t useful or reliable, it doesn’t matter how secure it is, because no one will use it. Before you launch, though, you will need to be secure. But don’t think of it that way: security isn’t a spice that you season on your service. It’s a fundamental component of any distributed system.
I remember when an early employer of mine started taking security seriously. We stopped development on many projects, took classes, and made security a top-level component, like performance or reliability. Before then, we hadn’t taken shipping secure software seriously enough. But those tools helped us deliver far more secure software than previously.
One of those classes taught me a great technique and acronym: STRIDE:
- Spoofing identity
- Tampering with data
- Repudiation (and non-repudiation)
- Information disclosure
- Denial of service
- Elevation of privilege
This is one of the most obvious of security vulnerabilities. Clients of your service (be they people, other services, etc) should not be able to fake that they are someone else. This is generally solved as part of authentication process. Credentials (and security tokens more generally) can be required. The most popular (but not the most secure) credential is a username and password.
Tampering with data
When someone sends your service a message, a man in the middle should not be able to alter the data. For instance, if your service provides chat messages, the bad guys should not be able to turn “I love you” into “I hate you”. This can be mitigated by securing the message or the channel cryptographically. For instance, signing a message with a public key.
Especially with e-commerce and other finance related applications, you need to prevent people from saying: “it wasn’t me.” Repudiation is the security flaw that prevents you from saying that. Generally speaking, non-repudiation requires cryptographic signatures and a strong security token strategy.
If malicious parties can view information they don’t have the right to see, you have an information disclosure. With services, this generally could happen one of two ways: you use an unencrypted channel or you have bugs that allow unauthorized users to view other user’s information (see Elevation of Privilege below.)
The most common way this is manifested is with e-mail that sends someone’s password. E-mail (more specifically SMTP) is not encrypted, by default. If you send e-mail from your service and include important information, malicious actors can monitor network traffic and view that data.
Denial of Service
DDOS is an acronym you hear a lot. It means Distributed Denial of Service. This is when someone uses many machines (usually a botnet) to flood your service with (bogus) requests, bringing it down or at least making it impossible to use for legitimate users. This is usually best mitigated with services like CloudFlare. But, unless you have a very large budget, you will always be susceptible to these attacks.
For less thorough attacks, such as a single user trying to spam your service, you can use rate limiting. This is when you do an upfront check (before much more computationally intensive processing) to determine if the user is making more requests than they are allowed.
Elevation of Privilege
The final attack when a user is able to fool your service into giving her more privileges than she should be allowed. This can be done quite a few different ways.
For one, a cross-site scripting attack may allow one user to access another user’s data. That is a horizontal privilege elevation (and essentially the same as spoofing identity.) A vertical privilege escalation is would be when the user fools the system into thinking they have greater permissions (for instance, breaking DRM on a movie to allow saving it, or having greater money transfer limits with a financial application.)
Where to Go From Here
Knowing the attacks is helpful, but to actually deliver a secure service will require threat modeling. In a future post, I’ll give a practical example of how to review your system for threats (using STRIDE). I’ll also go into more detail on practical authentication and authorization technologies for modern services, which will help mitigate these attacks.
Special thanks to Amy Bond, Rohit Rajan, and Joe Mellin for reviewing early drafts.