A Burp Suite extension that installs and updates other Burp extensions straight from GitHub repositories — the ones that never made it into the official BApp Store.
You give it owner/repo. It finds the release asset (or the script in the repository tree),
downloads it, records its SHA-256, and registers it with Burp. On every Burp start it verifies
what is installed and reports which repositories have published something newer.
It reports. It does not install behind your back — with two exceptions you control: the
per-extension Auto-update flag, off by default, and self-management, described below.
- Install a Burp extension from a GitHub release asset (
.jar) or from a file in the repository tree (.pyfor Jython,.rbfor JRuby, or a committed.jar). - For script extensions it installs the whole repository tree at the pinned commit, not just
the entry point — a Python extension normally imports modules from beside it, and on its own it
fails at the first
import. - Check for updates on startup and on demand, and show what is available.
- Update, reinstall, roll back to a previously installed version, and uninstall.
- Keep the last few versions on disk (three by default) so a bad update can be reverted without a network round trip.
- Verify on every start that installed files are still present and still hash to what was recorded; anything that fails is marked Broken and is never silently reinstalled.
- Notice when a release's asset changes underneath a version that is already installed, and say so instead of treating it as unchanged.
- Manage itself. On first load it installs itself from
creep33/Community-Extensionsand drops the entry you added by hand, so later releases arrive as ordinary updates rather than a manual download. It happens once — the copy Burp then loads lives under the managed directory, which is what stops it from doing it again. Turn it off under Settings if you would rather not. It is adopted withAuto-updateoff, like anything else — managing itself means it can update, not that it will do so unasked. - Install updates without asking, but only where you asked for that. The per-extension
Auto-updateflag is off by default and applies only to extensions you tick. It runs as part of the startup update check, so it needs Check for updates when Burp starts left on; checking for updates by hand reports what is available and installs nothing.
- Build from source. Cloning a repository and running its Gradle or Maven build means executing the repository's build scripts on your machine before you have even looked at the code. Only published artifacts are downloaded.
- Install updates silently. Every install and every update needs an explicit confirmation,
except for extensions you ticked
Auto-updateon and for the manager's own self-management. - Fetch from anywhere but GitHub. Requests, and every redirect hop, must land on
api.github.com,github.com,www.github.com,codeload.github.comor*.githubusercontent.com, over HTTPS. The GitHub token is only ever attached toapi.github.comandgithub.com, never to the storage hosts an asset download redirects to.
Every Burp extension runs inside Burp's JVM with no sandbox. It can read your proxy history — including any credentials, tokens and cookies you have intercepted — read and write your files, and open network connections. Installing an extension from an arbitrary GitHub repository is running a stranger's code with your privileges.
This tool makes that convenient. It does not make it safe.
What it does guard against: silent installs, downloads from anywhere but GitHub, redirects off GitHub, a token leaking to a storage host, an archive that tries to write outside its own directory, and an installed file changing underneath you (the SHA-256 is recorded and re-verified on every start).
What it cannot guard against: a compromised repository, a hijacked maintainer account, a project
that changes hands, or typosquatting of the owner name. The confirmation dialog shows you the
repository and version — reading the release before you accept it is still your job. Auto-update
skips that dialog by design, so turn it on only for projects you would keep trusting sight unseen.
- Burp Suite with the Montoya API (Community or Professional). Built against
montoya-api 2025.5. - Java 17 or newer — Burp's own JRE qualifies; a JDK 17+ is needed only to build.
- For
.pyor.rbextensions, a Jython or JRuby standalone jar configured under Settings → Extensions. The manager installs script extensions either way and warns when the interpreter is missing.
The Gradle wrapper fetches its own Gradle and the dependencies; a JDK 17 or newer is all you need installed.
./gradlew buildThe loadable extension is build/libs/burp-community-extensions-<version>.jar. It bundles Gson; the
Montoya API is compileOnly and comes from Burp at runtime.
- Build the jar, or download it from this repository's releases.
- In Burp: Extensions → Installed → Add, type
Java, select the jar. - A Community Extensions tab appears.
With self-management left on, that hand-added entry is replaced on first load by a copy under the managed install directory, and every later release arrives as an ordinary update — reported like any other, and installed when you say so. Burp reloads its extensions when the swap happens, which is expected; the jar you selected stops being referenced and can be deleted.
The swap only happens if the newest published release is at least as new as the build you loaded, so a jar you built yourself is never quietly replaced by an older one from GitHub. When it is declined or fails, the entry you added stays exactly as it was and nothing is retried for six hours.
With self-management switched off, upgrading stays manual: Burp stores the absolute path of the jar it loaded and the file name carries the version, so you remove the old entry under Settings → Extensions and add the new file.
- Add from GitHub — enter
owner/repoor a GitHub URL and press Look up. - Choose a release and its asset, or switch to File in the repository (.py / .rb / .jar) and pick a file. For releases, the Match future assets with pattern is prefilled from the asset you picked with the version number loosened; edit it if the project names its files unusually.
- Confirm the install. The source, version, file, size and download URL are shown first.
- After the download the SHA-256 of the installed file is displayed and stored.
The hash is shown after the download rather than before it, because GitHub does not publish a digest for release assets — there is nothing to check against until the bytes are here.
The table lists name, repository, type, installed and latest version, status, the Auto-update flag
and whether Burp currently lists the extension. The buttons alongside it are Check for updates,
Update selected, Update all, Roll back, Reinstall, Uninstall, Register with Burp,
Open repository and Settings.
Settings covers the install directory, the GitHub token, whether to check for updates at startup, whether to consider prereleases for new installs, self-management, the maximum download size (200 MB by default), how many versions to keep for rollback (three), and an optional outbound proxy.
They are kept in ~/.burp-community-extensions/settings.json, not in Burp's preferences. Burp scopes
persistence().preferences() to the extension entry it loaded, and a self-update registers a new jar
under a new name, so every release used to start with an empty token and a default install directory.
The file is narrowed to its owner where the filesystem allows it, but the token is still clear text:
use a fine-grained, read-only one. Settings written by an older build are moved across on first run.
The Montoya API has no call to load an extension. The only route is importing a configuration fragment, and that import:
- replaces
extender.extensionswith exactly what it is given — so the payload has to be the complete list, or everything not in it disappears; - makes Burp reload every extension, including this one, so an import is a self-restart;
- deals in entries carrying fields beyond the obvious ones (
bapp_uuid,auto_reload,use_ai), which must be preserved rather than rebuilt.
Getting that wrong cost two incidents on a real profile — one that grew an extension list from 5
entries to 648, and one that cut it down to 1. Both are written up in dev/spike-notes.md, along
with the part that is still not understood.
What the code does about it:
- Burp's list is only written to when you ask. The startup pass — verification, reading the
list, checking GitHub — never modifies it. The exception is self-management, which writes once, at
the end of the first startup, and only after the download has been verified; if anything fails,
the entry you added by hand is left exactly as it was and the attempt backs off for six hours. An
Auto-updateyou ticked installs at startup without asking, but that reuses the extension's existing path and so writes nothing to the list — unless the path itself moved, which is the same case as an update you ran by hand. - Entries the user added are copied through untouched. Only genuinely missing managed entries are added, and the only entries ever removed are managed ones — on uninstall, and the manager's own hand-added entry when it takes over managing itself.
- The result is verified, and rolled back if it is wrong. After every change the list is re-read; if anything is missing, duplicated, or the count is off, the previous list is restored and further changes are blocked.
- A five-second cooldown, a ceiling of twenty changes per five minutes, and a circuit breaker sit in front of all of it. That state lives on disk, because the reload an import causes would wipe an in-memory one. A breaker tripped by an older build is cleared when a new version loads.
- Each extension lives at a fixed path —
extensions/<owner>__<repo>/current/<owner>__<repo>.jar— so it is registered exactly once. Updates and rollbacks replace the file at that path and leave Burp's list untouched. You reload the extension yourself (Settings → Extensions) or restart Burp to run the new code. The one exception is the manager itself: Burp holds the jar it loaded open, so its live file carries the version in its name, each self-update registers the new path and removes the old one in a single write, and the superseded copy is deleted on the next start. - Uninstall removes the entry from Burp first, then deletes the files. That order is deliberate: if the list cannot be updated, nothing is deleted and the extension stays installed. Deleting files while Burp still points at them would leave you with an extension list that errors on every start. Because the removal itself makes Burp reload, an uninstall cut short mid-way is finished on the next start.
If the tab warns that an extension is installed but not listed in Burp, Register with Burp adds it. That button also clears the circuit breaker, after telling you to check the list first.
Given the history: try this against a throwaway profile before pointing it at a Burp you care about.
java -jar burpsuite.jar --user-config-file=/tmp/throwaway-config.jsonUnauthenticated GitHub API access is 60 requests an hour per IP, and each managed extension costs
roughly one request per check. Update checks send conditional requests (If-None-Match), so an
unchanged endpoint comes back as an empty 304 — that saves the transfer and the parse, but GitHub
still counts it against the limit, so it does not buy you extra checks.
What does protect the budget: when fewer than five requests remain the sweep stops early and says
so, rather than spending the rest. Adding a personal access token in Settings raises the limit
to 5000 an hour and allows private repositories — read the warning there first, the token is stored
in clear text in settings.json.
Default ~/.burp-community-extensions/, configurable in Settings:
manifest.json inventory of what is installed
manifest.lock lock file guarding manifest writes
extensions/<id>/current/<id>.jar the file Burp is pointed at, path never changes
extensions/<id>/current/ for script extensions, the extracted repo tree
extensions/<id>/versions/<version>/<original-name> archived downloads, for rollback
backups/extender-<timestamp>.json Burp's extension list before each change
cache/import-guard.json cooldown and circuit-breaker state
cache/etags.json conditional-request cache
logs/community-extensions.log audit log of installs and updates
The manager's own live file is the exception to the fixed path:
extensions/creep33__Community-Extensions/current/creep33__Community-Extensions-<version>.jar.
The manifest on disk is the source of truth and is independent of which Burp project is open. Burp preferences are used only for settings.
AGPL-3.0. See LICENSE.