What HTTP Headers and User Agent Does Holehe Use? A Deep Dive into Request Configuration

Holehe uses a randomized User-Agent string selected from a curated list of real browser signatures, combined with service-specific HTTP headers that vary per module.

Holehe, the popular open-source OSINT tool for email reconnaissance, implements sophisticated request header management to avoid detection. This article examines how the megadose/holehe repository configures HTTP headers and User-Agent strings across its module ecosystem.

How Holehe Generates User-Agent Headers

The foundation of Holehe's header strategy lives in a single source file. All modules import from holehe/localuseragent.py, which contains a JSON-structured dictionary named ua. This dictionary organizes authentic browser User-Agent strings into categories:

  • chrome
  • firefox
  • safari
  • iOS

When any module makes an HTTP request, it randomly selects from these pools:

from ..localuseragent import ua
import random

headers = {
    "User-Agent": random.choice(ua["browsers"]["chrome"])
}

This randomization ensures no two consecutive requests carry identical signatures, significantly reducing fingerprinting risk against bot detection systems.

Service-Specific HTTP Headers in Holehe Modules

Beyond the mandatory User-Agent, each module in holehe/modules/ constructs additional headers based on target service requirements. Common supplementary headers include:

  • Accept — Content negotiation values like application/json or text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  • Accept-Encoding — Compression preferences typically set to gzip, deflate, br
  • Accept-Language — Locale indicators such as en-US,en;q=0.9
  • DNT — Do-Not-Track flag (value 1) where applicable
  • Authorization — Bearer tokens or API keys generated dynamically within specific modules

Instagram Module Example

The social media checker in holehe/modules/social_media/instagram.py demonstrates typical header construction:

import random
from ..localuseragent import ua

def check_instagram(email):
    headers = {
        "User-Agent": random.choice(ua["browsers"]["chrome"]),
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Accept-Language": "en-US,en;q=0.9"
    }
    response = requests.get(
        "https://www.instagram.com/accounts/web_create_ajax/",
        headers=headers
    )
    # … processing logic

Office365 Module Example

Enterprise service modules often require lighter header sets. From holehe/modules/software/office365.py:

headers = {
    "User-Agent": random.choice(ua["browsers"]["firefox"]),
    "Accept": "application/json"
}

Key Implementation Files

File Purpose
holehe/localuseragent.py Master repository of browser User-Agent strings used project-wide
holehe/core.py Orchestrates module execution; delegates header construction to individual modules
holehe/modules/*/*.py Service-specific implementations adding custom headers as required by target endpoints

Summary

  • Holehe never uses a static User-Agent — it randomizes from real browser strings via holehe/localuseragent.py
  • Headers are module-specific — each service checker in holehe/modules/ builds appropriate supplementary headers
  • The design prioritizes stealth — mimicking genuine browser traffic patterns while satisfying API requirements
  • No central header manager exists — distribution of header logic allows fine-tuned per-service customization

Frequently Asked Questions

Does Holehe use the same User-Agent for every request?

No. Holehe selects a random User-Agent from browser-specific pools (Chrome, Firefox, Safari, iOS) for each request. This rotation occurs in every module through random.choice(ua["browsers"][...]) calls.

Where can I find the complete list of User-Agent strings?

The complete collection resides in holehe/localuseragent.py. This file contains hundreds of authentic browser signatures organized by platform and version.

Can I modify the HTTP headers Holehe sends?

Yes. Since header construction happens within individual modules under holehe/modules/, you can edit any module's headers dictionary directly. Changes take effect immediately upon running Holehe.

Why doesn't Holehe use a centralized header configuration?

Per-module header management allows precise adaptation to each service's requirements. Some endpoints need DNT headers, others require specific Accept values, and authorization workflows vary significantly. Distributed configuration prevents over-engineering while maintaining flexibility.

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 →