Releases: blacklanternsecurity/badsecrets
Release list
1.2
1.2.0
Major infrastructure overhaul and significant bug fixes for passive detection accuracy.
Breaking Changes
blacklist3rCLI tool removed — the standalone blacklist3r example script has been deprecated and deleted. Use the mainbadsecretsCLI instead.httpx→blasthttp— all HTTP client code migrated from httpx to blasthttp. If you importbadsecretsand were relying on httpx transports or response objects, update accordingly.poetry→uv— build system migrated from poetry/poetry-dynamic-versioning to hatchling + uv. Useuv sync/uv runinstead ofpoetry install/poetry run.check_all_modules()now returns a list (matchingcarve_all_modules's shape), including IdentifyOnly hits alongside SecretFound results.cookie_identify_onlyrenamed toreport_uncracked_cookieson module classes.
New Features
- Docker support — added Dockerfile and
.dockerignore(thanks @vortexau) badsecrets.__version__— version string now exposed at package level- IdentifyOnly results from cookies and manual product mode — cookies and the
badsecrets <product>CLI path now fall back toidentify()whencheck_secret()misses, surfacing recognizable crypto products with unknown keys (e.g. Laravel cookies)
Bug Fixes
- Fix Python 3.13+ test failures: URL-unquote before slicing in PBKDF1/PBKDF2 crypt tests
- Handle PyJWT 2.13.0
InvalidKeyErrorduring JWT secret detection - Fix
A-zcharacter class typo in rack2, rails, and django identify regexes (was matching `[]^_`` characters) - Fix
Telerik_HashKey.get_hashcat_commands: swapped variables and wrong encoding (was base64-decoding the HMAC message instead of hex-encoding raw bytes) - Guard
Rack2.get_hashcat_commandsagainstbinascii.Erroron malformed base64 - Guard all IdentifyOnly
get_hashcat_commandscalls with_safe_hashcatwrapper to prevent malformed cookie values from crashing scans - Suppress cookie false positives from Shiro, PeopleSoft, LTPA, Flask, and Rails modules (broad base64 regexes were matching ordinary cookies like
AWSALB) - Tighten
identify_regexon loose-base64 modules; deduplicate IdentifyOnly results per module - Fix blasthttp body encoding: pass
strnotbytes
Dependency Updates
- blasthttp (new) ≥ 0.8.0
- pycryptodome ≥ 3.23.0
- PyJWT ≥ 2.13.0
- yara-python ≥ 4.5.4
- idna 3.11 → 3.15
- django ≥ 5.2.15
- Various dev dependency bumps (pytest-cov, pytest-asyncio, pytest-mock, respx, dulwich)
Full Changelog: 1.1.0...1.2.0
1.0
badsecrets 1.0.0 Changelog
New Modules
Active Module System
A new active module architecture that sends probes to live targets to detect default/known secrets server-side. Modules are organized into passive/ and active/ subdirectories.
- GlobalProtect - Detects Palo Alto GlobalProtect portals using default master keys
- Shiro RememberMe (active + passive) - Detects Apache Shiro instances using known encryption keys (1,122 known keys)
- IBM LTPA Token (active + passive) - Detects IBM WebSphere servers using known LTPA keys (338 known key sets)
ASP.NET Resource Token
- New ASPNET_Resource passive module for detecting known machine keys via WebResource.axd / ScriptResource.axd encrypted URL tokens
MAC_DISABLED ViewState Detection
- Detect and report ASP.NET ViewStates with MAC validation disabled (a critical misconfiguration), including null-padded variants
New Features
- YARA pre-filter for carve scanning - Massively speeds up body carving by using YARA rules to pre-screen HTML before running expensive crypto checks
- Inline ViewState parser - Replaced the external viewstate library with a lightweight skip-only parser, removing a dependency and improving performance
- --list-modules CLI flag - Lists all available modules (passive and active) in a formatted table
- --custom-secrets CLI flag - Unified interface for passing custom secret material to any module
- Auto-follow trailing-slash redirects in CLI URL mode
- ViewStateUserKey support - Included in DOTNET 4.5 KDF purpose strings for proper key derivation
- MobilePage ViewState detection - Fixed detection for pages without __VIEWSTATEGENERATOR
- Per-module carve_locations scoping - Modules can now declare which parts of a response they want to carve from
Performance
- YARA pre-filter skips expensive crypto checks when no relevant tokens are found in the response body
- Deduplicated carve() logic and extracted reusable check_secret() helper
- Inline ViewState parser avoids full deserialization overhead
Infrastructure / Tooling
- Migrated HTTP client from requests/requests_mock to httpx/respx - Async-ready HTTP stack
- Replaced Black + Flake8 with Ruff for linting and formatting
- Expanded CI test matrix with broader Python version and ruff coverage
- Python 3.13+ compatibility - Fixed argparse help text format change
Secret Wordlist Updates
- New Rack secret keys including GitHub Enterprise hardcoded secret
- New Play Framework secret keys added to JWT wordlist
- New Strapi and common tutorial JWT secrets
- New JSF viewstate passwords and ASP.NET machine keys
Bug Fixes
- Fix ASPNET_Resource base64 crash on malformed input
- Fix false positive in JSF viewstate DES3 detection (now requires 2+ java. matches)
- Fix CodeQL regex security alerts
- Fix MAC_DISABLED carve detection for null-padded ViewStates
- Suppress JWT InsecureKeyLengthWarning noise
Dependency Updates
Django, cryptography, httpx, PyJWT, urllib3, certifi, charset-normalizer, and many others brought to current versions.
Acknowledgments
Thanks to @irsdl for crapsecrets, which inspired several additions in this release.
0.13
v0.12.12
What's Changed
- Bump charset-normalizer from 3.4.2 to 3.4.3 by @dependabot[bot] in #253
- Change aspnet_vstate to aspnet_compressedviewstate, increase coverage by @liquidsec in #256
- Misc fixes by @liquidsec in #257
Full Changelog: v0.11.118...v0.12.12
v0.11.118
What's Changed
- Bump h11 from 0.14.0 to 0.16.0 by @dependabot[bot] in #201
- Migrate pyproject to use newer syntax for poetry groups by @emmanuel-ferdman in #202
- Bump zipp from 3.21.0 to 3.22.0 by @dependabot[bot] in #218
- Bump certifi from 2025.1.31 to 2025.4.26 by @dependabot[bot] in #204
- Bump flask from 3.1.0 to 3.1.1 by @dependabot[bot] in #211
- Bump django from 4.2.20 to 4.2.21 by @dependabot[bot] in #210
- Bump cryptography from 44.0.2 to 45.0.3 by @dependabot[bot] in #217
- Update tests.yaml by @liquidsec in #224
- Bump zipp from 3.22.0 to 3.23.0 by @dependabot[bot] in #223
- Bump django from 4.2.20 to 4.2.22 by @dependabot[bot] in #221
- Bump viewstate from 0.6.0 to 0.7.0 by @dependabot[bot] in #206
- Bump pytest from 8.3.5 to 8.4.0 by @dependabot[bot] in #220
- Bump charset-normalizer from 3.4.1 to 3.4.2 by @dependabot[bot] in #207
- Bump pytest-mock from 3.14.0 to 3.14.1 by @dependabot[bot] in #216
- Bump pycryptodome from 3.22.0 to 3.23.0 by @dependabot[bot] in #215
- Bump viewstate from 0.6.0 to 0.7.0 by @dependabot[bot] in #230
- Bump django from 4.2.20 to 4.2.23 by @dependabot[bot] in #229
- Bump pycryptodome from 3.22.0 to 3.23.0 by @dependabot[bot] in #227
- Bump django from 4.2.20 to 4.2.23 by @dependabot[bot] in #231
- Bump pytest-cov from 6.1.1 to 6.2.1 by @dependabot[bot] in #232
- Bump requests from 2.32.3 to 2.32.4 by @dependabot[bot] in #228
- Bump cryptography from 45.0.3 to 45.0.4 by @dependabot[bot] in #226
- Bump flask from 3.1.0 to 3.1.1 by @dependabot[bot] in #212
- Bump importlib-metadata from 8.6.1 to 8.7.0 by @dependabot[bot] in #205
- Bump requests from 2.32.3 to 2.32.4 by @dependabot[bot] in #234
- ViewStateUserKey support by @liquidsec in #233
- Bump requests from 2.32.3 to 2.32.4 by @dependabot[bot] in #225
- Bump cryptography from 45.0.4 to 45.0.5 by @dependabot[bot] in #242
- Bump poetry-dynamic-versioning from 1.8.2 to 1.9.1 by @dependabot[bot] in #248
- Bump asgiref from 3.8.1 to 3.9.1 by @dependabot[bot] in #246
- Bump cryptography from 45.0.5 to 45.0.6 by @dependabot[bot] in #251
- Bump certifi from 2025.4.26 to 2025.8.3 by @dependabot[bot] in #250
- Bump typing-extensions from 4.13.2 to 4.14.1 by @dependabot[bot] in #244
- Bump urllib3 from 2.4.0 to 2.5.0 by @dependabot[bot] in #239
- Bump django from 4.2.20 to 4.2.22 by @dependabot[bot] in #222
- Bump urllib3 from 2.4.0 to 2.5.0 by @dependabot[bot] in #241
- Bump h11 from 0.14.0 to 0.16.0 by @dependabot[bot] in #203
- Bump pytest from 8.4.0 to 8.4.1 by @dependabot[bot] in #240
- telerik-knownkey major update by @liquidsec in #237
- Fix coverage by @liquidsec in #252
Full Changelog: v0.10.35...v0.11.118
v0.10.35
What's Changed
- Bump pycryptodome from 3.21.0 to 3.22.0 by @dependabot in #185
- Update symfony_appsecret.txt by @random-robbie in #187
- Update laravel_app_keys.txt by @random-robbie in #186
- Bump poetry-dynamic-versioning from 1.7.1 to 1.8.2 by @dependabot in #192
- Bump typing-extensions from 4.12.2 to 4.13.2 by @dependabot in #197
- Yii2 module addition by @liquidsec in #199
- Bump pytest-cov from 6.0.0 to 6.1.1 by @dependabot in #196
- Bump urllib3 from 2.3.0 to 2.4.0 by @dependabot in #198
Full Changelog: v0.9.30...v0.10.35
v0.9.30
What's Changed
- Bump cryptography from 43.0.3 to 44.0.1 by @dependabot in #172
- New Module: Rack 2.x signed cookies by @liquidsec in #173
- better handling of hashcat function by @liquidsec in #175
Full Changelog: v0.8.25...v0.9.30
v0.8.25
What's Changed
- Bump poetry-dynamic-versioning from 1.4.1 to 1.5.0 by @dependabot in #159
- Bump jinja2 from 3.1.4 to 3.1.5 by @dependabot in #160
- Bump poetry-dynamic-versioning from 1.5.0 to 1.5.2 by @dependabot in #162
- Bump django from 4.2.17 to 4.2.18 by @dependabot in #164
- Bump poetry-dynamic-versioning from 1.5.2 to 1.7.0 by @dependabot in #165
- Bump poetry-dynamic-versioning from 1.7.0 to 1.7.1 by @dependabot in #167
- Bump django from 4.2.18 to 4.2.19 by @dependabot in #168
- Bump jinja2 from 3.1.4 to 3.1.5 by @dependabot in #171
- improving express regex by @liquidsec in #170
Full Changelog: v0.7.14...v0.8.25