How Holehe Handles User Agents for Bot Detection in OSINT Investigations

Holehe bypasses bot-detection systems by randomly selecting realistic Chrome browser user-agent strings from a centralized dictionary defined in 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

Instead of hardcoding strings across dozens of modules, Holehe centralizes its browser signatures in a single location. The file 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.


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

The Facebook checker in 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.


# 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, instagram.py, and 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.


# 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 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 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, 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.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →