GraphQLScoper
Like many bug hunters, I’ve always relied on Burp Suite’s Scope feature to keep my testing organized. My usual approach is simple: define the target URIs in scope, and once I’ve thoroughly tested an endpoint, I move it to the Out of Scope section. It’s an effective way to cut down on clutter in my HTTP History and keep my focus laser-sharp.
But this URI-based scoping method hits a brick wall when you’re dealing with modern, API-heavy applications, especially those built on GraphQL.
The GraphQL Scoping Challenge
In a traditional REST API, every different action (like GET /users, POST /users, PUT /products/{id}) has a unique URI. Scoping by URI works perfectly.
However, with GraphQL, things are different. Often, all requests — whether they are data-fetching queries or data-modifying mutations — hit the exact same endpoint, typically something like /graphql or /api/graphql.
This means that my old scoping trick fails, and I get stuck seeing the same URI over and over:
Whenever I see the same traffic request flood my history tab, I can practically hear it say: “Oh, you again!”
If I move
/graphqlto "Out of Scope" after testing one mutation, I lose visibility on all other queries and mutations that use the same URI!
If you’re testing a product with a small number of requests, you might be able to manage them one by one. But when the traffic is high, trying to manually track which operation you’ve tested becomes a nightmare. You end up wasting time sifting through history or, worse, re-testing things you already looked at.
Scoping by GraphQL Operation
I started thinking about building a Burp extension to filter and scope based on the GraphQL operation name (the query or mutation name inside the POST body) instead of just the URI.
But then I remembered a powerful, built-in feature I hadn’t properly utilized: Burp Suite’s Bambda Scripting.
Why build a whole extension when I can use a short, elegant Bambda script to solve this specific, high-traffic problem?
My Bambda Scripting Idea
The GraphQLScoper script's primary role is to filter (hide) unnecessary requests from your Proxy History, combining traditional scoping with highly specific GraphQL exclusion.
- Enforce Scope: It strictly enforces the
IN_SCOPE_URLSarray, hiding anything that isn't your target domain. - Hide Static Assets: It filters out common file extensions (
.png,.js,.css, etc.), cleaning up the history view dramatically. - Operation-Based Exclusion (The Core Feature): This is the key solution for GraphQL. When the script sees a POST request body:
- It checks the request body against the strings defined in the
EXCLUDED_OPERATIONSarray (e.g.,"operationName":"Example"). - If the request body contains one of these excluded operation strings, the script will hide that request.
In short, once you finish testing the login mutation, you add "operationName":"login" to the EXCLUDED_OPERATIONS list like this ("\"operationName\":\"login\""), and you'll never see that noise in your history again—even though the main /graphql URI remains in scope for all other operations!
Walkthrough
This guide will show you how to set up the GraphQLScoper Bambda script to manage and filter GraphQL traffic specifically for a PortSwigger Web Security Academy lab.
Get bineeg’s stories in your inbox
Join Medium for free to get updates from this writer.
The first step is to get the script into Burp Suite.
- 1.1. Download/Copy the Script: Ensure you have the final version of the
GraphQLScoperscript code saved locally. - 1.2. Import into Burp:
- Open Burp Suite Professional.
- Navigate to the Extension tab.
- Select the Bambda Library sub-tab.
- Click the “Import script” button
- Load the
GraphQLScoperscript file .
Requests in a proxy before applying the script.
Click on the filter, select Script mode, and load our script.
Modified the part of script like the below , now we will only see traffic from web-security-academy.net
var IN_SCOPE_URLS = new String[] {
"https://id.web-security-academy.net"
};If you don’t want to see the /academyLabHeader in the proxy, add this URI to the OUT_SCOPE_URLS.
var OUT_SCOPE_URLS = new String[] {
"/academyLabHeader"
};Consider this: if I tested the getBlogSummaries operation, I no longer want to see this operation in my proxy history. Therefore, I modified the relevant part of the code as shown below.
var EXCLUDED_OPERATIONS = new String[] {
"\"operationName\":\"getBlogSummaries\""
};You can modify the script directly within Burpsuite on the Script mode.
I’m confident this will make my GraphQL assessments much more efficient. If you’ve been grappling with this same scoping headache, I encourage you to look into Bambda scripting for a quick fix! And if you know of a better existing tool or approach I might have missed, please drop a comment below .
Time to wrap up now. I’ll definitely be back soon with more write-ups and ideas. Happy hunting!








