How Holehe's Update Check Mechanism Works and How to Disable It

Holehe automatically checks for updates at startup by querying PyPI and running pip install --upgrade if a newer version exists, but this behavior can only be disabled by modifying the source code.

Holehe, the open-source email OSINT tool by megadose, includes a hard-coded automatic update mechanism that runs before any command-line arguments are parsed. This article explains exactly how this holehe update check works, where it's implemented in the codebase, and four methods to disable it when you need consistent, predictable behavior.

How the Automatic Update Check Works

The update mechanism is implemented entirely in holehe/core.py through two key components: the check_update() function and its invocation point in maincore().

Version Retrieval and Comparison

The check_update() function fetches the latest package metadata from PyPI using httpx:


# From holehe/core.py, lines 34-36

response = httpx.get("https://pypi.org/pypi/holehe/json")
data = response.json()
actual_version = data["info"]["version"]

This remote "version" field is compared against the locally-defined __version__ constant (currently "1.61" in the analyzed snapshot). The version string is hard-coded at the top of holehe/core.py and imported for external use via holehe/__init__.py.

Automatic Upgrade Execution

When versions differ, check_update() spawns a subprocess to upgrade the package:

  • Unix-like systems: Uses pip3 (lines 69-75)
  • Windows: Falls back to pip (lines 76-81)

After the subprocess completes, the program prints a message and exits immediately (lines 85-86). No email reconnaissance occurs until you restart with the updated version.

Invocation Timing

The check runs unconditionally at program startup. In maincore() at line 97, you'll find:

check_update()          # <- This executes before argument parsing

args = parser.parse_args()

This placement means no CLI flags exist yet to disable the behavior—the argument parser hasn't been initialized.

Can You Disable Holehe's Update Check?

Currently, there is no built-in CLI option to disable the update check. The routine is hard-coded without conditional guards. To prevent automatic updates, you must modify holehe/core.py using one of these four approaches.

Method 1: Comment Out the Function Call

The simplest approach is to remove the invocation:


# Original (holehe/core.py ~line 97)

check_update()
args = parser.parse_args()

# Modified—update check disabled

# check_update()

args = parser.parse_args()

This stops all version checking with minimal code change.

Method 2: Replace with No-Op Stub

For a cleaner modification, redefine check_update() itself:

def check_update():
    """Disabled update check."""
    pass

Place this stub anywhere before line 97, or replace the original function definition (lines 34-86).

Method 3: Add a --no-update CLI Flag

For a proper solution that preserves optional update functionality, extend the argument parser and add conditional logic:


# In ArgumentParser definition (~line 80)

parser.add_argument("--no-update", action="store_true",
                    help="Skip the automatic update check")

# Replace unconditional call with conditional (~line 97)

if not args.no_update:
    check_update()
args = parser.parse_args()

This requires editing both the parser setup and the invocation point.

Method 4: Environment Variable Guard

Modify check_update() to respect an environment variable:

def check_update():
    """Check and update holehe if not the last version."""
    import os
    if os.getenv("HOLEHE_NO_UPDATE"):
        return  # Skip update when env var is set

    
    # ... rest of original function unchanged ...

Then disable updates per-session:

export HOLEHE_NO_UPDATE=1
holehe user@example.com

Key Files and Code Locations

File Purpose Relevant Lines
holehe/core.py Defines __version__, check_update(), and program entry point Lines 34-86 (update logic), line 97 (invocation)
holehe/__init__.py Package initialization, version export for external use Version import from core.py

All update-related functionality is contained in holehe/core.py. No other files in the repository reference the update logic, making modifications straightforward.

Practical Implications

The holehe update check behavior has several operational consequences:

  • Network dependency: Startup fails if PyPI is unreachable (unless you apply a modification)
  • Unexpected exits: Valid reconnaissance runs may terminate mid-execution for upgrades
  • Environment inconsistency: Automated pipelines or containerized deployments may experience version drift
  • No audit trail: The subprocess upgrade happens silently without logging the change

For production OSINT workflows, disabling the automatic update is often essential to ensure reproducible results.

Summary

  • Holehe's check_update() in holehe/core.py queries PyPI at every startup and auto-upgrades via pip when versions differ
  • The check runs unconditionally at line 97, before CLI argument parsing
  • No built-in flag exists to disable updates—modification is required
  • Four viable approaches: comment the call, stub the function, add --no-update flag, or implement environment-variable guard
  • All changes are localized to holehe/core.py

Frequently Asked Questions

Does Holehe require internet access to run?

Yes, both for the update check and for its core OSINT functionality. Even if you disable the update mechanism, Holehe needs network connectivity to query email services. The update check specifically requires access to https://pypi.org/pypi/holehe/json.

Will Holehe lose data if it updates mid-scan?

Holehe exits immediately after upgrading, so any in-progress scan is interrupted. Data from completed modules is lost because the process terminates before results are finalized. Always complete operations before allowing an update, or disable automatic updates for long-running batches.

Can I pin Holehe to a specific version without modifying code?

Not through official mechanisms. Standard Python approaches like pip install holehe==1.61 only affect initial installation—the tool still checks for updates and may upgrade itself. Source code modification remains the only reliable method to freeze functionality.

Is the update check a security risk?

The mechanism itself uses HTTPS to PyPI and subprocesses the standard pip installer, which is relatively benign. However, automatic code execution without user consent violates least-privilege principles in controlled environments. The exit-on-upgrade behavior can also disrupt forensic chain-of-custody for OSINT investigations.

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 →