Interactive pentest toolkit for Bubble.io applications
Project description
bubblepwn
Offensive security toolkit for Bubble.io applications. Covers twelve
modules across reconnaissance, configuration audit, and data extraction,
including a cryptographic bypass on Bubble's internal Elasticsearch API:
knowing the public X-Bubble-Appname header is enough to forge any
request against /elasticsearch/{search,aggregate,msearch,maggregate, mget,bulk_watch} and read any data type without a correctly configured
privacy rule.
Author: @Siin0pe
Based on: Pablo's research on the Bubble.io Elasticsearch crypto flaw
(demon-i386/pop_n_bubble,
GBHackers, April 2025) + independent research into the surrounding
Bubble attack surface.
Elasticsearch crypto bypass
Bubble's SPA encrypts every Elasticsearch request into a three-part envelope
{x, y, z} before sending it. The scheme was reverse-engineered and
published in April 2025 (Lucca & Pedro,
demon-i386/pop_n_bubble,
GBHackers). The entire
derivation collapses onto a value that every client receives in plaintext —
the appname slug:
- Cipher: AES-256-CBC with PKCS7
- KDF: PBKDF2-HMAC-MD5 with 7 iterations and
appnameas salt - Constant IV seeds
po9andfl1, identical across every Bubble app - No authentication on the endpoint itself
The server therefore accepts any forged triple, and the response comes back in plaintext JSON. Bubble has not issued a patch.
bubblepwn rewrites the primitives from scratch (no dependency on the
unlicensed reference PoC) and wraps them in an interactive CLI focused on
three use cases:
- Prove the exploit on a live target (
es-audit probe). - Measure the blast radius by counting records on every data type
through
/aggregate— one round-trip per type, ~56 bytes per response (es-audit analyze). - Exfiltrate data by paginating
/search(es-audit dumpone,es-audit dumpall).
The crypto primitives are also exposed as utilities — decrypt a captured
triple, encrypt an arbitrary payload, query any ES endpoint with a
custom JSON body. See docs/crypto.md for the full
protocol specification and docs/modules.md
for the module reference.
Everything else
Eleven more modules cover the rest of the Bubble attack surface:
fingerprintcaptures theappnameand the session tokens.datatypesenumerates everycustom.*type discoverable in thestatic.jsbundle.secrets,config-audit,plugin-audit,api-probe,files,workflowscover adjacent attack surfaces (tokens in bundles, misconfigured workflows, open/fileupload, etc.).
Every finding lands in a single Context and can be exported as a
structured report (Markdown / HTML / JSON).
Install
Requires Python 3.11+. Three install paths, pick the one that matches your
setup. All of them install a bubblepwn console script on PATH so you can
run the tool from any directory inside the environment.
From a git clone (editable, recommended for development)
git clone https://github.com/Siin0pe/bubblepwn.git
cd bubblepwn
pip install -e .
bubblepwn --version
From GitHub directly
pip install "git+https://github.com/Siin0pe/bubblepwn.git@v0.2.0"
# or the latest main:
pip install "git+https://github.com/Siin0pe/bubblepwn.git"
For the private repo during early access, add your GitHub token:
pip install "git+https://<TOKEN>@github.com/Siin0pe/bubblepwn.git@v0.2.0"
With pipx (isolated environment, binary on PATH)
pipx install "git+https://github.com/Siin0pe/bubblepwn.git"
bubblepwn # launch the shell from anywhere
Verify
bubblepwn --version
bubblepwn modules
Dump artefacts
Reports, checkpoints, ES dumps, and the SQLite rebuild land under ./out/ by
default — run the tool in whichever working directory you want the artefacts
to be written to.
Documentation
docs/cli.md— shell command referencedocs/modules.md— module-by-module referencedocs/workflows.md— recipes and end-to-end sessionsdocs/architecture.md— code map for contributorsdocs/crypto.md— Elasticsearch crypto internals
Quick start — demonstrate the exploit
One-shot proof of exploitability against a live app:
bubblepwn flow crypto https://app.example.com --export out/crypto.html
This runs, in order:
fingerprint— capturesX-Bubble-Appname, session tokens, app flags.datatypes— parsesstatic.jsto enumerate every custom data type.es-audit probe— sends one forged/aggregatecount request; a 200 with acountfield confirms the crypto envelope is accepted.es-audit analyze --field-leak— counts records on every type anonymously and lists the visible_sourcekeys on exposed types.
The report names every leaking type with its record count and flags sensitive-looking field names (email, siret, iban, token, password, stripe).
Interactive equivalent:
bubblepwn ❯ target https://app.example.com
bubblepwn ❯ flow crypto
bubblepwn ❯ report out/crypto.html
Interactive shell
bubblepwn # launch the shell
Typical session:
bubblepwn ❯ target https://app.example.com
bubblepwn ❯ session load session.json # optional
bubblepwn ❯ modules # list modules by phase
bubblepwn ❯ help es-audit # show flags + examples
bubblepwn ❯ flow crypto # ES crypto bypass end-to-end
bubblepwn ❯ run es-audit dumpone custom.user # paginate a type
bubblepwn ❯ run es-audit query search '<json>' # forge any ES request
bubblepwn ❯ report out/report.html
Modules
| Phase | Module | Purpose |
|---|---|---|
| recon | fingerprint |
Detect Bubble.io; extract appname, session tokens, keys, infra |
| recon | plugins |
Enumerate Bubble plugins (first-party + marketplace) |
| recon | datatypes |
List custom types + fields (static.js + /init/data) |
| recon | pages |
Enumerate Bubble pages via wordlist |
| recon | elements |
Rebuild the UI element tree from dynamic.js |
| recon | secrets |
Scan HTML + bundles for tokens, API keys, URL secrets |
| audit | config-audit |
Security headers + public-editor probe + live/test diff |
| audit | plugin-audit |
Deprecated / leak-prone plugins and hosts |
| audit | api-probe |
Data API + Workflow API surface (meta, obj, wf, swagger) |
| audit | files |
S3/CDN enumeration and /fileupload probes |
| exploit | es-audit |
Elasticsearch crypto bypass: probe, count, dump, forge, encrypt/decrypt |
| exploit | workflows |
Workflow API audit (analyze, invoke, fuzz, compare) |
Flow presets
flow crypto — fingerprint + datatypes + es-audit probe + es-audit analyze
flow recon — passive reconnaissance
flow audit — active probing (GET/OPTIONS only)
flow exploit — es-audit + workflows
flow full — recon + audit + exploit
Append --export <path> to write a report at the end. Append
--checkpoint to snapshot findings after each step under
./out/<host>/checkpoints/.
Report formats
report <path> and flow ... --export <path> pick the format from the
file extension:
.md— GitHub-flavoured Markdown.html— self-contained HTML with inline CSS.json— full report payload
Environment
| Variable | Effect |
|---|---|
BUBBLEPWN_LOCAL_DUMP=<dir> |
Offline mode. HTTP fetches fall back to files in that directory when a matching path exists — useful for regression tests against a cached mirror. |
BUBBLEPWN_CACHE_DIR=<dir> |
Override the default bundle cache location (~/.cache/bubblepwn/bundles). |
Contributing
Ideas, bug reports, and new modules are very welcome.
- Bug reports / feature requests: open an issue. Include the target context (anonymised), the command you ran, and the output or stack trace.
- New modules: follow the short guide in
docs/architecture.md. The module registry auto-discovers anything dropped intobubblepwn/modules/. - Research notes: the pentest taxonomy in
docs/modules.mdis open to expansion — new Bubble internal endpoints, bypass primitives, or supporting attack surfaces are fair game. - Pull requests: keep them focused, match existing patterns, and add
a one-line entry to the relevant
docs/*.mdwhen user-visible.
The project is intentionally small — ~15 files in bubblepwn/, no heavy
framework. Reading three or four modules is enough to get the conventions.
Disclaimer
Use against assets you own or are explicitly authorised to test. The cryptographic endpoint is public and unpatched, which does not grant the right to exfiltrate data from third parties.
Credits
- Tool design and implementation: @Siin0pe.
- Cryptographic scheme research: Pablo (and Lucca), published April 2025
via
demon-i386/pop_n_bubblewith coverage from GBHackers, Cyberpress, SecurityOnline, and TechNADU.bubblepwnre-implements the primitives independently (no upstream code) and wraps them in twelve additional modules covering the rest of the Bubble.io attack surface. - Additional research: desk research on Bubble's Data API, Workflow API, file storage, plugin ecosystem, option-set leaks, and configuration pitfalls.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bubblepwn-0.2.12.tar.gz.
File metadata
- Download URL: bubblepwn-0.2.12.tar.gz
- Upload date:
- Size: 117.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5d5437cee9adc6d705c5b44b0848cf7f8109c948a1bdbc9c2aaa3b114713af8
|
|
| MD5 |
5b509749b67f1e0cfde0bcb0c16d5fb6
|
|
| BLAKE2b-256 |
8e72595f9085e41600d4808b3b06b35350d639546f6cabf34b738e5279f51ff4
|
Provenance
The following attestation bundles were made for bubblepwn-0.2.12.tar.gz:
Publisher:
publish.yml on Siin0pe/bubblepwn
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bubblepwn-0.2.12.tar.gz -
Subject digest:
c5d5437cee9adc6d705c5b44b0848cf7f8109c948a1bdbc9c2aaa3b114713af8 - Sigstore transparency entry: 1339301602
- Sigstore integration time:
-
Permalink:
Siin0pe/bubblepwn@5974d26b168fccdc88046dc97a56978018ece28c -
Branch / Tag:
refs/tags/v0.2.12 - Owner: https://github.com/Siin0pe
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5974d26b168fccdc88046dc97a56978018ece28c -
Trigger Event:
push
-
Statement type:
File details
Details for the file bubblepwn-0.2.12-py3-none-any.whl.
File metadata
- Download URL: bubblepwn-0.2.12-py3-none-any.whl
- Upload date:
- Size: 127.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
83a3eaae3a367ddd61fdb876d5482166cd7abcd39364c9420367fac5da344f1f
|
|
| MD5 |
18cab25e4f2375798f149d372ce98fd4
|
|
| BLAKE2b-256 |
07888141a7f348fa3ba9c619c1d7fbc6964268d9ca07e3aa61afdbc12fb50b50
|
Provenance
The following attestation bundles were made for bubblepwn-0.2.12-py3-none-any.whl:
Publisher:
publish.yml on Siin0pe/bubblepwn
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bubblepwn-0.2.12-py3-none-any.whl -
Subject digest:
83a3eaae3a367ddd61fdb876d5482166cd7abcd39364c9420367fac5da344f1f - Sigstore transparency entry: 1339301603
- Sigstore integration time:
-
Permalink:
Siin0pe/bubblepwn@5974d26b168fccdc88046dc97a56978018ece28c -
Branch / Tag:
refs/tags/v0.2.12 - Owner: https://github.com/Siin0pe
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5974d26b168fccdc88046dc97a56978018ece28c -
Trigger Event:
push
-
Statement type: