Skip to content

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Burp Community Extensions Manager

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.

Community-Extensions

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.

What it does

  • Install a Burp extension from a GitHub release asset (.jar) or from a file in the repository tree (.py for Jython, .rb for 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-Extensions and 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 with Auto-update off, 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-update flag 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.

What it deliberately does not do

  • 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-update on 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.com or *.githubusercontent.com, over HTTPS. The GitHub token is only ever attached to api.github.com and github.com, never to the storage hosts an asset download redirects to.

Read this before you install anything

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.

Requirements

  • 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 .py or .rb extensions, a Jython or JRuby standalone jar configured under Settings → Extensions. The manager installs script extensions either way and warns when the interpreter is missing.

Building

The Gradle wrapper fetches its own Gradle and the dependencies; a JDK 17 or newer is all you need installed.

./gradlew build

The loadable extension is build/libs/burp-community-extensions-<version>.jar. It bundles Gson; the Montoya API is compileOnly and comes from Burp at runtime.

Installing the manager itself

  1. Build the jar, or download it from this repository's releases.
  2. In Burp: Extensions → Installed → Add, type Java, select the jar.
  3. 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.

Using it

  1. Add from GitHub — enter owner/repo or a GitHub URL and press Look up.
  2. 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.
  3. Confirm the install. The source, version, file, size and download URL are shown first.
  4. 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.

How it talks to Burp, and why it is careful about it

The Montoya API has no call to load an extension. The only route is importing a configuration fragment, and that import:

  • replaces extender.extensions with 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-update you 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 pathextensions/<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.json

GitHub rate limits

Unauthenticated 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.

Where things are stored

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.

Licence

AGPL-3.0. See LICENSE.

About

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.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages