# How Holehe Handles Sites That Return Obfuscated Recovery Information

> Learn how Holehe handles obfuscated recovery info by extracting masked emails and phone numbers precisely as shown, preserving obfuscation and returning None when no data is exposed.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: internals
- Published: 2026-08-25

---

**Holehe extracts masked email addresses and phone numbers exactly as displayed by target sites, preserving obfuscated strings like "j***@gmail.com" without attempting de-obfuscation, and returns `None` when no recovery data is exposed.**

Holehe is an open-source OSINT (Open Source Intelligence) tool maintained by **megadose** that checks where an email address is registered across hundreds of web services. When investigating how Holehe handles sites that return obfuscated recovery information, the tool's module-based architecture reveals a design philosophy of transparency: it captures masked data verbatim rather than attempting speculative reconstruction.

## The Standard Module Workflow for Recovery Data

Every Holehe module follows a consistent five-step pattern to handle password recovery pages. The workflow begins in [`holehe/localuseragent.py`](https://github.com/megadose/holehe/blob/main/holehe/localuseragent.py), which supplies realistic **User-Agent** strings to avoid detection. The module then performs an initial GET request to the target site's login or recovery endpoint, parsing the HTML response with **BeautifulSoup** to inspect for recovery data elements.

When a service deliberately hides the full address—displaying only obfuscated placeholders like "j***@gmail.com" or masked phone numbers—the module captures that exact string. If no recovery field is present, the module records `None`. Finally, each module appends a standardized result dictionary to the shared `out` list, containing keys for `emailrecovery`, `phoneNumber`, and `others`.

## Extracting Obfuscated Data in Practice

### Social Media Recovery Parsing (Odnoklassniki)

The Odnoklassniki module at [`holehe/modules/social_media/odnoklassniki.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/odnoklassniki.py) demonstrates how Holehe handles partially masked credentials. The code inspects `<button>` elements with specific `data-l` attributes—specifically `data-l="t,email"` and `data-l="t,phone"`—to extract recovery information.

When these elements contain text (e.g., a masked email address), the module stores the raw string directly in the result dictionary. If the attributes are absent or empty, the fields remain `None`. This approach preserves whatever obfuscation the service applies, ensuring the tool reports exactly what an attacker or investigator would see in a browser.

### JSON-Based Recovery Checks (Adobe)

In [`holehe/modules/software/adobe.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/software/adobe.py), the module attempts to locate secondary email addresses within JSON responses returned by Adobe's endpoints. Around lines 59-66, the code checks for specific keys in the response body. When the service does not expose a secondary email—either because it is hidden or not configured—the module explicitly sets the `emailrecovery` value to `None` rather than fabricating data.

### No-Exposure Services (Blablacar)

Not all services reveal recovery information during the lookup phase. The Blablacar module at [`holehe/modules/transport/blablacar.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/transport/blablacar.py) represents services that provide no recovery data at all. In such cases, the module directly constructs a result dictionary with `"emailrecovery": None`, maintaining consistent output structure while accurately reflecting the absence of visible data.

## Core Orchestration and Result Aggregation

The central logic driving this behavior resides in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py). This orchestrator iterates over selected modules, passes the shared `out` list for population, and returns the accumulated results. Crucially, the core makes no assumptions about the format of recovery data—it does not validate whether strings are obfuscated, de-obfuscated, or null. This architectural decision keeps the tool simple and avoids speculative processing, ensuring that whatever the module extracts (masked or otherwise) is returned verbatim to the user.

## Practical Implementation Example

To observe how Holehe captures obfuscated recovery data, execute the following:

```python
from holehe import core
import asyncio

async def run():
    email = "test@example.com"
    results = await core.check(email, modules=["odnoklassniki", "adobe"])
    for r in results:
        print(r["name"], r["emailrecovery"])

asyncio.run(run())

```

If Odnoklassniki returns a masked address like `j***@mail.ru` while Adobe exposes no secondary email, the output will be:

```text
odnoklassniki j***@mail.ru
adobe None

```

## Summary

- Holehe modules extract masked recovery strings exactly as presented by target sites without attempting de-obfuscation.
- The tool returns `None` for `emailrecovery` and `phoneNumber` when services hide this data entirely or do not expose it during the lookup phase.
- The [`core.py`](https://github.com/megadose/holehe/blob/main/core.py) orchestrator aggregates results from all modules without validating or transforming the recovery data format.
- Implementation details vary by service: Odnoklassniki parses HTML button attributes, Adobe inspects JSON responses, and transport modules like Blablacar default to `None`.

## Frequently Asked Questions

### Does Holehe attempt to de-obfuscate masked email addresses?

No. According to the source code in [`holehe/modules/social_media/odnoklassniki.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/odnoklassniki.py), Holehe captures the masked string (e.g., "j***@gmail.com") exactly as displayed by the service and stores it in the `emailrecovery` field. The tool does not implement logic to reverse-engineer the original address from partial masks.

### What happens when a site doesn't expose any recovery information?

When services like Blablacar do not display recovery data on their public-facing endpoints, the respective module explicitly sets `"emailrecovery": None` before appending the result to the output list. This ensures a consistent data structure across all checked services, clearly indicating when information is unavailable rather than missing.

### How does Holehe ensure it receives the same obfuscated data as a regular user?

Each module utilizes realistic User-Agent strings defined in [`holehe/localuseragent.py`](https://github.com/megadose/holehe/blob/main/holehe/localuseragent.py) and standard HTTP headers when requesting password recovery pages. This ensures the target site responds with the same HTML or JSON content—including obfuscated recovery fields—that would be visible to a legitimate user accessing the page through a standard browser.

### Can Holehe differentiate between partially masked and fully visible recovery data?

The core logic in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) treats all recovery data opaquely. The orchestrator simply aggregates whatever string the module supplies—whether fully visible, partially masked, or `None`—without parsing the content to categorize the level of obfuscation. This design keeps the tool agnostic to the specific masking strategies employed by different web services.