How Start-Ups Can Build a Data-Driven Culture
Here’s what you can do now to create a data-driven culture and maintain it as your company scales.
Learn about the most common issues with APIs via manual testing, and how to mitigate these issues for your next penetration test.
API-based applications have taken over the development architecture lately. It is the gateway to the application, the servers they are running on and the data they are processing. As APIs play such an important role, it’s crucial to make sure that these APIs don’t cause any issues to the web application or the organization.
Our focus in the post will be on the security aspects of API testing. We’ll start with understanding what API testing is and why it’s important. Then look into some common challenges with API testing. Finally, we’ll go through some top vulnerabilities found in APIs via manual testing.
API testing is a software testing practice used to evaluate the functionality, performance, and security of APIs. You can test APIs using various methods such as unit testing, integration testing, load testing, etc.
There are 3 main benefits of API testing:
As the scope of this post is security, let’s understand why API security testing is important.
APIs help in exchanging data between the components of an application and between the application and the user. And this can also include sensitive data. If APIs are not secure, then attackers may be able to get access to sensitive data compromising security. Attackers can manipulate APIs to perform malicious actions which could lead to disasters. To avoid all this, you need to test the API to identify security weaknesses and fix them.
Here’s an example of how an insecure API led to scraping data of around 700 million LinkedIn users.
There are two types of APIs: Internal and External. Internal APIs are used by different components of the web application for communication or used by different systems within an organization's network. Internal APIs are inaccessible to external users directly. External APIs are used by users to interact with web applications.
In order to keep your application and organization secure, you need to secure both internal and external APIs. As these APIs are built for different purposes and used by different entities, you need to design tests for internal and external APIs considering different things in mind. For example, rate limiting is an important aspect of external APIs but not so much for internal APIs.
Most APIs can be used to harm business operations. Although you can prioritize which API to test first and what tests to run, it’s crucial to test every API. Sometimes there are hundreds, even thousands of APIs used by an application. This increases the attack surface creating a challenge to test all APIs in time and accurately. In addition to that, keeping up with regular updates to APIs adds to this challenge.
When there are hundreds or thousands of APIs, it is difficult for anyone to remember the details, even the developer. APIs are usually poorly documented making it hard to understand how to call them, and how they work. This makes it difficult to understand how to API test i.e., how to build tests and execute them. And without proper documentation, it’s also possible that some functionalities of the API are not tested due to a lack of awareness.
For example, I built an API to get event information from shared Google calendars at a particular time. As different calendars were created in different time zones, it was also important to cater to daylight saving. Without documentation, it would be difficult for testers to know about this adaption to daylight saving and test it.
There are different types of APIs. Some of the most commonly used ones are GraphQL, SOAP, and REST. Each of these has its own pros and cons. So, an organization might not necessarily stick to using one type of API. Therefore, testing different kinds of APIs adds extra load to understand how they work, build tests accordingly and execute them.
In complex applications, you need to call APIs in a particular sequence for them to work. If the sequence is missed, you won’t get the desired result. Maintaining the order of sequence becomes difficult for complex applications and even more so if multi-threading is used.
Testing is usually done on staging environments. These environments should have seed data so that a tester can simulate real-world behavior. The seed data must be valid so that a tester can look at all the business use cases.
When performing API tests we should ideally be using data that is real-world applicable but not actual data. Not having valid seed data increases the overhead of the overall testing process and can lead to coverage gaps.
Test data management involves several aspects such as having access to the right data for testing, data masking, storage costs, etc. Therefore getting test data management right becomes a challenge.
These are some of the most common challenges faced in API testing. Even with these challenges, one can’t compromise on API testing because they can lead to catastrophic damages. To understand why API testing is crucial, let’s look into some of the top vulnerabilities found in APIs.
Authentication is crucial especially for external APIs to ensure that APIs are not being accessed by users who are not permitted to do so. It’s also important to use strong authentication mechanisms. Attackers can leverage API authentication weaknesses to bypass security or compromise users’ tokens to get access. Credential stuffing is a good example of how attackers can exploit authentication weaknesses in APIs.
Authorization is a system that checks whether an entity is allowed to perform certain actions and either allows or denies the entity to perform that action. A good number of APIs expose object identifier endpoints increasing the attack surface. If you don’t implement strong authorization practices, attackers can manipulate the API request to perform a dangerous action.
For instance, let’s consider the following requests:
The session cookie helps the server authenticate the user. But putting the session in a parameter like this is a terrible practice.
Now let’s look into an example of how poor authorization can result in successful attacks. Let’s say the API to update a user’s email address for their account looks something like this:
Here, the user_id parameter points to the user account to change the email address, the session contains the session cookie, and the new_email is the new email to be updated to the user’s account.
If there’s no strong authorization mechanism, an attacker can change the email address for some other user as follows:
And as the email address is changed, they might be able to take full control of the account.
Parameters play an important role in the application to understand what particular data should be sent back in the response or processed. For example, if you have an endpoint to display the user’s data. Sending a request without a parameter as follows, will not fetch you the desired data.
Depending on how the application is configured, you might get data for all or some users, or nothing at all. But if you have a parameter, you’ll get that specific data:
This would fetch you details for the user with ID 1234.
Sometimes, developers use some values in the request that are stored in the background and are not affected by the legitimate use of the application. For example, a value stored in the hidden field of a form. However, attackers can exploit this to change the values in the API request to bypass security measures or send a dangerous request. They can also take full control of the account by making a password reset request.
APIs focus more on providing data and not so much on how data is presented or filtering data. These aspects are usually taken care of by the client. When developers don’t take enough care of data security, APIs might expose sensitive data.
For example, the UI of a web application might make an API request to get user details and display the name and email address of the user from the API response. However, if the API response contains the full user object as follows:
Even though the UI would just display the name and email address, attackers still get other sensitive information like their credit card number and SSN. For example, attackers can use the card number and SSN to perform more legitimate-looking spear phishing attacks.
Returning excessive data than what is required, especially sensitive information is bad news bears. By exposing excessive data, you’re not just helping the attackers but also bringing regulatory trouble onto yourself.
Flaws in the design of the APIs cause business logic vulnerabilities. These weaknesses are one of the most dangerous API security weaknesses because, unlike some attacks, they can’t be detected by security systems such as WAFs and IDS as they are difficult to detect. What’s worst about this is that attackers don’t need to bypass certain security restrictions in all such attacks.
For example, if an API is used to make an online transaction between A and B. There might be a restriction that the amount field must be an integer. So an attacker can’t change it to a string. However, if there are no security checks, the attackers can change the amount to be sent to a negative integer. For instance, attacker A sends -$500 to receiver B. This might result in the amount being credited to the attacker.
These are some of the most common vulnerabilities/security weaknesses found during manual API testing. If you’re interested in knowing about the overall top vulnerabilities in APIs, check this OWASP list.
Through this post, we learned in brief what API testing is and why it’s important in this era. We went a bit in-depth to understand some common challenges faced in API testing and finally, covered some of the top vulnerabilities found in APIs via manual testing.
Looking at the top vulnerabilities and what would be the consequences if they were exploited, there’s no doubt that API testing should be one of the top priorities for application security. I will end this post by leaving something for you to read to improve the overall security of your application:
Can be easily manipulated without detection if not properly secured.
Digitally signed and can be validated on the server. Manipulation can be detected.
Limited to 4KB.
Can contain much more data, up to 8KB.
Often used for session data on the server-side. The server needs to store the session map.
Contains all the necessary information in the token. Doesn’t need to store data on the server.
Browser cookie jar.
Local storage or client-side cookie.
Here’s what you can do now to create a data-driven culture and maintain it as your company scales.
Read this article to understand the benefits of threat modeling for penetration testing and how Software Secured integrates threat modeling.
No testing strategy is one-size-fits-all. Pentesting in a production environment can provide advantages, though it does come with many risks.
Providing the quality of the biggest names in security without the price tag and complications.
Manual penetration testing
Full time Canadian hackers