Interactive pentest toolkit for Bubble.io applications
Project description
bubblepwn
Offensive security toolkit for Bubble.io applications — 12 modules covering reconnaissance, configuration audit, and data extraction, driven from a single interactive CLI. Includes a working implementation of the Elasticsearch crypto bypass publicly disclosed in April 2025.
Author: @Siin0pe · License: MIT
Features
Reconnaissance (read-only, passive)
fingerprint— detect Bubble.io, extractappname, session tokens, API keys, CDN/infraplugins— enumerate Bubble plugins (first-party + marketplace), optionally enrich from the Bubble plugin storedatatypes— list every custom data type and its fields fromstatic.js+/init/datapages— enumerate Bubble pages via wordlist (live +/version-test/)elements— rebuild the UI element tree fromdynamic.jssecrets— scan HTML + bundles for tokens, API keys, URL secrets; verify exposed Google keys
Audit (active, read-only probing)
config-audit— security headers, public-editor check, live vs/version-test/diffplugin-audit— flag deprecated / leak-prone plugins, detect third-party data-leak hostsapi-probe— map the Data API and Workflow API surface (meta, obj, wf, swagger)files— enumerate S3/CDN URLs, test anon access, probe/fileupload, optional type-fuzz
Exploit
es-audit— Elasticsearch crypto bypass: probe, analyze, dump, forge, encrypt/decryptworkflows— audit workflow API, detect anon-reachable and temp-password-leaking workflows
Reporting
- One
Contextcollects findings across every module - Export as Markdown, HTML, or JSON from a single
reportcommand - Optional
--checkpointsnapshots after each step
Install
Requires Python 3.11+.
pipx install bubblepwn
Verify:
bubblepwn --version
bubblepwn modules
Reports and dumps land under ./out/ by default, so run bubblepwn from the
directory you want the artefacts written to.
Usage
Three paths, from simplest to most complete.
1. Quick fingerprint
Single module, one-shot, no state to manage. Good for confirming a target is a
Bubble.io app and grabbing the appname, session tokens, keys, and infra:
bubblepwn run fingerprint https://app.example.com
2. Full audit + report
Run every module (recon → audit → exploit) in the right order and export a structured report:
bubblepwn flow full https://app.example.com --export out/report.html
.md, .html, and .json are all supported — the extension picks the format.
Add --open to pop the report in your browser when the flow finishes.
Shorter variants:
bubblepwn flow recon https://app.example.com # passive only
bubblepwn flow audit https://app.example.com # + active probing
bubblepwn flow crypto https://app.example.com # ES bypass end-to-end
bubblepwn report https://app.example.com out/report.html # alias for `flow full --export`
3. Interactive shell
For iterative work — pick modules, inspect findings, export at the end:
bubblepwn # launches the REPL
bubblepwn ❯ target https://app.example.com
bubblepwn ❯ session load session.json # optional, authenticated session
bubblepwn ❯ modules # list modules by phase
bubblepwn ❯ help es-audit # module-specific help
bubblepwn ❯ flow recon # chain modules
bubblepwn ❯ run es-audit analyze --field-leak # single module with flags
bubblepwn ❯ findings # review what was captured
bubblepwn ❯ report out/session.html
Tab-completion works on commands, modules, and targets. History persists to
~/.bubblepwn_history.
Flow presets
| Preset | Chain |
|---|---|
recon |
fingerprint → plugins → pages → datatypes → elements → secrets |
audit |
fingerprint → plugins → config-audit → plugin-audit → api-probe → files (enumerate / test-public / upload-probe) |
crypto |
fingerprint → datatypes → es-audit probe → es-audit analyze --field-leak |
exploit |
fingerprint → datatypes → es-audit analyze → workflows analyze |
full |
recon + audit + exploit (deduplicated) |
Every preset accepts --export <path>, --open, and --checkpoint.
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). |
BUBBLEPWN_NO_UPDATE_CHECK=1 |
Disable the passive PyPI update check at startup (also auto-skipped when stdout is not a TTY). |
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 protocol
Elasticsearch crypto bypass
Short version: every Bubble SPA encrypts its Elasticsearch requests into a
three-part envelope {x, y, z} before sending them, but the entire derivation
hinges on a value every client receives in plaintext — the appname slug. The
scheme was reverse-engineered and published in April 2025 by Lucca & Pedro
(demon-i386/pop_n_bubble,
GBHackers coverage).
- Cipher: AES-256-CBC + PKCS7
- KDF: PBKDF2-HMAC-MD5 with 7 iterations,
appnameas salt - Constant IV seeds
po9/fl1, identical across every Bubble app - No authentication on the endpoint itself — Bubble has not issued a patch
bubblepwn re-implements the primitives from scratch (no upstream code) and
exposes them through es-audit: probe, analyze, dumpone, dumpall,
query, encrypt, decrypt. See docs/crypto.md for the
full protocol spec and docs/modules.md#es-audit for the
subcommand reference.
Contributing
Ideas, bug reports, and new modules are very welcome.
- Bug reports / feature requests: open an issue with the (anonymised) target context, the command you ran, and the output.
- New modules: follow the short guide in
docs/architecture.md. Anything dropped intobubblepwn/modules/is auto-discovered. - 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 — reading three or four modules is enough to get the conventions.
Disclaimer & authorized use
bubblepwn is an offensive security research tool. Running it implies
acceptance of the terms below.
- Authorized testing only. Use
bubblepwnonly against systems you own or that you have prior written authorization to test (formal engagement, bug-bounty scope, CTF, training lab). - Unauthorized use is prohibited and is the sole responsibility of the end user. The author accepts no liability for it.
- Public disclosure. The Elasticsearch bypass targets a Bubble.io flaw that was publicly disclosed in April 2025 by Lucca & Pedro; this project re-implements the primitives from the public specification independently.
- No affiliation.
bubblepwnis not affiliated with, endorsed by, or sponsored by Bubble Group, Inc. - No warranty. Software provided "as is" per the MIT
LICENSE.
Responsible disclosure
- Vulnerability in a Bubble.io app you discover with this tool: report it privately to the application owner with a reasonable fix window (typically 90 days) before any public disclosure.
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 and wraps them in eleven additional modules covering the rest of the Bubble.io attack surface.
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.22.tar.gz.
File metadata
- Download URL: bubblepwn-0.2.22.tar.gz
- Upload date:
- Size: 132.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1754bd2f84b4c32be9f81fe076687ede5a429ef4be4a2846b69abbaeb5cd0f49
|
|
| MD5 |
5919960ae0ecc3e2d3ab4f0923a56705
|
|
| BLAKE2b-256 |
3eef2e9266d3f4b71a7d2a873b01f4cf75f22dc7c535a80c46c2bcd135a8943c
|
Provenance
The following attestation bundles were made for bubblepwn-0.2.22.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.22.tar.gz -
Subject digest:
1754bd2f84b4c32be9f81fe076687ede5a429ef4be4a2846b69abbaeb5cd0f49 - Sigstore transparency entry: 1343458927
- Sigstore integration time:
-
Permalink:
Siin0pe/bubblepwn@776a9d7e8a5f33179339da87a3421afe340d6ec9 -
Branch / Tag:
refs/tags/v0.2.22 - Owner: https://github.com/Siin0pe
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@776a9d7e8a5f33179339da87a3421afe340d6ec9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file bubblepwn-0.2.22-py3-none-any.whl.
File metadata
- Download URL: bubblepwn-0.2.22-py3-none-any.whl
- Upload date:
- Size: 141.8 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 |
ec26a7ba76a2997720764eee8b94227ff5aa4c32b751dbe4516a8e2f4ce0ea32
|
|
| MD5 |
8717eef0e2ce9351b9947be5cd21f970
|
|
| BLAKE2b-256 |
a152cf80b8ec2f971535418228e0f98f3dc53b653fa2150bd8317971d167bce7
|
Provenance
The following attestation bundles were made for bubblepwn-0.2.22-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.22-py3-none-any.whl -
Subject digest:
ec26a7ba76a2997720764eee8b94227ff5aa4c32b751dbe4516a8e2f4ce0ea32 - Sigstore transparency entry: 1343458991
- Sigstore integration time:
-
Permalink:
Siin0pe/bubblepwn@776a9d7e8a5f33179339da87a3421afe340d6ec9 -
Branch / Tag:
refs/tags/v0.2.22 - Owner: https://github.com/Siin0pe
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@776a9d7e8a5f33179339da87a3421afe340d6ec9 -
Trigger Event:
push
-
Statement type: