How to Use the Password Recovery Method for Account Detection in Holehe
The password recovery method in Holehe detects registered accounts by triggering "Forgot password?" flows and extracting masked contact information from the response.
Holehe is an open-source email investigation tool that checks whether an address is registered on hundreds of online services. For many platforms, the only reliable detection mechanism is to simulate a password reset request and analyze what data the service leaks. According to the megadose/holehe source code, this technique is explicitly labeled as "password recovery" and can be controlled via CLI flags or programmatically.
How Password Recovery Detection Works in Holehe
Each service module in Holehe declares its detection strategy through a method variable. When method = "password recovery", the module triggers the same flow a legitimate user would use to recover a forgotten password.
The Core Detection Pattern
In holehe/core.py, the orchestration engine filters modules based on this method string. Lines 58–62 of the source show how the --no-password-recovery flag removes these modules from the scan:
# From holehe/core.py - get_functions()
if args.nopasswordrecovery:
websites = [f for f in websites if f.__code__.co_consts[-5] != "password recovery"]
When a password recovery module runs, it returns a standardized dictionary with these keys:
{
"name": "adobe", # service identifier
"domain": "adobe.com", # service domain
"method": "password recovery",
"frequent_rate_limit": False,
"rateLimit": False,
"exists": True, # account found
"emailrecovery": "a***@example.com", # masked recovery email
"phoneNumber": "+1 5******89", # masked phone number
"others": None # additional metadata
}
Real-World Implementation Examples
Adobe (holehe/modules/software/adobe.py)
The Adobe module demonstrates the classic password recovery flow. It:
- POSTs to Adobe's authentication endpoint to obtain an encrypted token
- Queries the
passwordRecoverychallenge endpoint with the email - Parses
secondaryEmailorsecurityPhoneNumberfrom the response to confirm account existence
# Simplified flow from adobe.py
method = "password recovery"
# Token acquisition and recovery request
async def adobe(email, client, out):
# ... token extraction logic ...
data = {
"username": email,
"password": "" # intentional empty password triggers recovery flow
}
response = await client.post(
"https://auth.services.adobe.com/signin",
data=data
)
# Parse for recovery indicators
exists = "secondaryEmail" in response.text or "securityPhoneNumber" in response.text
# ... append to out list ...
Samsung (holehe/modules/products/samsung.py)
Samsung's implementation is more complex. The module:
- Initiates a sign-up flow to harvest CSRF tokens
- POSTs the email to Samsung's check-email endpoint
- If recognized, follows the reset-password flow to extract a masked phone number
This two-step pattern is required because Samsung's password recovery endpoint requires valid session tokens obtained from an initial interaction.
Odnoklassniki/OK.ru (holehe/modules/social_media/odnoklassniki.py)
The Odnoklassniki module loads the "Forgot Password" page directly after a failed login attempt. The HTML response contains masked profile data when the email is registered:
# From odnoklassniki.py
method = "password recovery"
async def odnoklassniki(email, client, out):
# Dummy login to establish session
await client.post("https://ok.ru/dk", data={"login": email})
# Load recovery page
reset_page = await client.get(
"https://ok.ru/dk?st.cmd=anonymRecoveryStart"
)
# Extract masked email, phone, profile info from HTML
# ... parsing logic ...
Controlling Password Recovery via Command Line
Default Behavior (Password Recovery Enabled)
By default, Holehe runs all modules including password recovery checks:
holehe target@example.com
Output includes recovery data when available:
[+] adobe.com target@example.com / t***@gmail.com / +1 ***
[+] samsung.com target@example.com / / +1 5******89
[+] ok.ru target@example.com / target****@ok.ru / 06 ** ** **
Disabling Password Recovery (-NP / --no-password-recovery)
Use the -NP flag to exclude password recovery modules. This skips Adobe, Samsung, Odnoklassniki, and similar services:
holehe target@example.com -NP
In holehe/core.py lines 90–92, the argument parser defines this flag:
parser.add_argument("-NP", "--no-passwordrecovery",
action="store_true",
help="Don't run password recovery modules")
Programmatic Usage with Password Recovery
When using Holehe as a Python library, you control password recovery inclusion through the get_functions() call:
import trio
import httpx
from holehe.core import import_submodules, get_functions, launch_module
async def scan_with_password_recovery(email: str):
"""
Run Holehe scan including password recovery modules.
"""
# Load all service modules
modules = import_submodules("holehe.modules")
# Include all modules (password recovery included)
funcs = get_functions(modules) # No args.nopasswordrecovery passed
client = httpx.AsyncClient(timeout=10, follow_redirects=True)
results = []
async with trio.open_nursery() as nursery:
for func in funcs:
nursery.start_soon(launch_module, func, email, client, results)
await client.aclose()
return results
async def scan_without_password_recovery(email: str):
"""
Run Holehe scan excluding password recovery modules.
"""
modules = import_submodules("holehe.modules")
# Filter out password recovery modules manually
all_funcs = get_functions(modules)
funcs = [
f for f in all_funcs
if f.__code__.co_consts[-5] != "password recovery"
]
client = httpx.AsyncClient(timeout=10)
results = []
async with trio.open_nursery() as nursery:
for func in funcs:
nursery.start_soon(launch_module, func, email, client, results)
await client.aclose()
return results
# Execute scan
if __name__ == "__main__":
email = "investigate@example.com"
full_results = trio.run(scan_with_password_recovery, email)
for r in full_results:
if r.get("exists") and r.get("method") == "password recovery":
print(f"[{r['domain']}] Found: {r.get('emailrecovery') or 'N/A'} / {r.get('phoneNumber') or 'N/A'}")
Key Source Files for Password Recovery
| File | Purpose |
|---|---|
holehe/core.py |
Main engine, CLI parsing (-NP flag), module orchestration via get_functions() and launch_module() |
holehe/modules/software/adobe.py |
Reference implementation for token-based password recovery |
holehe/modules/products/samsung.py |
Multi-step flow with CSRF token extraction and phone number recovery |
holehe/modules/social_media/odnoklassniki.py |
HTML parsing approach for masked contact extraction |
holehe/localuseragent.py |
Rotates realistic User-Agent strings to avoid fingerprinting |
Summary
- Password recovery detection triggers "Forgot password?" flows and analyzes leaked contact information to confirm account existence
- Modules declare
method = "password recovery"to indicate this detection strategy, as implemented inadobe.py,samsung.py, andodnoklassniki.py - CLI control uses
-NPor--no-password-recoveryto skip these modules (default: enabled) - Standardized output includes
emailrecoveryandphoneNumberfields with masked contact data - Library usage requires filtering
get_functions()results based onmethodstring when exclusion is needed
Frequently Asked Questions
What services use password recovery detection in Holehe?
Adobe, Samsung, and Odnoklassniki are the primary implementations. Each service in holehe/modules/ that declares method = "password recovery" uses this technique. Check individual module files to identify which services apply this method.
Why would I disable password recovery with -NP?
Password recovery modules often involve multi-step HTTP flows and may trigger rate limits more aggressively. Disabling them speeds up scans and reduces detection footprint when you only need basic registration checks from other modules.
Does password recovery detection notify the account owner?
Yes. Triggering a password reset flow typically sends a genuine reset email or SMS to the registered contact. This is an inherent limitation of the technique—Holehe cannot verify account existence through password recovery without generating notifications.
What data can password recovery modules extract?
The standardized output may include emailrecovery (masked alternate email), phoneNumber (masked phone), and platform-specific data in others. Availability depends entirely on what each service leaks in its recovery response.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →