APIs are everywhere these days. In fact, they’re responsible for a whopping 73% of internet traffic in 2023, according to the State of API Security in 2024 Report by Imperva. With this level of activity, especially in industries like banking and online retail, securing APIs isn’t just important—it’s essential. The average organization has around 613 API endpoints in production, and as the pressure to deliver faster mounts, that number is only growing.
To keep up with this demand while ensuring security, adopting a ‘Shift-left’ approach is crucial. What does that mean? It means integrating security earlier in the development process—right from the design stage, all the way to deployment. By doing this, you’re not just patching up vulnerabilities at the end but embedding security into the very fabric of your API.
API testing plays a huge role in this approach. You’re essentially poking and prodding at the logic layer of your application, checking how it responds, how fast it does so, how accurately it handles data, and whether it can fend off security threats. This is where Postman shines. It’s a widely used tool that’s loved for its ease of use and versatility, making it a perfect fit for your shift-left strategy.
With Postman, you can simulate attack scenarios, test for security issues, and validate security measures, all within the same space where you build your APIs. But before we dive into scripting in Postman, let’s get it installed.
First things first, if you don’t already have a Postman account, head over to their website to create one. You can sign up using Google if you prefer. Once that’s done, download the version that suits your operating system and get it installed.
We’ll need a vulnerable API to test our scripts, and the BreachMe API in my book (API Security For White Hat Hackers) is perfect for this. You can find it here. Follow the documentation to set it up, and don’t forget to import the BreachMe collection into Postman. Just click the import button in the collections tab, and you’re good to go.
Scripts in Postman are where things get really interesting. They allow you to add dynamic behavior to your API requests, mimicking complex workflows and writing test assertions that simulate real-world scenarios. Postman’s sandbox execution environment is written in JavaScript, This means that in order to make a script executable in Postman, it has to be written in Javascript. So, If you’re familiar with Javascript, you’re already halfway there.
There are two main types of scripts in postman. The first, pre-request script which is run before a request is rendered to Postman. The second, post-response scripts are scripts that are run after Postman gives a response to a sent request. The order of script execution for a single request is as follows:
There are two main types of scripts in Postman:
The order of script execution for a single request is as follows: Pre-request script
You can run these scripts at three levels: the request level, folder level, and collection level. This flexibility means you can apply scripts to individual requests, a group of requests, or even an entire collection.
The execution of these scripts will happen in the following order.
During API testing, you often need to work with various user inputs, which can be tedious to create manually each time. One of the coolest features of Postman scripting is the ability to add dynamic behavior to a request. Imagine trying to manually create user inputs for each test—it would be a nightmare. Postman allows you to automate this process, generating variables like random usernames, random IP addresses, email addresses, and passwords on the fly.
For example, to generate a dynamic username you can use {{$randomUserName}}. Want a dynamic email? Just use {{$randomEmail}}. And for a password, {{$randomPassword}} has you covered. This makes it easy to send multiple requests to the register endpoint, effectively testing the API.
Postman provides everything and we can now send as many register requests as we need to effectively test the API. Dynamic variables can also be set using pre-request scripts.
Postman can be used to perform essential API testing such as functional testing, this is testing to ensure that the API works/functions in the way it is intended to. When testing functionality, postman allows you to send requests to your API endpoints and validate the responses against expected outcomes. You can check if the API returns the correct data, handles inputs properly, and responds with appropriate status codes (e.g., 200 OK, 404 Not Found). Let’s try that in the above API to check if the login endpoint will return a 200 status code. Navigate to the login endpoint’s script tab and choose the post-response tab.
The script we will use will look like this…
Let’s break down the snippet. We’ll use the pm.test() function. The first argument “Status code is 200” will be used as the description of the test. The second argument is a function that will contain the actual test. The pm.response
refers to the response object. .to.have.status(200)
evaluates whether the response status code is 200.
Post-request scripts can be used to set tokens or variables that will be needed throughout the testing of the API. Imagine testing an API and manually copying and pasting variables between requests—tiring, right? This approach ensures the variable is accessible across all requests in the collection, making your testing workflow more efficient, less error-prone, and more secure. Some variables contain sensitive data and may require a bit more protection especially when working in a collaborative environment. Postman recommends using variables in such cases. Let’s take an example of an access token that is short-lived, used by most of the endpoints in the collection, and is set when the login request is successful. To streamline this, we could use a post-response script in the login endpoint to automatically set it. Navigate to the auth folder of the Breachme_API collection and select the login endpoint.
Ensure that the username you are trying to log in as is a registered user but using the register login before the login endpoint. When logging in, you’ll require a correct username and password in the body of the request as shown below. The correct credentials will result in a response containing the token.
To set it, we will need to get the response; take only the token and set it. The script will look like this:
var theResponse =pm.response.json();
pm.collectionVariables.set("access_token", theResponse.token)
The first line of code captures the response from the API request and converts it to a JSON object then stores it in a variable theResponse. The pm.response.json() is a Postman function that parses the response body as JSON, making it accessible as a JavaScript object. With the response accessible, we can then get the token using the theResponse.token and set it as a collection variable with the command pm.collectionVariables.set()
function. The first parameter will specify the collection variable you want to save it as.
Postman scripts can also be used to validate whether the response contains the expected data. Let’s say you have created a post, you would expect it to have the ‘id’, ‘username’, ‘message’, and maybe an ‘image’. You can use Postman to check if every expected data is returned in the expected format. Let’s check if the register endpoint returns what we expect, with the body
{
"username":"user2",
"email":"user2@email.com",
"password":"user2password"
}
We expect the response to look like below
{
"message": "user created successfully",
"user": {
"id": 2,
"email": "user2@email.com",
"username": "user2",
"is_admin": false,
"password": "#############",
"createdAt": "2024-08-28T22:13:30.000Z"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwiZW1haWwiOiJ1c2VyMkBlbWFpbC5jb20iLCJ1c2VybmFtZSI6InVzZXIyIiwiaXNfYWRtaW4iOmZhbHNlLCJwYXNzd29yZCI6IiMjIyMjIyMjIyMjIyMiLCJjcmVhdGVkQXQiOiIyMDI0LTA4LTI4VDIyOjEzOjMwLjAwMFoiLCJpYXQiOjE3MjQ4ODMyMTAsImV4cCI6MTcyNTE0MjQxMH0.Z3fdfRXkePNFoWgX2gSqrTTtOy_AzsnG8yG_wKdnOz4"
}
To automate it, we will use the script in the post-response tab of the register endpoint.
pm.test("User object has id, email, username, is_admin, password", function () {
const responseData = pm.response.json();
pm.expect(responseData.user).to.have.property("id");
pm.expect(responseData.user).to.have.property("email");
pm.expect(responseData.user).to.have.property("username");
pm.expect(responseData.user).to.have.property("is_admin");
pm.expect(responseData.user).to.have.property("password");
});
To ensure that your API meets performance requirements, you can use a post-response script to measure the response time. The snippet we will use us as seen below:
pm.test("Response time is less than 300ms", function () {
pm.expect(pm.response.responseTime).to.be.below(300);
});
The above script uses the pm.test() function with the test description as the first argument and an anonymous function that contains the actual test as the second argument. The pm.expect()
function is a Postman function that is used to make assertions, it sets up an expectation for a certain condition. In this case, it expects that the pm.response,responseTime
will be below 300 milliseconds. Not meeting this expectation makes the test fail.
Scripting in Postman isn’t just about convenience—it’s about transforming your testing into a proactive, security-focused process. By using these scripts, you’re not only automating repetitive tasks but also fortifying your API against potential threats. Combine this with other security measures, and you’ll have an API that’s ready to hold its own in the fast-paced world of software development.
"As you continue to deepen your understanding of API security and testing, consider exploring "API Security for White Hat Hackers" written by Confidence Staveley. This book is a comprehensive guide that simplifies API security by showing you how to identify and fix vulnerabilities. From emerging threats to best practices, this book helps you defend and safeguard your APIs.
Confidence Staveley is a multi-award-winning cybersecurity leader with a background in software engineering, specializing in application security and cybersecurity strategy. Confidence excels in translating cybersecurity concepts into digestible insights for diverse audiences. Her YouTube series, “API Kitchen,” explains API security using culinary metaphors.nConfidence holds an advanced diploma in software engineering, a bachelor’s degree in IT and business information systems, and a master’s degree in IT management from the University of Bradford, as well as numerous industry certifications such as CISSP, CSSLP, and CCISO. In addition to her advisory roles on many boards, Confidence is the founder of CyberSafe Foundation and MerkleFence.