
The Beginners Guide to Writing API Security Tests in Postman
Did you know that Postman includes a sandbox that allows you to write API security tests in Javascript and execute them against your targets?
This sandbox includes a runtime based on Node.js that enables you to build rich positive and negative tests to maximize the potential of your security testing.
It also includes a post-request processing framework through the Chai.js library that allows you to use behavior-driven development (BDD) syntax to create readable test assertions. This becomes quite useful for security testing as you look to taint data to see how the API reacts and responds.
In this article, I will show you the basics of how to write API security tests in Postman.
Let’s get to it!
Adding your first test
Tests can be added at three different points in Postman:
- Against an individual request
- Against an entire collection
- Against a folder within a collection
Postman has an execution order of precedence. The execution order for each request is (i) collection tests, (ii) folder tests, and (iii) request tests.
An API security test script associated with a collection will run after every request, and a test script associated with a folder will run after every direct child request in the folder.
This enables you to reuse commonly executed tests after requests.
Let’s add our first test directly to a request. For the examples in this article, I’ll use an existing Postman collection I have for OWASP’s Completely Ridiculous API (crAPI).
Testing crAPI Community Posts
For our first test, let’s add it to the “Get Recent Posts” endpoint. If we expand the collection to /community/api/v2/community/posts/recent
and select the Tests tab, we can enter our first code snippet.
Let’s make it easy on ourselves. To the right of the Test code editor is a Snippets panel. Scroll down until you see “Status code: Code is 200”. Click it and let Postman insert your first test script for you!
Now hit the Save button to commit your test to the request.
It might look something like this:

Notice how we refer to pm.test().
The pm
object refers to the Postman core sandbox object, which we will be using a lot. Postman includes a complete reference guide to the Postman Sandbox Javascript API here.
Debugging your first test
With your first test written, let’s try it out. Simply hit the “Send” button.
Notice something? It failed.

Actually, that’s by design. The test asserted that the response we got from the API wasn’t the expected success code of 200. We got a 401 response code because we haven’t logged in yet to populate the {{bearerToken}}
variable in the collection.
This might make more sense if we look at the Authorization tab of the request.

So, how could we debug this to find that out?
Postman includes very rudimentary debugging capabilities. The easiest way is to use the log statements, which allow you to write content out to the main console of Postman.
Currently, Postman supports the following log statements:
console.log()
console.info()
console.warn()
console.error()
console.clear()
We can use this to write out the current value of {{bearerToken}}
. So before the first test, let’s dump the variable using the following code:
console.log("Bearer Token: " + pm.collectionVariables.get("bearerToken") );
Notice how we can access the collection variables using pm.collectionVariables.get()
, which we then write to the console.
If we open the console window at the bottom of Postman, we can see the request go out and then dump the variable, which is currently empty.

So what could we do from here? Knowing that we can never run our test properly if we haven’t yet populated that collection variable, we can account for that in its own test code.
This is one way to do it:
pm.test( "Bearer Token exists", function () {
let token = pm.collectionVariables.get("bearerToken");
pm.expect(token).length.greaterThan(0);
} );

That works. However, it’s not a very useful test. Before we can get into that, let’s discuss how you should be thinking about security testing in Postman, and how to organize how your tests are going to work.
Organizing your tests
OK. So this may be an unpopular opinion. And it’s my own. So weigh the advice accordingly.
There is a time and place for positive testing of API endpoints. To me, this is something the developers should be doing to verify that their code is working AS EXPECTED.
I see security testing as something different. It should typically be focused on negative testing, verifying how the API endpoints work when interacted with in ways NOT INTENDED.
What does this mean?
If you watch most tutorials and guidance on security testing in Postman, they usually showcase how to use the Test tab in a request. In many cases, this is directly against the API spec docs.
In my opinion, this is just wrong.
You should never touch the collection representing the API documentation.
Any test scripts written in the API docs collection should use positive testing and demonstrate how the API is supposed to function.
Your API security tests should be in their own collection and structured according to the order and precedence of the vulnerability classes you are testing against.
But why?
Why API Security Tests should be in their own collection
It’s reasonable to question why I believe you should have a dedicated collection for your Security Tests. It comes down to how tests run in Postman and how to leverage the Collection Runner.
Pre-Request Scripts & Post-Request Scripts
The first thing to consider is that when doing security testing, you will want to taint data in weird places. This will usually require multiple iterations and the injection of malicious payloads into the request.
You don’t want to pollute your API docs with pre-request scripts that are intended to potentially make the API work in weird ways, if at all. So by keeping the security tests in it’s own collection, you can keep tainted payloads away from the main testing.
Business Logic Abuse
When you author your API security tests in their own collection, you can leverage how the Collection Runner works and its order of execution. As it runs from top to bottom in sequential order, you can use collection variables to ensure that a previous test sets the stage for future tests.
When testing for potential flaws in an app’s business logic, you can purposely call different API endpoints out of sequence to see how a transaction will occur. For example, you might have an endpoint that expects that an object is detached from an account it references before it can be deleted. But what happens if you purposely try to delete it before that occurs? Would database constraints prevent it? Would the app work in unpredictable ways that the developers may not have accounted for?
You just never know.
By keeping your security tests in their own collection, you can leverage folders to structure complete test scenarios to logically organize different business logic abuse cases independently from one another.
Automated security testing
Postman includes an awesome command line interface (CLI) called Newman, which allows you to run your API security tests manually from the terminal. You can also use this to run as a scheduled task or cron job, or as part of a custom CI/CD pipeline.
More importantly, you can use this to run regression testing against previously found vulnerabilities that your security testing may have exposed.
The point is that there are several different scenarios in which having a dedicated collection for security testing can be helpful.
Using Test collections and folders
Using a custom collection is relatively easy. Create a new blank collection by clicking on the ‘+’ button at the top left of your Postman app, where the Collection Explorer view is.

When prompted, give it a unique name. In this example, I called mine “Security Tests for crAPI”.
Going forward, organize your security test scenarios by way of folders. In our case, let’s create a folder called Security Headers. Right-click on the new collection you made, and select Add folder. Name it “Security Headers”.

Writing your first security test
With our new collection created, let’s start by setting up a collection variable called baseURL.
Click on the collection name and then click the Variables tab. Create a new variable and set it to your target’s URL. Remember to hit the “Save” button to commit it.

For our first test, let’s verify that the web server sets the correct headers that may impact security.
Normally, you would follow the guidance from the OWASP Secure Headers Project to determine the correct security headers to add and the response headers to remove. However, in this example, we will just add a couple to get you comfortable in writing test scripts.
- Right-click on the “Security Headers” folder and select “Add request.”
- When prompted, give it a descriptive name like “Check security headers.”
- In the URL field, enter the name of the collection variable you set. ie: {{baseURL}}.
- Hit Send and make sure the request works.
It might look something like this:

Add your first test script
Now that we have a working request let’s add a test. Click on the Tests tab.
For our first API security test script, let’s ensure that the web server prevents information disclosure by removing headers that may show the tech stack in use. The first such header is the Server header.
The test may be as simple as:
pm.test('Check if Server header is present', function () {
pm.expect(pm.response.headers.get('Server')).equal(undefined);
});
Now, to test this quickly, hit Send.
Uh oh. crAPI is telling us it’s running on “openresty/1.17.8.2”.

Now don’t go and get excited here. This is more of an informational finding than anything else… unless there is a P1 crit CVE for openresty I’m unaware of. But you can see the process here… we can look for the existence or absence of headers pretty easily.
Let’s add onto this.
Add your second test script
In this day and age, APIs should be forcing clients to use HTTPS whenever possible. The Strict-Transport-Security header (often abbreviated as HSTS) is designed to do just that. It is a more secure option than the traditional method of using 301 redirects from HTTP to HTTPS.
The header has to include a max-age parameter, which is what we can check for.
The API security test may be as simple as:
pm.test("Check for Strict-Transport-Security header", function() {
const header = pm.response.headers.get("Strict-Transport-Security") || ""
pm.expect(header.toLowerCase()).contains("max-age")
});
Let’s test it.
Damn. This deployment of crAPI isn’t passing that either.

Although these tests are failing (as they should at this point), I think you get the idea. If you believe a header should or shouldn’t be there, you can use this methodology to test for it.
Now that we have our test, let’s improve how we run them.
Running your security tests
While you can easily hit the Send button and run our tests against a single request, imagine that we created a whole bunch of other security tests. Maybe you have a test suite that checks for the behavior of access tokens as part of authentication and authorization, where you might have several test cases like:
- Missing access token
- Valid access token
- Expired access token
- Tampered access token

As you can imagine, there could be dozens of different tests. It’s inefficient to walk through each test manually if you want to run them all.
This is where the Collection Runner comes in.
Running your security tests with the Collection Runner
The Collection Runner enables you to run the requests in a Postman Collection in a specified order to test the functionality of your API. The Collection Runner will log the test results for each request, and it can use scripts to pass data between requests and change the request workflow.
To execute a run, right-click on the collection’s name and select “Run collection.” If you want to run just a subset of tests against a particular folder, right-click on an individual folder and select “Run folder.”

You will be presented with the Runner config screen. Here, you can (de)select any tests you don’t want to execute and make any configuration changes as needed.
The defaults work pretty well, but you might want to make changes to delay requests and persist response data for the session.

Once you are ready to start a test run, hit the orange button that says “Run Security Tests for crAPI” (or whatever you named your collection) and watch all the tests execute and report back on their status in the results pane.

It’s that easy.
Now let me show you another way…
Running your security tests with newman
Running your API security tests with the Postman desktop app is nice, but what if you want to run this as part of an automated process? This could be useful if you want to insert security testing as a guardrail in the CI/CD pipeline for deployment of the API if you are working internally within a company.
Or, if you are working externally, this might be something you run on a scheduled basis to test the API regularly to look for changes and regressions. Whatever the motivation, let me show you how to run this from the command line.
Before we can do that though, we need to export our collection and any variables tied to it.
How to export your collection
To export your security tests collection, right-click on the collection name and select “Export”.

When prompted, choose to export in the latest version of the collection format (v2.1 currently) and hit the Export button. This will prompt you to save the file with a JSON extension. I called mine sectests.json.

TIP: When completing the export, the JSON file will contain any variable values set in the “Initial value” column. All “Current value” data is ignored to help prevent information disclosure and leakage. However, since you will want to run the collection locally, you will either need to update the values in the JSON file or produce an environment in Postman and export that, too.
For simplicity, I will update the collection JSON. However, it is more desirable to use Postman environments in a production environment where sensitive tokens, keys, and credentials may be used.
I’ll show you how to execute both.
Using newman
Let me show you a basic way to run newman interactively from the command line:
newman run sectests.json

This is a nice and quick way to run things and see results outputted to the screen.
Now let me show you a typical way I run newman and then explain the parameters I use:
newman run sectests.json -r json --reporter-json-export sectests-results.json
The parameter flags are as follows:
- -r json : Instead of writing results to the console, use the reporter that exports results to a JSON file
- –reporter-json-export sectests-results.json : Sets the name of the exported results file.
If you wanted to load in a Postman environment as part of your test execution, you would use the -e flag:
newman run sectests.json -e sectests-env.json -r json --reporter-json-export sectests-results.json
At this point, you have the results in a JSON file. We can easily parse that with a JSON parser like jq:
cat sectests-results.json | jq -r '.run.stats.assertions'

You can see it lists the number of assertions inside of all the tests, and how many of them failed.
If you only wanted to get the count of the number of assertions that failed and use a non-zero value to alert you, parsing that out is as easy as:
cat sectest-results.json | jq -r '.run.stats.assertions.failed'

Conclusion
This article has turned out to be a bit longer than I expected. However, you can see the groundwork we are creating here. It is possible to set up a dedicated collection in Postman to build and execute your custom API security tests in the order and manner you see fit. You can export that work and even run it outside of that environment in an automated manner, giving you the most flexible environment to validate the security of the APIs you are testing.
It is worth the time to learn how to set this up and run it properly. I hope this guide gives you a glimpse at what is possible.
Hack hard!
One last thing…

Have you joined The API Hacker Inner Circle yet? It’s my FREE weekly newsletter where I share articles like this, along with pro tips, industry insights, and community news that I don’t tend to share publicly. If you haven’t, subscribe at https://apihacker.blog.
The post The Beginners Guide to Writing API Security Tests in Postman appeared first on Dana Epp's Blog.
*** This is a Security Bloggers Network syndicated blog from Dana Epp's Blog authored by Dana Epp. Read the original post at: https://danaepp.com/the-beginners-guide-to-writing-api-security-tests-in-postman