Fuzzing APIs
Fuzzing or Fuzz testing is an automated testing method where random, invalid, distorted, or unexpected input is given to an API Endpoint to see if any crashes or bugs emerge. The aim of Fuzzing is to identify unknown bugs and defects.
API Fuzzing is a way of API testing that uses an API’s definition to do testing in an automated way. It creates tests based on schemas, runs them, and reports on success and failures. It is not a replacement of functional tests, but it automates the busy work of creating tests that validate the correct behavior based on input and output schemas.
Cybersecurity industry leader Confidence Staveley, in one of her episodes “Balancing Flavors: Proper Asset Management in API Versioning” for her API Security series on youtube (API Kitchen) describes Fuzzing as like pulling a joke on an API by giving it strange and unexpected data to see if it can handle it gracefully; in the same way that you will tickle someone to see if they would laugh or get mad at you. Fuzzing tickles the code of an application to find any secret flaws. It’s a sneaky way to mess with APIs and push it to the limit in order to find flaws that need to be fixed.
In this chapter, you’ll make your first ever hack. I’m going to guide you on how to find a vulnerability via fuzzing.
I recommended in earlier chapters that you should try to use all the functionalities of crAPI before saving them in the crAPI_Swagger_file collection. One particular action I expect you to have taken is to use the “Forgot Password” feature to generate a new password. If you didn’t do that, it is fine because I didn’t also do it, so I can explain it in this chapter. But note that as an API Hacker, you shouldn’t leave anything behind while you’re trying to analyze endpoints.
Now let’s dive right into the technicalities
If you didn’t use the “Forgot Password” feature like me, let’s add the request to our collection first. We’ll use Burpsuite to capture the traffic, then copy and paste it into Postman.
Make sure the proxy is set to port 8080. Then click on “Forgot Password”.
It’ll take you through steps to recover youtr password, follow all the steps till you see the dialogue box below
It’ll prompt you to enter an OTP, you can decide to enter the wrong OTP also like I did here
We’ll copy the request and paste it to Postman. We’ll also need to copy the data and paste it too
The image above is the captured request in Burpsuite. What I want you to take note of is the “Request” section. Notice how the version in this API endpoint is different from all the previous ones. It is using version 3 (v3) while other ones we’ve been dealing with have been using version 2 (v2).
Let me use an example of the most popular messaging app in Nigeria, Whatsapp. One of the new features of Whatsapp is that you can now edit the messages you send, which you cannot do before. Now, let’s assume that the version we were using to send messages before was v2, and the version we are using now is v3.
The cool thing about API versioning is we can tell the exact version just by looking at the API Endpoint. Which is the case with the image above, the version in the API endpoint here is different from what we have been seeing.
So what we want to do with Fuzzing is to explore the changes between these different versions of the API. We should be curious as hackers, to know what is different in v3 compared to v2. This can help us discover any potential weaknesses or vulnerabilities in the way these endpoints are working as opposed to how the developer intends for it to work.
It is very important to pay attention to version differences in API Endpoints, because tiny details matter. If we pay attention to this, we become better at finding any security issues/vulnerabilities.
We’ll right click on our collection, and select “Add Request” to add the new request from Burp
Don’t forget it’s a POST request. Also navigate to the “Body” section, select “raw” and paste the data you copied from the request.
Here is the response below. It says Invalid OTP because I actually imputed an invalid OTP
I sent the request multiple times, almost 10 times, and it gave me the response below: “You have exceeded the number of attempts.” Now I have an inference that maybe the v3 has maybe introduced “Rate Limiting”
RATE LIMITING:
APIs introduce Rate Limiting to prevent abuse of the API. This simply means that the number of request you can make within a particular period is limited. i.e. if you sent a request multiple times like I did above, rate limiting will be triggered.The main reason they do this is to ensure that there is a fair use of the API by the consumers instead of a single person sending too many request within a short time that can overwhelm the server. Rate Limiting also helps prevent abuse of the server
A popular scenario is when X (fka Twitter) around mid July 2023, introduced Rate Limiting. The owner Elon Musk said that some people including LLMs were scraping Twitter data massively and they had no choice but to introduce Rate Limiting. Remember this affected the number of tweets we could send per day.
After I exceeded the rate limits, further requests were giving ERROR response
Next is to start Fuzzing.
Fuzzing an API simply means sending different input values to endpoints to uncover potential vulnerabilities or any unexpected behavior.
First, let’s create an environment. Click on the environment icon at the top right of Postman and click on “Add”. I named the environment crAPI_Swagger
We need to define a variable and also create a key-value pair. Here, my variable is “path” and key-value pair is v3. Don’t forget to save
Next, click on the environment icon again, and make sure you select the environment you just created. The default was “No Environment”
Navigate to the collection, go to the “Tests” tab and paste the following script:
pm.test(“Status code is 404”, function () {
pm.response.to.have.status(404);
});
then right click on the collection and select “Run Collection”
Click on the orange button that says you should Run crAPI_Swagger_file
Notice how all the 14 requests failed
The test scripts we ran earlier checks whether the response status code is 404 (Not Found). When we run the script, it is meant to validate that the response status code matches the expected value. Since all the 14 requests in our collection failed this test, this means that the responses from the 14 requests are not returning the status code 404.
I mentioned earlier that “Fuzzing an API simply means sending different input values to endpoints to uncover potential vulnerabilities or any unexpected behavior.
”. What we did was send a series of requests and check whether it will return 404. If it had return 404, then the behavior is unexpected. But in a scenario where we actually have an invalid request in our collections and send the request, then it does return a 404 response, this response is expected and the application is responding appropriately.
You can also check the actual response code you got. In my case I got 200 (OK success), 401 (Not Authorized), 500 (Server Error) etc.
.Next is to replace
Select all the boxes, then replace with “{{path}}”
You’ll notice that all occurrence of v2 has been changed to {{path}}
We didn’t replace v3, you can do this manually
Next, we’ll run a deliberately failed scan
I changed the current value to invalid419, this is because I’m sure I don’t have any request like invalid419 and I want the scan I want to run to fail
Don’t forget to Save.
Run the collection