# How Holehe Handles User Agents for Bot Detection in OSINT Investigations

> Learn how Holehe evades bot detection in OSINT investigations by using randomized realistic user agents. Discover how it mimics human browsing for effective data gathering.

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

---

**Holehe bypasses bot-detection systems by randomly selecting realistic Chrome browser user-agent strings from a centralized dictionary defined in [`holehe/localuseragent.py`](https://github.com/megadose/holehe/blob/main/holehe/localuseragent.py), injecting varying headers into each HTTP request to mimic genuine human browsing patterns.**

Holehe is an open-source OSINT (Open Source Intelligence) tool designed to check if an email address is registered on various websites. To avoid triggering automated security mechanisms during these checks, the repository implements a sophisticated user-agent rotation strategy. This article examines how Holehe handles user agents for bot detection by analyzing the source code in `megadose/holehe`.

## The Centralized User-Agent Repository in [`localuseragent.py`](https://github.com/megadose/holehe/blob/main/localuseragent.py)

Instead of hardcoding strings across dozens of modules, Holehe centralizes its browser signatures in a single location. The file [`holehe/localuseragent.py`](https://github.com/megadose/holehe/blob/main/holehe/localuseragent.py) defines a JSON-style dictionary named `ua` containing a curated list of **Chrome user-agent strings** spanning Windows, macOS, and Linux architectures.

This centralized architecture allows maintainers to update browser signatures once, with changes immediately propagating to all modules that import the data.

```python

# holehe/localuseragent.py

import json

ua = json.loads('''{
    "browsers": {
        "chrome": [
            "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36"
        ]
    }
}''')

```

## Randomized Header Injection Across Social Media Modules

When individual check modules perform HTTP requests, they import the `ua` dictionary and utilize Python’s `random.choice()` to select a fresh signature for each invocation. This randomization ensures that consecutive requests from the same IP address appear to originate from different legitimate browsers.

### Facebook Module Implementation ([`facebook.py`](https://github.com/megadose/holehe/blob/main/facebook.py))

The Facebook checker in [`holehe/modules/social_media/facebook.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/facebook.py) demonstrates the standard implementation pattern. The module constructs a headers dictionary using a randomly selected Chrome user-agent, along with appropriate Accept and Origin headers to masquerade as a genuine browser session.

```python

# holehe/modules/social_media/facebook.py

from holehe.localuseragent import ua
import random
import httpx

async def facebook(email, client, out):
    headers = {
        'User-Agent': random.choice(ua["browsers"]["chrome"]),
        'Accept': 'application/json, text/plain, */*',
        'Accept-Language': 'en-US,en;q=0.5',
        'Origin': 'https://www.facebook.com',
        'Referer': 'https://www.facebook.com/'
    }
    # HTTP request execution follows...

```

### Pattern Replication in Twitter and Instagram Checkers

This approach is replicated consistently across the codebase. Modules such as [`twitter.py`](https://github.com/megadose/holehe/blob/main/twitter.py), [`instagram.py`](https://github.com/megadose/holehe/blob/main/instagram.py), and [`blablacar.py`](https://github.com/megadose/holehe/blob/main/blablacar.py) import the same `ua` data structure, ensuring uniform evasion capabilities across different platforms. While some modules may use the underlying HTTP client’s default headers, they retain access to the `ua` dictionary for explicit header overrides when necessary.

```python

# holehe/modules/social_media/twitter.py

from holehe.localuseragent import *

async def twitter(email, client, out):
    # Module imports ua data for potential header customization

    # Actual request headers may be handled by the client instance

    pass

```

## Technical Advantages of Chrome-Centric Rotation

Holehe specifically utilizes **Chrome browser signatures** rather than generic or outdated user-agents for specific tactical reasons:

- **High legitimacy volume**: Chrome represents the majority of global browser market share, making these signatures statistically unlikely to trigger false-positive bot flags.
- **Platform diversity**: The `ua` dictionary includes signatures for Windows NT, macOS Intel, and Linux variants, supporting geolocation-consistent headers.
- **Entropy generation**: The `random.choice()` implementation prevents pattern-based detection that static user-agent strings would exhibit.

## Summary

- Holehe stores all user-agent strings in [`holehe/localuseragent.py`](https://github.com/megadose/holehe/blob/main/holehe/localuseragent.py) within a dictionary named `ua`.
- The tool exclusively uses Chrome browser signatures covering multiple operating systems to maximize legitimacy.
- Modules import `ua` and call `random.choice(ua["browsers"]["chrome"])` to inject unpredictable headers.
- This centralized approach simplifies maintenance while ensuring consistent bot-detection evasion across all OSINT checks.

## Frequently Asked Questions

### What is the primary method Holehe uses to avoid bot detection?

Holehe mitigates bot detection by randomly selecting user-agent strings from a predefined list of legitimate Chrome browser signatures using `random.choice()`. This ensures each HTTP request presents a different browser identity, preventing pattern recognition algorithms from flagging the traffic as automated.

### Where are the user-agent strings stored in the Holehe repository?

All user-agent data resides in [`holehe/localuseragent.py`](https://github.com/megadose/holehe/blob/main/holehe/localuseragent.py) within a JSON-parsed dictionary called `ua`. This file contains a "browsers" key with a "chrome" sublist holding multiple platform-specific signatures for Windows, macOS, and Linux systems.

### Can developers add custom user-agent strings to Holehe?

Yes. Because the repository uses a centralized dictionary in [`localuseragent.py`](https://github.com/megadose/holehe/blob/main/localuseragent.py), developers can extend the `ua["browsers"]["chrome"]` list with additional strings without modifying individual module files. This design allows for rapid updates when browser versions change or when targeting specific platform demographics.

### Does Holehe rotate user-agents per request?

Yes. Each time an OSINT module executes, it calls `random.choice()` on the Chrome user-agent list, generating a fresh header for that specific request. This per-request rotation prevents temporal correlation attacks that might identify the tool through consistent header fingerprints.