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:
chromefirefoxsafariiOS
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 likeapplication/jsonortext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Encoding— Compression preferences typically set togzip, deflate, brAccept-Language— Locale indicators such asen-US,en;q=0.9DNT— Do-Not-Track flag (value1) where applicableAuthorization— 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →