# How to Use the Password Recovery Method for Account Detection in Holehe

> Learn to use Holehe's password recovery method for account detection. Trigger forgot password flows to extract masked contact info and identify registered accounts.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: how-to-guide
- Published: 2026-08-30

---

**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`](https://github.com/megadose/holehe/blob/main/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:

```python

# 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:

```python
{
    "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`](https://github.com/megadose/holehe/blob/main/holehe/modules/software/adobe.py))

The Adobe module demonstrates the classic password recovery flow. It:

1. POSTs to Adobe's authentication endpoint to obtain an encrypted token
2. Queries the `passwordRecovery` challenge endpoint with the email
3. Parses `secondaryEmail` or `securityPhoneNumber` from the response to confirm account existence

```python

# 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`](https://github.com/megadose/holehe/blob/main/holehe/modules/products/samsung.py))

Samsung's implementation is more complex. The module:

1. Initiates a sign-up flow to harvest CSRF tokens
2. POSTs the email to Samsung's check-email endpoint
3. 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`](https://github.com/megadose/holehe/blob/main/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:

```python

# 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:

```bash
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:

```bash
holehe target@example.com -NP

```

In [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) lines 90–92, the argument parser defines this flag:

```python
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:

```python
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`](https://github.com/megadose/holehe/blob/main/holehe/core.py) | Main engine, CLI parsing (`-NP` flag), module orchestration via `get_functions()` and `launch_module()` |
| [`holehe/modules/software/adobe.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/software/adobe.py) | Reference implementation for token-based password recovery |
| [`holehe/modules/products/samsung.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/products/samsung.py) | Multi-step flow with CSRF token extraction and phone number recovery |
| [`holehe/modules/social_media/odnoklassniki.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/odnoklassniki.py) | HTML parsing approach for masked contact extraction |
| [`holehe/localuseragent.py`](https://github.com/megadose/holehe/blob/main/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 in [`adobe.py`](https://github.com/megadose/holehe/blob/main/adobe.py), [`samsung.py`](https://github.com/megadose/holehe/blob/main/samsung.py), and [`odnoklassniki.py`](https://github.com/megadose/holehe/blob/main/odnoklassniki.py)
- **CLI control** uses `-NP` or `--no-password-recovery` to skip these modules (default: enabled)
- **Standardized output** includes `emailrecovery` and `phoneNumber` fields with masked contact data
- **Library usage** requires filtering `get_functions()` results based on `method` string 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.