On the latest API pentest, fintech service every request requiredHMAC-signature in the title X-Signature - calculated from the body,current timestamp and session secretion obtained duringauthentication. No single plugin from the BApp Store supported thisscheme: Repeator sent queries with a non-valid signature, Intruderwashed uselessly at 401. Two hours for a custom extension with anautomatic re-signature - and we saved a week of manual fuss withPostman.
BApp Store (BurpApp Store) - Extension Store for Burp Suite
When standardfeatures are lacking, the development of Burp Suite extensions ceasesto be a whim and becomes the only working option. Below is thespecific path from zero to working JAR to the Montoya API, with theoverlap of the Python approach and its limitations.
HMAC signature -In cryptography, one of the mechanisms for verifying the integrity ofinformation, ensuring that data transmitted or stored in anunreliable environment has not been changed by outsiders.
Burp Suiteenlargement site in the web pentest chain
Exploration(Vulnerability Scanning, T1595.002Reconnaissance). Extensions likeParam Miner automatically detect hidden GET/POST parameters, titles,and Cookies. PortSwigger Scanner does not know the business logic ofa particular SPA and misses custom entry points. Write the BurpPython extension to override specific parameters - half an hour ofwork, and at the output - dozens of hidden points ends, which Scannerdid not see.
Initial access(Exploit Public-Faction Application, T1190) The caste passive scannerdetects mys configurations specific to the target application: CORSwith a reflection of an arbitrary Origin (OWASP A05:2021 - SecurityMisconfiguration), non-standard injection points in proprietary queryformats (OWASP A03:2021 - Injection), weak cryptographic schemes oftokens (OWASP A02:2021 - Cryptographic Failures) The standard Scannerchecks typical patterns. Kastomny is what the pentist knows.
Credential access(Brute Force, T1110; Steal Web Session Cookie, T1539) Multi-stageauthentication with CSRF-tokens, OTP and custom waist-response is anightmare for Intruder in wastewater mode. The Stepper extensionallows you to build a chain of queries with the transmission ofparameters between the steps, and the custom HtpHandler cantransparently update the session token at each request. Intruder andRepeater work as if the session is immortal.
Typical situation:you are on the internal pentest, you have a web interface formanaging infrastructure with custom authentication. The standardIntruder can not twist the login, because every request requiresfresh CSRF-token. Kastom expansion solves the problem in a couple ofhours of development - and all the remaining time goes to operation,and not to fight the tool.
[Applicable:external and internal web application captest, API testing, bugbounty]
Montoya API orLegacy Extender API: what to choose in 2025
A critical factthat all Russian-language guides miss on the topic: according to theofficial PortSwigger documentation, The legacy Extender API is nolonger supported. Quote: "The Extender API is maintained nolonger actively"“Extender API is no longer supported”(portswingger.net/burp/documentation/desktop/extopen/exptensions/creating).All publications on Habra and in Russian-language blogs describingthe development through IBurpExtender and IScannerCheck, use an APIthat will not be corrected or new features.
Montoya API -complete replacement. Single entry point - interface MontoyaApi with24 access methods: http(), proxy(), scanner(), intruder(),repeater(), logging(), userInterface(), utilities(), collaborator(),websockets() and even ai() for AI-integration in the Professionalversion (according to javadoc PortSwigger). For comparison: in thelegacy of the API had to tinker with IBurpExtenderCallbackswhereevery interface (IScannerCheck, IHttpListener, ITab,IMessageEditorController) was recorded in a separate challenge andinteracted with others through non-obvious chains.
Montoya API workswith immutable query and response objects - methodwithUpdatedHeader() returns a new specimen, and does not mutate theexisting one. This eliminates the whole race condition class in theparallel operation of Intruder.
What appeared inMontoya and what is not in the legacy: working with HTTP/2kettled-claims, integration with LLM through ai()Bambdas and BChecksas alternative extensibility mechanisms, enhanced support forWebSockets.
Python, Java orBamdas: a selection table for web pen-pentest automation
Before opening anIDE, determine the scale of the task. PortSwigger offers three levelsof customization, and not every task requires a full expansion:

PortSwiggerRecommendation is unambiguous: Java with Montoya API - the main wayfor Burp Suite Development API. Kotlin is compiled in JAR and loadsas a Java extension. Python through Jython is appropriate fordisposable scripts and the migration of the existing codebase – butnot for new projects.
Bamdas (Javafragments working directly in Burp) close the tasks of filtering andmodifying traffic without project infrastructure. BChecks (DSL forscan checks) replace passive scanners for typical checks. A fullextension is needed when you need a custom UI, integration withexternal services, complex multi-stage logic or working with multiplecomponents of Burp at the same time.
We are writing anextension in Java with Montoya API
Adjustments to theenvironment
• OS:Windows, macOS, GNU/Linux - no restrictions
• JDK: Java21 (Burp does not support Java extensions above 21 - explicitrequirement in PortSwigger documentation)
• IDE:IntelliJ IDEA Community Edition (free, recommended by PortSwigger) orany IDE with Gradle support
• BurpSuite: Community or Professional, version 2024.x+ with Montoya APIsupport
• RAM:minimum 4 GB for simultaneous operation of IDE + Burp, recommended 8GB
• Network:Internet is needed for the initial loading of Gradle-adminis; furtherdevelopment - offline
• Assembly:Gradle (included in the starting project, no need to put separately)
Entry point:Extension.java from the start of the project
PortSwiggerprovides a ready-made launch project - downloaded directly from Burp:Extensions -> APIs -> Download starter project. The projectcontains build.gradle.kts with dependence on Montoya API, filesettings.gradle.kts and Extension.java - the only file you need totouch at the start.
Minimum expansionentry point (from the official PortSwigger documentation):
Three things topay attention to. implements BurpExtension - the interface that tellsBurp that it is an extension in front of it. initialize(MontoyaApimontoyaApi) is caused upon download - here there is a registration ofall handlers. @Override guarantees a compilation error when typing inthe method name - without this annotation, Burp will silently ignorethe extension, and you will guess for half an hour of reasons whynothing works.
Assembly:./gradlew jar at the root of the project. Result - JAR inbuild/libs/, loaded into Burp via Extensions -> Installed ->Add. From downloading the template to the first "Hello, Burp"- 15 minutes.
From 2025, a fileappeared in the start-up project CLAUDE.md - prepared product forgenerating extension code via LLM (Claude Code). PortSwiggerrecommends using it for prototyping, but with a mandatory rector ofthe result. The file contains the context of the Montoya API andextension patterns, so LLM does not hallucinate non-existent methods.For other LLM content CLAUDE.md and folders docs/ can be transmittedas part of the context window.
Python throughJython: When the legacy is acquitted
Python extensionsof Burp Suite work through Jython - JVM-realization of Python 2.7.Restrictions are hard: no Python 3, no requests, no asyncio, noaccess to the Montoya API. Extensions use legacy Extender API withinterfaces IBurpExtender, IScannerCheck, IHttpListener.
Two cases whereJython is still appropriate:
1. A one-timescript is to write a passive scanner in 20 minutes, use on oneproject, throw after a report.
2. Migrationis not possible – the team has been using Python extensions writtenin 2019-2022 for years and it is economically unprofitable to rewriteJava.
Settings: in Burp- Extensions -> Options - Python Environment - Path tojython-standalone-2.7.x.jar (downloads with jython.org). Fordebugging - repository burp-exceptions: Turns unreadableJava-traceback species java.lang.RuntimeException
rg.python.core.PyException at burp.fl.a(Unknown Source) in normalAttributeError: 'burp.ul' object has no attribute 'setEsditable'.Without it, a debag on Jython is insane masochism.
The architectureof the passive scanner in Python (logic without full listing, so asnot to produce deprecated patterns): the class inherits IBurpExtenderand IScannerCheck, method doPassiveScan(baseRequestResponse) Receivesa couple of request-response. Through _helpers.analyzeResponse()Respond headlines. Iterage by headlines: if presentAccess-Control-Allow-Origin Reflecting the Arbitrary Origin from therequest and Access-Control-Allow-Credentials: true -CORS-misconfiguration is fixed through custom IScanIssue. This isSecurity Misconfuration (OWASP A05:2021) - a typical find on externalpentests.
This approach isdescribed in several Russian-language materials (Habr, 2021), butwith a reservation: legacy IScannerCheck works with PortSwiggerScanner API, whose behavior changes between versions. For the newproject, a similar passive scanner on the Montoya API is registeredthrough montoyaApi.scanner().registerScanCheck() Behaving morepredictably in the long run.
[Applicable: fastprototyping; when working on a fixed version of Burp (e.g. corporatestandard Burp 2023.x)]
What SOC and WAFsee when Burp extensions see
WAF (ModSecurity,Cloudflare, Wallarm, PT Application Firewall). Extensions for activephases (Intruder with custom payload, Turbo Intruder) leave typicalsignatures: high query frequency from one IP, payload-patter inparameters, anomalous headers. Caste extension can reduce behavioraldetection: randomize delays between requests through Thread.sleep()with variable interval, rotate User-Agent, use upstream proxy for IPdistribution. But it's not bypass WAF in its pure form - if thesignature analysis blocks a particular payload (<script> in theparameter), the extension will not do.
SIEM and accesslogs. Passive extensions (traffic analyzers, passive scanners) do notcreate additional queries - they process data that has already passedthrough Proxy. Expansion with api.http().sendRequest() (activeshipment) generate traffic visible in access logs. With a pentest ofan internal web application for corporate proxy, the SOC will see asurge of atypical queries correlated with your IP and activity time.It is especially noticeable when the extension performs automaticreautrification: a series of POST requests for /login with the rightcreeds in seconds - an anomaly that any SIEM-alert on brote forcecatches.
Collaborator andDNS logs. If the extension uses montoyaApi.collaborator() to checkblind-vulnerabilities (SSRF, blind XSS, Adversary-in-the-Middlescripts - T1557), DNS-requests to *.oastify.com recorded in corporateDNS logs. For projects with OPSEC restrictions - ownCollaborator-server.
Practicalconclusion: passive extensions (CORS scanner, header analyzer) -minimally noticeable. Active (phasizers, brute-force-utilities) -noticeable exactly as the standard Intruder. The caste code givescontrol of timing and payload format, but does not make trafficinvisible.
[Applicable:external pentest via the Internet - maximum relevance; internalpentest with agreed scope - less relevant restrictions]
Debugging andtypical rakes in the development of Burp Suite extensions
The console is themain tool. In the Montoya API:montoyaApi.logging().logToOutput("debug: " +request.url()). Output - Extensions -> Extensions tab ->Output. In Python: sys.stdout = PrintWriter(callbacks.getStdout(),True), then sys.stdout.println(). No IDE-debaggers connect to theexpansion inside Burp directly. The whole debate is through logging.Get used to it.)
Version of Java.Burp supports Java 21 and below. JAR, assembled on Java 22+, will notboot - the error will appear on the Errors tab, but the wording isnot obvious (UnsupportedClassVersionError) I wasting my time twiceuntil I wasged into the habit: before the first assembly. javac--version and sourceCompatibility = JavaVersion.VERSION_21 inbuild.gradle.kts.
Jython import.Python extension does not boot with ImportError - most likely, thepath is not specified Folder for loading modules in Extensions ->Options -> Python Environment. Each module (includingexceptions_fix.py) should be in this directory.
Blocking calls inthe handlers. handleHttpRequestToBeSent() caused synchronously.Severe operation inside (request to the external API, long-termcalculation) blocks all Burp traffic. Decision: CompletableFuture forasynchronous logic, caching results or transferring heavy operationsto handleHttpResponseReceived()where the delay is less critical.
Compatibility oflegacy-extensions. Python-plagins, written in 2020-2021 under Burp2020.x, can work incorrectly in Burp 2025.x. Typical symptom:deprecated-method getToolFlag() returns unexpected values, a passivescanner misses some of the traffic. If the extension is critical,this is the argument for migration to the Montoya API.
Infinite cyclewhen creating UI components. A separate trap from PortSwiggerdocumentation: if ExtensionHttpRequestEditor uses HttpRequestEditoras UI-component at registration HttpRequestEditorProvider, there isan endless cycle of nested editors, and Burp falls. Similar toHttpResponseEditor. On PortSwigger forums, this issue floatsregularly.
Support status:Montoya API is actively updated (javadoc - May 2025, GitHub-Residionburp-extensions-montoya-api of the weekly committees). LegacyExtender API - archive without updates.
From Idea toWorking JAR: Checklist
1. Check theBApp Store - Param Miner, Turbo Intruder, JWT Editor, Stepper,ActiveScan++ cover the typical tasks. Writing your own is worth onlyif there is nothing suitable.
2. Determinethe scale: filter/rule in Proxy -> Bambdas; custom scan check >BChecks; all the rest -> Extension.
3. Choose alanguage: new project -> Java 21 + Montoya API. Disposable script-> Python/Jython + legacy API.
4. Downloadthe start-up project from Burp (Extensions -> APIs -> Downloadstarter project) or cloning examples:portswigger/burp-extensions-montoya-api-examplesonGitHub (15+ ready-made scripts: HttpHandler, scan checks, WebSockets,custom UI).
5. Build anEmpty JAR (./gradlew jar) and download to Burp - to make sure thatthe assembly infrastructure works before writing business logic.
6.Implementing the logic in Extension.java: Register HttpHandlerthroughmontoyaApi.http().registerHttpHandler()or scan check throughmontoyaApi.scanner().registerScanCheck().
7. Test on thetest application (PortSwigger Web Security Academy, DVWA, OWASP JuiceShop - not for combat purpose).
8. Whenplanning on the BApp Store - to study the criteria acceptance beforethe start of development: PortSwigger requires specific code anddocumentation standards.
The whole cyclefrom idea to working expansion for an experienced developer is 2-4hours. For the first time - the day, taking into account the settingof the environment and reading the documentation.
MostRussian-language guides on Burp Suite extension in Python describethe legacy of the Extender API, an approach to which PortSwigger hasstopped supporting. This forms a distorted picture: a novicepentestuster studies IBurpExtender and IScannerCheckwrites theextension on Jython, and in six months discovers that it does notwork after the Burp update. I’ve seen this at least in three teams– each time the reaction is the same: “we just wrote it.”
The transition tothe Montoya API is not a matter of preference, but a matter ofengineering hygiene. Java-expansion with Gradle is collected inreproducible, dislikes through standard tools, accesses all new Burpfeatures including AI and HTTP/2. Python via Jython is Python 2.7 in2025. It works until it breaks. And when it breaks, there is nothingto fix.
BApp Store (BurpApp Store) - Extension Store for Burp Suite
When standardfeatures are lacking, the development of Burp Suite extensions ceasesto be a whim and becomes the only working option. Below is thespecific path from zero to working JAR to the Montoya API, with theoverlap of the Python approach and its limitations.
HMAC signature -In cryptography, one of the mechanisms for verifying the integrity ofinformation, ensuring that data transmitted or stored in anunreliable environment has not been changed by outsiders.
Burp Suiteenlargement site in the web pentest chain
Exploration(Vulnerability Scanning, T1595.002Reconnaissance). Extensions likeParam Miner automatically detect hidden GET/POST parameters, titles,and Cookies. PortSwigger Scanner does not know the business logic ofa particular SPA and misses custom entry points. Write the BurpPython extension to override specific parameters - half an hour ofwork, and at the output - dozens of hidden points ends, which Scannerdid not see.
Initial access(Exploit Public-Faction Application, T1190) The caste passive scannerdetects mys configurations specific to the target application: CORSwith a reflection of an arbitrary Origin (OWASP A05:2021 - SecurityMisconfiguration), non-standard injection points in proprietary queryformats (OWASP A03:2021 - Injection), weak cryptographic schemes oftokens (OWASP A02:2021 - Cryptographic Failures) The standard Scannerchecks typical patterns. Kastomny is what the pentist knows.
Credential access(Brute Force, T1110; Steal Web Session Cookie, T1539) Multi-stageauthentication with CSRF-tokens, OTP and custom waist-response is anightmare for Intruder in wastewater mode. The Stepper extensionallows you to build a chain of queries with the transmission ofparameters between the steps, and the custom HtpHandler cantransparently update the session token at each request. Intruder andRepeater work as if the session is immortal.
Typical situation:you are on the internal pentest, you have a web interface formanaging infrastructure with custom authentication. The standardIntruder can not twist the login, because every request requiresfresh CSRF-token. Kastom expansion solves the problem in a couple ofhours of development - and all the remaining time goes to operation,and not to fight the tool.
[Applicable:external and internal web application captest, API testing, bugbounty]
Montoya API orLegacy Extender API: what to choose in 2025
A critical factthat all Russian-language guides miss on the topic: according to theofficial PortSwigger documentation, The legacy Extender API is nolonger supported. Quote: "The Extender API is maintained nolonger actively"“Extender API is no longer supported”(portswingger.net/burp/documentation/desktop/extopen/exptensions/creating).All publications on Habra and in Russian-language blogs describingthe development through IBurpExtender and IScannerCheck, use an APIthat will not be corrected or new features.
Montoya API -complete replacement. Single entry point - interface MontoyaApi with24 access methods: http(), proxy(), scanner(), intruder(),repeater(), logging(), userInterface(), utilities(), collaborator(),websockets() and even ai() for AI-integration in the Professionalversion (according to javadoc PortSwigger). For comparison: in thelegacy of the API had to tinker with IBurpExtenderCallbackswhereevery interface (IScannerCheck, IHttpListener, ITab,IMessageEditorController) was recorded in a separate challenge andinteracted with others through non-obvious chains.
Montoya API workswith immutable query and response objects - methodwithUpdatedHeader() returns a new specimen, and does not mutate theexisting one. This eliminates the whole race condition class in theparallel operation of Intruder.
What appeared inMontoya and what is not in the legacy: working with HTTP/2kettled-claims, integration with LLM through ai()Bambdas and BChecksas alternative extensibility mechanisms, enhanced support forWebSockets.
Python, Java orBamdas: a selection table for web pen-pentest automation
Before opening anIDE, determine the scale of the task. PortSwigger offers three levelsof customization, and not every task requires a full expansion:

PortSwiggerRecommendation is unambiguous: Java with Montoya API - the main wayfor Burp Suite Development API. Kotlin is compiled in JAR and loadsas a Java extension. Python through Jython is appropriate fordisposable scripts and the migration of the existing codebase – butnot for new projects.
Bamdas (Javafragments working directly in Burp) close the tasks of filtering andmodifying traffic without project infrastructure. BChecks (DSL forscan checks) replace passive scanners for typical checks. A fullextension is needed when you need a custom UI, integration withexternal services, complex multi-stage logic or working with multiplecomponents of Burp at the same time.
We are writing anextension in Java with Montoya API
Adjustments to theenvironment
• OS:Windows, macOS, GNU/Linux - no restrictions
• JDK: Java21 (Burp does not support Java extensions above 21 - explicitrequirement in PortSwigger documentation)
• IDE:IntelliJ IDEA Community Edition (free, recommended by PortSwigger) orany IDE with Gradle support
• BurpSuite: Community or Professional, version 2024.x+ with Montoya APIsupport
• RAM:minimum 4 GB for simultaneous operation of IDE + Burp, recommended 8GB
• Network:Internet is needed for the initial loading of Gradle-adminis; furtherdevelopment - offline
• Assembly:Gradle (included in the starting project, no need to put separately)
Entry point:Extension.java from the start of the project
PortSwiggerprovides a ready-made launch project - downloaded directly from Burp:Extensions -> APIs -> Download starter project. The projectcontains build.gradle.kts with dependence on Montoya API, filesettings.gradle.kts and Extension.java - the only file you need totouch at the start.
Minimum expansionentry point (from the official PortSwigger documentation):
Java:
importburp.api.montoya.BurpExtension;
importburp.api.montoya.MontoyaApi;
public classExtension implements BurpExtension {
@Override
public voidinitialize(MontoyaApi montoyaApi) {
montoyaApi.extension().setName("HMAC Auto-Signer");
montoyaApi.http().registerHttpHandler(
newMyHttpHandler(montoyaApi));
}
}
Three things topay attention to. implements BurpExtension - the interface that tellsBurp that it is an extension in front of it. initialize(MontoyaApimontoyaApi) is caused upon download - here there is a registration ofall handlers. @Override guarantees a compilation error when typing inthe method name - without this annotation, Burp will silently ignorethe extension, and you will guess for half an hour of reasons whynothing works.
Assembly:./gradlew jar at the root of the project. Result - JAR inbuild/libs/, loaded into Burp via Extensions -> Installed ->Add. From downloading the template to the first "Hello, Burp"- 15 minutes.
From 2025, a fileappeared in the start-up project CLAUDE.md - prepared product forgenerating extension code via LLM (Claude Code). PortSwiggerrecommends using it for prototyping, but with a mandatory rector ofthe result. The file contains the context of the Montoya API andextension patterns, so LLM does not hallucinate non-existent methods.For other LLM content CLAUDE.md and folders docs/ can be transmittedas part of the context window.
Python throughJython: When the legacy is acquitted
Python extensionsof Burp Suite work through Jython - JVM-realization of Python 2.7.Restrictions are hard: no Python 3, no requests, no asyncio, noaccess to the Montoya API. Extensions use legacy Extender API withinterfaces IBurpExtender, IScannerCheck, IHttpListener.
Two cases whereJython is still appropriate:
1. A one-timescript is to write a passive scanner in 20 minutes, use on oneproject, throw after a report.
2. Migrationis not possible – the team has been using Python extensions writtenin 2019-2022 for years and it is economically unprofitable to rewriteJava.
Settings: in Burp- Extensions -> Options - Python Environment - Path tojython-standalone-2.7.x.jar (downloads with jython.org). Fordebugging - repository burp-exceptions: Turns unreadableJava-traceback species java.lang.RuntimeException
The architectureof the passive scanner in Python (logic without full listing, so asnot to produce deprecated patterns): the class inherits IBurpExtenderand IScannerCheck, method doPassiveScan(baseRequestResponse) Receivesa couple of request-response. Through _helpers.analyzeResponse()Respond headlines. Iterage by headlines: if presentAccess-Control-Allow-Origin Reflecting the Arbitrary Origin from therequest and Access-Control-Allow-Credentials: true -CORS-misconfiguration is fixed through custom IScanIssue. This isSecurity Misconfuration (OWASP A05:2021) - a typical find on externalpentests.
This approach isdescribed in several Russian-language materials (Habr, 2021), butwith a reservation: legacy IScannerCheck works with PortSwiggerScanner API, whose behavior changes between versions. For the newproject, a similar passive scanner on the Montoya API is registeredthrough montoyaApi.scanner().registerScanCheck() Behaving morepredictably in the long run.
[Applicable: fastprototyping; when working on a fixed version of Burp (e.g. corporatestandard Burp 2023.x)]
What SOC and WAFsee when Burp extensions see
WAF (ModSecurity,Cloudflare, Wallarm, PT Application Firewall). Extensions for activephases (Intruder with custom payload, Turbo Intruder) leave typicalsignatures: high query frequency from one IP, payload-patter inparameters, anomalous headers. Caste extension can reduce behavioraldetection: randomize delays between requests through Thread.sleep()with variable interval, rotate User-Agent, use upstream proxy for IPdistribution. But it's not bypass WAF in its pure form - if thesignature analysis blocks a particular payload (<script> in theparameter), the extension will not do.
SIEM and accesslogs. Passive extensions (traffic analyzers, passive scanners) do notcreate additional queries - they process data that has already passedthrough Proxy. Expansion with api.http().sendRequest() (activeshipment) generate traffic visible in access logs. With a pentest ofan internal web application for corporate proxy, the SOC will see asurge of atypical queries correlated with your IP and activity time.It is especially noticeable when the extension performs automaticreautrification: a series of POST requests for /login with the rightcreeds in seconds - an anomaly that any SIEM-alert on brote forcecatches.
Collaborator andDNS logs. If the extension uses montoyaApi.collaborator() to checkblind-vulnerabilities (SSRF, blind XSS, Adversary-in-the-Middlescripts - T1557), DNS-requests to *.oastify.com recorded in corporateDNS logs. For projects with OPSEC restrictions - ownCollaborator-server.
Practicalconclusion: passive extensions (CORS scanner, header analyzer) -minimally noticeable. Active (phasizers, brute-force-utilities) -noticeable exactly as the standard Intruder. The caste code givescontrol of timing and payload format, but does not make trafficinvisible.
[Applicable:external pentest via the Internet - maximum relevance; internalpentest with agreed scope - less relevant restrictions]
Debugging andtypical rakes in the development of Burp Suite extensions
The console is themain tool. In the Montoya API:montoyaApi.logging().logToOutput("debug: " +request.url()). Output - Extensions -> Extensions tab ->Output. In Python: sys.stdout = PrintWriter(callbacks.getStdout(),True), then sys.stdout.println(). No IDE-debaggers connect to theexpansion inside Burp directly. The whole debate is through logging.Get used to it.)
Version of Java.Burp supports Java 21 and below. JAR, assembled on Java 22+, will notboot - the error will appear on the Errors tab, but the wording isnot obvious (UnsupportedClassVersionError) I wasting my time twiceuntil I wasged into the habit: before the first assembly. javac--version and sourceCompatibility = JavaVersion.VERSION_21 inbuild.gradle.kts.
Jython import.Python extension does not boot with ImportError - most likely, thepath is not specified Folder for loading modules in Extensions ->Options -> Python Environment. Each module (includingexceptions_fix.py) should be in this directory.
Blocking calls inthe handlers. handleHttpRequestToBeSent() caused synchronously.Severe operation inside (request to the external API, long-termcalculation) blocks all Burp traffic. Decision: CompletableFuture forasynchronous logic, caching results or transferring heavy operationsto handleHttpResponseReceived()where the delay is less critical.
Compatibility oflegacy-extensions. Python-plagins, written in 2020-2021 under Burp2020.x, can work incorrectly in Burp 2025.x. Typical symptom:deprecated-method getToolFlag() returns unexpected values, a passivescanner misses some of the traffic. If the extension is critical,this is the argument for migration to the Montoya API.
Infinite cyclewhen creating UI components. A separate trap from PortSwiggerdocumentation: if ExtensionHttpRequestEditor uses HttpRequestEditoras UI-component at registration HttpRequestEditorProvider, there isan endless cycle of nested editors, and Burp falls. Similar toHttpResponseEditor. On PortSwigger forums, this issue floatsregularly.
Support status:Montoya API is actively updated (javadoc - May 2025, GitHub-Residionburp-extensions-montoya-api of the weekly committees). LegacyExtender API - archive without updates.
From Idea toWorking JAR: Checklist
1. Check theBApp Store - Param Miner, Turbo Intruder, JWT Editor, Stepper,ActiveScan++ cover the typical tasks. Writing your own is worth onlyif there is nothing suitable.
2. Determinethe scale: filter/rule in Proxy -> Bambdas; custom scan check >BChecks; all the rest -> Extension.
3. Choose alanguage: new project -> Java 21 + Montoya API. Disposable script-> Python/Jython + legacy API.
4. Downloadthe start-up project from Burp (Extensions -> APIs -> Downloadstarter project) or cloning examples:portswigger/burp-extensions-montoya-api-examplesonGitHub (15+ ready-made scripts: HttpHandler, scan checks, WebSockets,custom UI).
5. Build anEmpty JAR (./gradlew jar) and download to Burp - to make sure thatthe assembly infrastructure works before writing business logic.
6.Implementing the logic in Extension.java: Register HttpHandlerthroughmontoyaApi.http().registerHttpHandler()or scan check throughmontoyaApi.scanner().registerScanCheck().
7. Test on thetest application (PortSwigger Web Security Academy, DVWA, OWASP JuiceShop - not for combat purpose).
8. Whenplanning on the BApp Store - to study the criteria acceptance beforethe start of development: PortSwigger requires specific code anddocumentation standards.
The whole cyclefrom idea to working expansion for an experienced developer is 2-4hours. For the first time - the day, taking into account the settingof the environment and reading the documentation.
MostRussian-language guides on Burp Suite extension in Python describethe legacy of the Extender API, an approach to which PortSwigger hasstopped supporting. This forms a distorted picture: a novicepentestuster studies IBurpExtender and IScannerCheckwrites theextension on Jython, and in six months discovers that it does notwork after the Burp update. I’ve seen this at least in three teams– each time the reaction is the same: “we just wrote it.”
The transition tothe Montoya API is not a matter of preference, but a matter ofengineering hygiene. Java-expansion with Gradle is collected inreproducible, dislikes through standard tools, accesses all new Burpfeatures including AI and HTTP/2. Python via Jython is Python 2.7 in2025. It works until it breaks. And when it breaks, there is nothingto fix.