Improve your API Security Testing with Burp BCheck Scripts

Improve your API Security Testing with Burp BCheck Scripts

Introduction

I’m a big fan of Burp Suite. In my Beginner’s Guide to API Hacking, I even go so far as to outright state you should BUY Burp Suite Professional if you are going to get serious about API security testing.

Today, I am going to showcase WHY I believe that.

It’s because of continuous improvements and new features being developed that help us improve our tradecraft, like in the latest release (v2023.6), which includes a new feature called BCheck Scripts.

By the end of this article, you will learn how to improve your API security testing through a new form of automation that can help rapidly speed up your testing methodology through simple scripting.

Let’s get right to it.

What are BCheck Scripts?

BCheck Scripts are an artifact of an extension for Burp Suite Professional that allows you to write and execute simple scripts that can be used as part of your security testing methodology.

These scripts usually end in a .bcheck file extension and follow a very specific definition reference. You can see the documentation here.

The script language is easy to learn if you have any basic programming experience, and it allows you to inject special application security tests into the regular flow of your API testing process. This is done by executing the scripts on top of Burp Suite’s powerful web vulnerability scanner engine.

The scripts are written in a language called BCheck Scripting Language (BSL). This scripting language supports a wide range of features that allow you to control Burp Suite and perform various actions, such as:

  • Performing automated requests
  • Checking responses for expected results
  • Interacting with Burp Collaborator (for all that fun OAST SSRF stuff)
  • On discovery of potential input insertion points, programmatically deliver your own injection payloads into it
  • Log issues detected in the advisory dashboard and include full details and remediation recommendations

These features allow you to automate many of the tedious tasks normally associated with API security testing, such as validating inputs or checking for unexpected tokens in the response. This can help speed up your testing process significantly.

Here’s a great BurpSuite Short from the PortSwigger crew on using BChecks:

Benefits of BCheck Scripting

By far one of the biggest benefits of BChecks is that they are much quicker and easier to write than a custom BApp extension. Especially when you want to add something simple to a scan check.

You can check out Portswigger’s GitHub repo to get a feel for what a BCheck script looks like. However, an even better way would be to tailor a few real examples that you might use as part of the day-to-day hacking of your APIs.

So let’s go have some fun.

A real example: Auditing for missing Authorization headers

OK, consider this scenario. You have an API that you always expect to require an Authorization header in any request. You want to see if any of your endpoints work without needing an Authorization header.

Let’s write a BCheck script to detect that.

Scaffold your first .bcheck script

You can write your bcheck scripts in whatever text editor you like. However, I will show you how to use Burp’s built-in BS Code editor.

Ya, it’s called the BS Code editor. No BS. 🤣

You can find it by following these steps:

  1. Clicking on the Extensions tab
  2. Clicking the BCheck subtab
  3. Clicking the New button

It will prompt you to select a BCheck template to use. As we are going to write one from scratch, you can choose whichever one you like, as we will be deleting all the content anyways.

Click the “Create using this template” button, and delete all the content. It should look something like this:

Every script includes a mandatory metadata block. It provides information about the script. The only mandatory property you have to include is the “name.” This is displayed in the Burp Suite UI when the check reports an issue.

I recommend that you also include the following properties:

  • language: The version of the BCheck definition language used. Currently, this is v1-beta.
  • description: A description of the script.
  • author: Your name.
  • tags: Identifying tags.

Here is the metadata block for our first script:

metadata:
     language: v1-beta
     name: "Possible missing Authorization header"
     description: "Tests potential API calls that don't have an Authorization header"
     author: "Dana Epp"
     tags: "CWE-864"

Writing your first .bcheck script

Now that the metadata is defined, we can add some meat to the script.

Every check script must contain a given / then statement containing one of the following:

  • given response then – The check runs once for each response audited.
  • given request then – The check runs once for each request audited.
  • given host then – The check runs once for each host audited.
  • given any insertion point then – The check runs once for each insertion point audited. Burp Scanner also uses this default option if you do not specify an insertion point type (i.e. you use given insertion point).
  • given query insertion point then – The check runs once for each query audited.
  • given header insertion point then – The check runs once for each header audited.
  • given body insertion point then – The check runs once for each set of body content audited.
  • given cookie insertion point then – The check runs once for each cookie audited.

In our case, we will be using given response then. Let me show you all the code, and then I’ll walk you through it.

The Code

metadata:
     language: v1-beta
     name: "Possible missing Authorization header"
     description: "Tests potential API calls that don't have an Authorization header"
     author: "Dana Epp"
     tags: "CWE-864"

given response then
     if {to_lower(base.response.headers)} matches "application/json" then
          if not ("authorization:" in {to_lower(base.response.headers)}) then
               report issue:
                    severity: medium
                    confidence: firm
                    detail: `Possible API call detected without an Authorization header at {base.request.url}.`
                    remediation: "Check to see if the endpoint requires authorization or not."
          end if
     end if

Let’s walk through this:

  • Lines 1-6 are the metadata block. For the tag, I linked it to the actual CWE for reference to others who may be using this script.
  • On line 8, I tell the script I only want to look at responses
  • On line 9, I check only for responses that have a Content-Type of application/json, which is a signal that an API endpoint may be in use. I am checking this against the original base response for this scan check.
  • On line 10, I check to see if the response includes an Authorization header. If not, then I want to report an issue.
  • On lines 11-15, I construct an advisory and report the issue back to Burp.

Notice the string interpolation in the issue detail vs. remediation. When you use backticks, you can insert variables into the string. If you use double quotes, it’s treated as normal literal string output.

With your first script now complete, it’s time to set up your system to run them.

Setup Burp Scanner to test .bcheck scripts

If you watched the Burp Suite Short video I linked to earlier, you may have noticed that Dave mentioned that running BCheck scripts is as easy as running a new scan and selecting “Audit Checks – BChecks Only” in the scan configuration.

He lied.

OK, that’s not fair. It’s just that they forgot to add that to the library in the release of 2023.6. So you can’t… yet. It is expected to be included in a future release.

So here is how you can add your own until they do.

Click on the Dashboard tab and then click the New Scan button.

Now click on the Scan Configuration side tab. In the middle of the screen, select the “Use a custom configuration” radio button and then click the “New …” button. When the fly menu pops up, choose Auditing.

You will now see a new custom configuration for auditing with nothing defined. It will ask you to name it. I suggest something like “BChecks” so there isn’t any confusion or collision when Portswigger finally does add the audit check configuration for BChecks.

Now expand “Issues Reported” and choose the “Select individual issues” radio button. Uncheck every single item except “BCheck generated issue,” which should be right at the bottom.

Once that is done, at the bottom of the window, look for a checkbox named “Save to library.” Check that box and then click the Save button. You now have a dedicated BChecks audit in your scanner library.

Run an audit scan to trigger your .bcheck script

Time to test your BCheck script using the new audit configuration you created.

To quickly test this script, I will purposely scan a vulnerable target, which can be triggered at http://crapi.apisec.ai/workshop/api/mechanic/mechanic_report?report_id=1.

Click on the Dashboard tab and then click the New Scan button.

Under the “Scan details” side tab, add the URL to the vulnerable mechanic report under “URLs to scan.”

Now click on the Scan Configuration side tab. In the middle of the screen, select the “Use a custom configuration” radio button and then click the “Select from library” button. Select the new BCheck scan configuration you built earlier, and then click OK.

At this point, Burp’s web vulnerability scanner will run against your scan configuration in the background. After a few seconds, you should see an issue detected and listed under the Advisory pane on the Dashboard.

Another example: Detecting security.txt

This next example is perfect if you want to detect if a target publishes a security.txt. If you don’t know what that is or why it’s useful to you, read my article on The Security Researcher’s Guide to Reporting Vulnerabilities to Vendors.

Let me show you the code and then walk you through it.

The Code

metadata:
     language: v1-beta
     name: "Security.txt detected"
     description: "Checks to see if a security.txt is published on the host"
     author: "Dana Epp"
     tags: "security.txt"

run for each:
     potential_path =
          "/security.txt",
          "/.well-known/security.txt"

given host then
     send request called check:
          method: "GET"
          replacing path: {potential_path}
     
     if {check.response.status_code} is "200" then
          report issue:
               severity: info
               confidence: firm
               detail: `Security.txt found at {check.request.url.protocol}://{check.request.url.host}:{check.request.url.port}{potential_path}.`
               remediation: "Read security.txt file and make sure you document the contact info and PGP keys (if any)."
     end if

How the code works

In accordance with section 3 of RFC 9116, vendors are supposed to publish their security policies for vulnerability disclosure to /.well-known/security.txt. For legacy purposes, this file may exist at the root of the domain.

  • So in lines 8-11, we set up a variable called potential_path that we can iterate through to check each potential URL.
  • On line 13, we tell Burp we want to run this every time we detect a new host.
  • On line 14, we send a request to check for the file
  • On line 16, we replace the path to the file on each iteration.
  • On line 18, we check if we got a valid response.
  • On lines 19-23, we report the finding if we detect the security.txt file.

Simple code. But now, it will automatically appear in your Advisories if the host publishes security.txt. It will look something like this:

Conclusion

Using Burp BCheck scripts, you can quickly and easily detect potential security issues on your target. You no longer have to rely solely on pre-built automated scans and manual testing. With a few lines of code, you can create custom audit checks that will be reported back to you when running a scan.

By using the framework provided by BChecks, you can quickly and easily create powerful scripts that are both secure and maintainable. So get out there and start writing your own BCheck scripts to improve your security assessment!

Just remember, don’t forget to save it to the library so you can use it again later. Happy testing!

One last thing…

Like what you’re reading? Then join the API Hacker Inner Circle. It’s a FREE weekly newsletter designed for developers, testers, and hackers that helps to level up your API security testing skills and keeps you up to date with the community and my work.

Hope to see you there!

Dana Epp

Discover more from Dana Epp's Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading