API Security Testing – How to Hack an API and Get Away with It (Part 3 of 3)
[caption id="attachment_20924" align="aligncenter" width="500"] The first two installments in this series have set us well on our path to API security/intrusion nirvana; we first got to grips with current API technology basics, moved on to API Attack surface detection and then looked at a series of common and potent vulnerability attacks – all sharing the fact that they are pretty simple to perform using a little wit and available tools. Let’s dig a little more in our arsenal before concluding with some hands on tips on how to work with API Security Testing.[/caption]
Cross Site Request Forgery (CSRF)
The last vulnerabilities we looked at in the previous installment were related to cross-site scripting attacks (XSS). Now, let’s have a look at another vulnerability / attack that plays with similar cards; cross-site request forgery. Just like XSS, this is an attack that originates from a web-browser – but since it often follows through with an API call it is definitely something you should be aware of:
Let’s walk through this so to provide an understanding of how this type of attack works:
- A user logs in to his/her bank account – which sets a session cookie on the client
- The bank shows a (malicious) ad for the latest vitamin pills, which the user clicks on without first logging out of the bank
- The page selling vitamin pills also contains a hidden form performing a bank-transfer, which is submitted automatically without the user noticing
- Since the user is still logged in to the bank the “forged request” succeeds and makes the transfer without the user noticing.
While this example may seem somewhat contrived (what bank shows vitamin ads?), I’m sure you get the idea, and I’m also sure I’m not the only one that has navigated away from an authenticated site without logging out first.
A common way to attempt to prevent these attacks is to look for specific http headers related to request referral, but headers can easily be spoofed using various techniques described online. The much better way to guard for these attacks from a development point-of-view is therefore to require a unique request token to be added to each incoming request to an API – either as an HTTP header or as a query parameter. The value is generated by the server when preparing the underlying webpage using a secret algorithm - which the attacker presumably won’t know – and thus won’t be able to.
Testing this becomes straightforward; are tokens enforced and validated correctly? What if you use one of the previously discussed techniques for the token itself; fuzzing, injection, etc.? Is this all handled gracefully or does an error message give away a little too much about how things are being done on the server side?
Insufficient SSL Configuration
Let’s shift our focus a little and have a look at some common vulnerabilities and attack opportunities that relate to the security stack of your API itself.
Using a self-signed SSL certificate is an easy mistake to make – the convenience of generating your own certificate is high – but the dangers are lurking, especially when it comes to APIs; if your app is the only one consuming your API your developers might even have hard-coded the client to accept the certificate – and then forgot all about it. Unfortunately, using a self-signed certificate leaves your API wide open for man-in-the-middle attacks – where an attacker inserts him/herself between the API and its client by replacing the client-facing certificate – allowing them to listen in on (and modify) traffic that was meant to be encrypted.
Testing for insufficient SSL configurations is straightforward – make sure your tests accept only valid certificates. Taking an extra precaution for MITM attacks is also advisable – for example by adding signatures to a message, which makes it impossible (well, almost) for a eavesdropper to modify messages on the wire, even if they manage to insert themselves in the communication pipeline. Testing with signatures, that they are enforced, correctly validated, etc. – is equally possible.
Insecure Direct Object References (IDOR)
Including object references as arguments to an API call is common practice – and consequently a very common API vulnerability is that access rights are not enforced for objects a user does not have access to. Identifying id parameters and sequentially looping through possible values can be an easy way to access data that isn’t meant for a user – once again API metadata can be a natural source for more information in this regard, making it easy for both hackers and tester to find possible attack surfaces within an API topology.
As a tester you need to validate that security is correctly enforced for objects one should not have access to – which is easily done by automating requests to resource not accessible and validating that the correct error messages are shown. At a higher level – you should perhaps also question the usage of identifier values that can easily be guessed – especially if the data is sensitive. Perhaps using GUID identifiers could be a better solution as identifiers in applicable cases.
Bad Session / Authentication Handling
The previous vulnerability is a specific example of whole slew of vulnerabilities related to bad session, security and authentication handling. Consider some more examples:
- Are session tokens re-used or sequential?
- Do session tokens timeout correctly?
- Are tokens exposed in unencrypted traffic?
- Are tokens added to URLs when sending links?
- Are login endpoints restricted?
All of these will be obvious attack points for a hacker – and should be as such for you as a Security Tester. Make sure that the described situations are correctly handled, do not give “bad” error messages if charged with invalid / unexpected input (using the arsenal of tests we have been looking at) – and do not provide an entry point for a hacker to start prying away at the walls of your APIs defense mechanisms!
Recap – and some tips to go!
Some hands-on tips to ensure that your APIs are fully security tested before we say our goodbyes:
- Automate: Most of the testing approaches for security vulnerabilities that we have covered can be automated (here’s a tool to help you do so); and should definitely be done so – preferably against your production environment in some way. A system upgrade or server reconfiguration could be just as much a cause for a security vulnerability as bad development in the code of your APIs – and you definitely want to find out if such changes open up for unexpected vulnerabilities before anyone else.
- Stay on top: OWASP provides invaluable services and information on Internet related security vulnerabilities – and how to work against them. Make it a habit to check out their website and match their recommendations and findings against your APIs and infrastructure. Follow their guidelines – specifically those geared at APIs - and make sure you are doing what you can base on their resources.
- Finally - It’s your problem: Security is probably not going to be fixed or worried by anyone else than you, – make sure you give it the same attention and focus as you do to functional, performance, usability, A/B testing, etc. The price to pay for leaked passwords or erased user data is too high to pay for you not to care (which I know you do).
And there you have it - that’s it for the last part of the series. Hopefully you have learned plenty; basic underpinnings of API security vulnerabilities, how easy it is too perform common API attacks and how equally easy it is in most cases to test for corresponding vulnerabilities. Now get out there and hack an API!
API Security Testing – How to Hack an API and Get Away with It (Part 1 of 3)
API Security Testing – How to Hack an API and Get Away with It (Part 2 of 3)