It was recently released that there were some security concerns with how the Moonpig, an online greetings card company in the UK, utilizes their API for mobile applications. From the public disclosure of a vulnerability found in their API it may be possible for a user to see other user’s personal information, including last 4 of their credit card number, expiration date and name. This is a great opportunity to look at some of the security issues and how they can be avoided in your code.
Take-Aways
For Developers
- Use strong authentication mechanisms
- Tamper Protection
- Anti-Replay
- Secure Communication
- Limited Access
- Don’t use hard-coded passwords
- Implement authorization checks at the row level for data records
- Implement brute-force and anti-automation protections
- Implement certificate-pinning if possible to limit the ability to intercept traffic
For QAs
- Use a proxy for inspecting traffic to the API
- This would help identify use of stored credentials
- Verify authorization checks
- This is especially important when you see numeric parameters. Increment/decrement them to see if access is granted to other customers
- Check for Brute Force protections
Authentication
One of the first things pointed out in how the MoonPig API works is the authentication. The application was making use of Basic Authentication, which is commonly seen in mobile API’s. The good news is that the basic authentication was being performed over a secure channel (HTTPS). The secure channel helps protect the credentials in transit to the server for verification. This protection is important because basic authentication only base64 encodes the username and password. It takes minimal effort to decode base64, although there is a common misconception otherwise. As an example, the username/password of “James:password” is encoded as “SmFtZXM6cGFzc3dvcmQ=”. While the resulting output appears to be unreadable, it isn’t. Basic authentication does have some drawbacks, such as no brute force or anti-replay protections.
It appears that the API in question had some detail about using OAuth2, but it was not implemented. OAuth provides a great option for authentication for mobile applications. In some implementations it will include a signature to help prevent tampering of the request, anti-replay functions and other controls that are very useful when authenticating a request. For more information on OAuth please visit the main OAuth Community Site.
Authorization
The next issue is a lack of authorization when it comes to accessing functionality or data. Authorization is the ability to determine what functionality or data an authenticated user has access to. Authentication is required for authorization to work. In this situation, the ability to view other user’s information is a perfect example. The API accepted a customer id of some sort, which happened to be an incremental numeric value, which identified what data to display. By incrementing that customer id, it could be possible to view a different customer’s data. This is common in many applications and is referred to as a Direct Object Reference. A properly designed application would only allow the authenticated user to have access to the customer records for which they control and not any others.
Anti-Automation
The final issue to discuss is the lack of brute force protections on the API. In a situation where simply implementing a parameter value by 1 or other set value returns different data, automating that to scrape lots of data becomes a concern. It would be one thing if an attacker could grab one record at a time manually and it takes a long time to get the entire database. It is completely different when a script can run through the 3 million records in a few minutes or an hour. Unfortunately, this can also be difficult to defend against when it is an API. With a user interface, you can throw a CAPTCHA or some other method up there, but with a lack of interface that can be a bit more challenging. This is something that should be thought about when designing your APIs.
Certificate Pinning
It is just an assumption that the application doesn’t use certificate pinning because the traffic was intercepted and modified. While it is possible to bypass certificate pinning I didn’t get that impression. The purpose of certificate pinning is to have the app only accept trusted certificates. When this is configured it makes it more difficult to use a certificate that is generated by the proxy an attacker might use for their man-in-the-middle attempts.
While certificate pinning is a great control, it is not always the right choice. If your users are within a corporate environment that sends all traffic through a proxy that may strip or modify the SSL then this might not be feasible.
Conclusion
We can learn something from all of the security incidents that we see. Although the breach may not effect you directly, take the time to understand what happened so you can ensure the same things are not happening within your organization.