Tip from @zseano
You will often see a version number on API queries, such as /api/v2.0/execute or even as a parameter, /api/getuser?v=2.0. Try OLDER versions to see what's changed in older versions!
Resources
A list of useful websites, blog posts, reports tools to help you.Learning to test APIs
Firstly, what is an API? Short for "application programming interface", an API will allow the web application to easily interact with it to perform a defined function. For example, imagine you have the following API endpoints:
/api/getuser
- When queried with an authenticated session, this API endpoint will typically retrieve your profile information and respond with a JSON format, which the web application will then handle. The alternative to this is without an API, your user information may just be reflected in the HTML source, without any additional queries./api/getshippingaddress
- Imagine you are on a shop and you've clicked Checkout, the web application uses an API to retrieve (and modify) information, so when queried with an authenticated session, this API endpoint will respond with your current selected shipping address
An API makes it "easy" for developers to scale web applications with new features as they can directly talk to the API for the information needed, rather than needing to query it from a database and handling the output on each page.
Finding API endpoints
A lot of websites will offer documentation around their API to help third party developers when building third party applications. For example, Twitters API documentation can be found here, https://developer.twitter.com/en/docs/twitter-api. However, this may not always be the case if the API is not intended to be used for public reasons. So where else can we find API endpoints?
Javascript files!
As the web application needs to talk to the API, the endpoints for this must be made accessible to the web application, which also means it'll be accessible for us to find! This is why you will see API endpoints in javascript (.js) files as API requests are usually AJAX requests, which are made in Javascript. Simply scan discovered .js files and endpoints for common keywords such as "/api/", or other keywords relating to the application, such as editing your account information.
You can browse our guide on reading .JS files here.
Fuzzing/Scanning
- Start dorking for common API keywords to see if anything interesting has been indexed: site: example.com inurl:api
. When using the web application if no /API/ queries are made, you could scan for common API directories such as /api/
, api.example.com
. Once you can determine an API exists, then it's a case of mapping out what API queries may be available. (If no information available in .js files or used on web application)
So what can you test an API for?
Developers can make a variety of mistakes when developing APIs and issues affecting them are a lot more common than you think. Below we will explore some techniques of how you can take advantage of APIs to discover security vulnerabilities.
IDORs
- Sometimes when interacting with an API, you will see your userID in the request. This may be an integer or some type of GUID value, however these values are typically always vulnerable and allow you to query other user information from simply changing the userID parameter. As well as being able to query it will also sometimes allow you to modify user information. Check out our Insecure Direct Object Reference (IDOR) to learn more on this.An example of a vulnerability can be seen below from a disclosed report on FirstBlood. You can read the full report here: GUUID is replaceable by an 8 digit number which makes it vulnerable to IDOR
Misconfigured CORS
- As the web application needs to talk to the API this means an AJAX request must be made. The larger the web application, the more complicated an API can become. Imagine the API is onhttps://api.example.com/api/getuser
, but the subdomain,https://superbowl.example.com/
needs to query the API in order to retrieve user information. The API will respond withAccess-Control-Allow-Origin:superbowl.example.com
granting it access to the response.However, if an attacker can use their own domain, then they can retrieve the information themselves! As well as this a misconfigured CORS endpoint may also allow an attacker to use an XSS vulnerability to increase the impact. You can see this on the disclosed finding, Finding XSS on .apple.com and building a proof of concept to leak your PII information
You can easily test for misconfigured CORS by providing
Origin: yourdomain.com
in the request, and looking forAccess-Control-Allow-Origin:yourdomain.com
in the response. You may face some filters with this but can sometimes be bypassed. Check our Cross Origin Sharing guide for bypassing.-
SQL Injection
- The API is designed to execute a query based on your input, which means a database query is likely happening behind the scenes. You can try common SQL injection payloads on API parameters, however keep in mind most SQL injections on APIs will be blind and may only produce Internal Server Error! With this you should try sleep() payloads and monitor the response times. Browse our SQL injection gude here. Broken access control
- As an API is designed to take an input and execute on it, sometimes you can use this to your advantage and increase your account role for example. Imagine the following request:POST /api/updateuser
{"bio":"example"}An API will take the input and execute based on it, so in this case it would update your bio. With that in mind, simply adding
"role":"admin"
onto the request,{"bio":"example","role":"admin"}
, can sometimes cause the API to increase your privileges. This will be due to the API not doing the correct checks on your current user permissions, and simply executing based on user input regardless.Don't forget, an API may also work different to a web application. For example, when posting a video on a bug bounty program I was not able to inject XSS into the Title, however when modifying my video via the API endpoint, I was able to inject XSS, due to different sanitisation. The web application filtered XSS, but the API did not!
As well as updating information, try and read API endpoints you should not be able to! For example, an admin only API may exist at
/api/adminedit
and you should test this on non-admin accounts (normal users). A great example of this was found on our web application FirstBlood and can be seen below. The attacker did not have access when using the web application as a non-administrator, however the API endpoint did not have restrictions!