The Problem

Sherlock solves the practical problem of determining whether a given username exists across hundreds of social networks. Manual checking is slow and error-prone; this tool automates the process by sending targeted HTTP requests to each platform and interpreting the responses.

What This Does

The repository is a fork of the popular sherlock-project/sherlock, providing a command-line tool that checks username availability across 400+ social networks. The core logic lives in the sherlock_project/ package, with supporting test infrastructure and Docker/Apify actor configurations for deployment.

The tool accepts one or more usernames, iterates through a site manifest (sherlock_project/resources/data.json), and reports which platforms have an account matching the username. It supports output to text, CSV, and XLSX formats, plus optional proxy support.

How It Is Wired

Execution starts at main in sherlock_project/sherlock.py:538. It reaches 13 functions and is called from one place (sherlock_project/__main__.py). The flow:

  1. main calls SitesInformation to load the site list, then remove_nsfw_sites to filter unless --nsfw is passed.
  2. For each username, main calls sherlock, which orchestrates the checking. sherlock is called from 4 places and is the central hub.
  3. sherlock calls interpolate_string (3 times) to expand wildcards, then request for each site. request makes the actual outbound network call via requests.get.
  4. Results are collected in QueryResult objects and reported through QueryNotify (notify.py), which handles file output and terminal display.

The module graph shows sherlock_project/sherlock with instability 0.67 (Ca 2, Ce 4) - it both depends on and is depended upon, making it the change hotspot. sherlock_project/__init__.py has Ca 5 but Ce 0, so it's a leaf that many import but it imports nothing itself.

The traced network path is short: main → sherlock → request → requests.get. File output goes through notify.py, which also handles the cryptographic operation (likely for the Apify actor's secret handling).

How To Use It

Setup: Install with pipx install sherlock-project or run the Docker image.

Running it:

sherlock user123
sherlock user1 user2 user3

Results save to individual text files per username. Use --csv or --xlsx for structured output, --site to limit to specific platforms, --proxy for proxied requests.

Real-World Use

A security researcher validating a username across platforms before an engagement:

sherlock --csv --output findings.csv --site github --site twitter target_user

This produces a CSV with confirmed accounts, which can feed into a broader OSINT pipeline.

Code Health & Issues

Static analysis found 12 issues (4 high, 8 medium) across 6 kinds:

  • High - Deep nesting: result.py, notify.py, sherlock.py have max indentation depth 10; control flow is hard to follow. Fix with early returns and guard clauses.
  • Medium - File opened without context manager: notify.py has open() calls not wrapped in with.
  • Medium - Broad exception handling: sherlock.py and sites.py catch Exception indiscriminately.
  • Medium - Oversized file: sherlock.py at 707 lines is a change hotspot.
  • Medium - Duplicated code: 2 repeated 6-line blocks across notify.py, result.py, sites.py.
  • Medium - High branching density: devel/summarize_site_validation.py and tests/test_validate_targets.py have 15 branch points over 51 lines.

SDLC observations: CI exists via GitHub Actions, tests are present, and a Dockerfile is included. However, third-party actions are pinned to mutable tags (not commit SHAs), and CI has continue-on-error on a correctness step in validate_modified_targets.yml. Dependencies lack a lockfile, and the container base image uses a mutable tag.

The Bottom Line

This is a functional, well-tested tool for a narrow purpose. The code works but has maintainability debt in sherlock.py and the notification layer. The CI/CD hygiene needs tightening before production use. It's suitable for security researchers and OSINT practitioners; the Docker image makes deployment straightforward.