# How the Register Detection Method Works in holehe: Email Enumeration via Registration Flows

> Learn how holehe's register detection method works for email enumeration. It simulates registrations to identify existing email accounts on target services.

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

---

**The register detection method in holehe simulates a new user registration attempt on target services and analyzes HTTP responses for indicators—such as error messages or specific status codes—that confirm whether an email address is already associated with an existing account.**

`holehe` is an open-source Python tool for email footprinting that checks whether an address is registered across hundreds of online services. Each service module in the repository declares a **`method`** attribute that dictates its enumeration strategy. When this attribute is set to **`"register"`**, the module exploits the service's public registration endpoint to infer account existence without requiring authentication.

## How the Core Engine Dispatches Register Checks

In [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), the engine dynamically imports every Python file located in `holehe/modules/**` and instantiates service-specific classes. Each class exposes a class-level attribute named `method`. When the core encounters `method = "register"`, it routes execution to the registration-based enumeration logic rather than password-reset or login-based alternatives.

### Module Discovery and Method Selection

The core buildsa dictionary mapping service names to module instances. For each imported module, the engine inspects the `method` attribute:

```python

# Conceptual flow from holehe/core.py

for module in load_modules('holehe/modules/'):
    if module.method == "register":
        tasks.append(module.run(client, email))

```

This dispatch mechanism allows `holehe` to treat registration-based checks as a distinct category requiring specific request patterns: retrieving registration pages, extracting anti-CSRF tokens, and submitting form data.

### Asynchronous Request Execution

The core initializes an `httpx.AsyncClient` (provided by [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py)) to maintain session state across requests. For register modules, the typical execution flow involves three phases:

1. **Token Extraction**: A GET request to the registration URL retrieves hidden form fields, CSRF tokens, and session cookies.
2. **Form Submission**: A POST request sends the target email address alongside dummy data (passwords, usernames) that passes client-side validation but triggers server-side email uniqueness checks.
3. **Header Mimicry**: Requests include realistic headers such as `User-Agent`, `Referer`, `Accept-Language`, and `Content-Type` to avoid bot detection.

## Response Analysis and Detection Logic

After submitting the registration form, the module analyzes the server response through multiple vectors to determine if the email exists in the target database.

### Identifying Registered Accounts via HTTP Responses

The `run` coroutine in each module implements response parsing logic that looks for three specific indicators:

- **Status Code Analysis**: HTTP 422 (Unprocessable Entity), 409 (Conflict), or custom status codes specific to the platform that indicate validation failures.
- **Text Pattern Matching**: Case-insensitive searches for strings like "already registered", "email is already used", "that email is taken", or "account already exists" within `response.text`.
- **JSON Field Inspection**: For API-based registration endpoints, parsing the JSON body for error keys such as `{"error": "already_exists"}`, `{"success": false, "code": "duplicate_email"}`, or similar schema markers indicating the email is in use.

### Returning Enumeration Results

The module's `run` method returns a structured result—typically a boolean or dictionary—that the core aggregates into the final report. For example:

```python

# Typical return pattern from holehe/modules/ example

if "already registered" in post_resp.text.lower() or post_resp.status_code == 422:
    return {"name": "ExampleService", "exists": True, "email": email}
return {"name": "ExampleService", "exists": False, "email": email}

```

## Implementation Example: Anatomy of a Register Module

The following code illustrates the pattern used across `holehe/modules/**/*.py` when implementing the register detection method:

```python

# Located at holehe/modules/example_platform.py

import httpx
from holehe.instruments import get_random_user_agent

class ExamplePlatform:
    method = "register"
    url = "https://example.com/signup"
    
    async def run(self, client: httpx.AsyncClient, email: str):
        headers = {
            "User-Agent": get_random_user_agent(),
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
        }
        
        # Step 1: Retrieve registration form and tokens

        get_resp = await client.get(self.url, headers=headers)
        csrf_token = extract_csrf_token(get_resp.text)  # Custom parsing logic

        
        # Step 2: Simulate registration attempt

        payload = {
            "email": email,
            "password": "DummyPassword123!",
            "confirm_password": "DifferentPass123!",  # Intentional mismatch to prevent actual creation

            "csrf_token": csrf_token,
            "terms": "false"  # Fail additional checks

        }
        
        post_resp = await client.post(
            self.url,
            data=payload,
            headers={**headers, "Content-Type": "application/x-www-form-urlencoded"}
        )
        
        # Step 3: Analyze response for existence indicators

        if post_resp.status_code == 400 and "email already exists" in post_resp.text.lower():
            return {"exists": True, "service": "ExamplePlatform"}
        
        return {"exists": False, "service": "ExamplePlatform"}

```

## Why Registration-Based Enumeration Is Effective

Public registration endpoints must validate email uniqueness before creating accounts, making them reliable indicators of account existence. Unlike login endpoints—which often return ambiguous errors for "user not found" versus "wrong password"—registration forms typically provide explicit confirmation when an email is already registered. By reproducing the exact request sequence a browser would send, `holehe` bypasses the need for API keys or authenticated sessions while leveraging the service's own validation logic.

## Summary

- **Register Method**: Simulates account creation attempts to probe for existing emails without completing actual registration.
- **Module Declaration**: Service modules declare `method = "register"` in files under `holehe/modules/**/*.py` to opt into this strategy.
- **Core Orchestration**: [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) imports modules, checks for the register method, and coordinates asynchronous execution via `httpx.AsyncClient`.
- **Detection Mechanism**: Analysis relies on HTTP status codes (422, 409), plain-text error markers ("already registered"), and JSON error fields from registration endpoints.
- **Session Management**: [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py) provides utilities for maintaining sessions and generating realistic request headers.

## Frequently Asked Questions

### What is the difference between the register method and other detection methods in holehe?

Other methods may exploit password reset flows or login error messages to infer account existence. The register method specifically targets the account creation endpoint, which often provides binary "email already exists" responses rather than ambiguous authentication failures.

### How does holehe handle CSRF tokens and session cookies during register checks?

According to [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py), the tool maintains persistent sessions via `httpx.AsyncClient`. Each registration module first performs a GET request to the target's registration page to extract anti-CSRF tokens and session cookies, then includes these values in the subsequent POST request to ensure the registration attempt appears legitimate.

### Can the register detection method trigger actual account creation?

No. Modules using the register method are designed to halt before final submission or employ intentionally invalid secondary data—such as mismatched password confirmations or declined terms-of-service agreements—that passes email format validation but fails subsequent business logic checks. The tool only captures the immediate server response regarding email uniqueness.

### Which file contains the main orchestration logic for the register method?

The primary dispatch logic resides in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), which dynamically imports modules from `holehe/modules/`, inspects the `method` class attribute for the value `"register"`, and coordinates the asynchronous execution of each service's `run` coroutine while aggregating results into the final enumeration report.