OpenSource-Hub

user-scanner

CLI ツール

kaifcodec/user-scanner

メールとユーザー名の高度な OSINT スイート。465+ のスキャンベクトルに対応。

概要

User Scanner は、セキュリティ研究と調査向けの Python ベースの OSINT スイートです。465以上のアクティブなプラットフォームをスキャンし、メタデータの抽出やアカウント登録の検証を行い、ハンドルとメールアドレスによる自動関連付けで調査を拡張できます。クロススキャン、プロキシローテーション、複数フォーマットのレポート、および AI エージェント統合用の MCP サーバーをサポートしています。

README プレビュー

# User Scanner\n\n\n  \n\n\n\n  \n  \n  \n  \n  \n  \n  \n     \n  \n\n\n\n  \n    \n  \n\n\n---\n\nA powerful **2-in-1 OSINT suite** engineered for deep **Email and Username Intelligence**.\n\nWith **465+ total scan vectors**—including **175+ email-integrated sites** and **290+ username platforms**—you can map digital footprints, analyze target behavior, uncover interests, full metadata of usernames and verify account registrations in seconds.\n\n---\n\n## 💖 Sponsored by\n\n\n  \n    \n  \n  \n  Go beyond account enumeration. WebVetted turns an email or username into a complete identity investigation with deep OSINT enrichment, breach intel, AI analysis, and an interactive identity graph.\n  \n  Start an Investigation →\n\n\n---\n\n\n  \n    \n  \n  \n  Comprehensive OSINT platform for professional investigators and analysts. Reverse email, phone number, and username search across 250+ modules. Automate your intelligence gathering with our powerful tools.\n  \n  Get Started →\n\n\n---\n\n## ✨ Key Features\n\n- 🔎 **Deep Email & Username OSINT:** Look up email registrations and perform advanced username profiling across 465+ platforms.\n- 👤 **Rich Metadata Scraping:** Scrapes avatars, bio descriptions, follower counts, UID numbers, seller statuses, and account attributes.\n- 🔀 **Cross-Scan & Pivot Engine:** Mines handles, profile links, and exposed email addresses from initial scans, automatically pivoting across secondary target vectors.\n- 🤖 **Model Context Protocol (MCP) Server:** Native AI agent integration for Claude Desktop, Cursor, Antigravity, and LLMs to run autonomous OSINT scans and recursive pivots.\n- 🛡️ **Hudson Rock Infostealer Breach Intel:** Query infostealer malware breach logs using the `--hudson` flag for high-priority target correlation.\n- ⚡ **High-Throughput Parallel Engine:** Powered by `httpx` and `curl_cffi` for maximum concurrency with automated TLS fingerprint impersonation.\n- 🔀 **Permutation & Alias Generator:** Wildcard-based use

FAQ (5)

トラブル対応
ユーザー名やメールアドレスに &、#、%、+、スペース、または非 ASCII 文字が含まれる場合に、Python の URL クエリ文字列で壊れたり不正確になったりする API リクエストを修正するにはどうすればよいですか?

ユーザーが制御できる生の値を f-string の URL に直接挿入しないでください。各クエリ値を urllib.parse.quote でパーセントエンコードしてください:

from urllib.parse import quote

url = f"{base_url}{endpoint}?{param}={quote(target, safe='')}"
api_url = f"https://www.instagram.com/api/v1/users/web_profile_info/?username={quote(user, safe='')}"

複数のパラメータがある場合は、urlencode を優先してください:

from urllib.parse import urlencode

params = {"username": user, "email": email}
url = f"{base_url}{endpoint}?{urlencode(params)}"

core/、email_scan/、user_scan/ 配下のモジュールを含むすべての f-string クエリ URL を監査し、補間されている user、username、email、target などの値をすべてエンコードしてください。URL 全体ではなく、パラメータの値のみをエンコードしてください。&、#、%、+、空白文字、非 ASCII 文字を含む入力を使用した回帰テストを追加してください。既存の leetcode.py における urllib.parse.quote() の使用を参照パターンとして利用できます。

参照 Issue #574
トラブル対応
-C または MCP でコンカレンシーが 0 に設定されている場合、user-scanner がハングするのはなぜですか?

concurrency を 0 に設定すると asyncio.Semaphore(0) が生成されるため、すべてのモジュールがモジュール単位のタイムアウトが開始される前に永久に待機することになります。MCP モードでは、これによりスキャンロックが保持され、キューがブロックされる可能性もあります。影響を受けるバージョン(1.5.2.1 を含む)での回避策として、-C 1 などの正の concurrency 値を指定してスキャンを実行するか、MAX_CONCURRENT_REQUESTS=1 を設定してください。0 や負の値は使用しないでください。この修正では、CLI/MCP の境界、および orchestrator.set_concurrency と email_orchestrator.set_concurrency の両方に検証が追加され、1 未満の値に対して ValueError が送出され、MCP スキーマには minimum: 1 が設定されます。ユーザー名スキャンとメールスキャンで早期かつ一貫した検証を得るために、修正を含むリリースにアップグレードしてください。

参照 Issue #690
トラブル対応
I'm not familiar with the internals of a tool specifically called "user-scanner," so I can't point to its exact code or config options — but the behavior you're describing (main requests go through the proxy, PDF/media downloads don't) is a common bug pattern with a few standard causes and fixes. Take this as general guidance and verify against the tool's source/docs. **Why this usually happens** - The tool configures the proxy only on its main HTTP session (the one used for API/page requests), but media downloads use a separate code path — e.g., `urllib.request.urlretrieve`, a raw `requests.get` without `proxies=`, an `aiohttp` session created without proxy args, or a subprocess call to `curl`/`wget`. - The `-P`/`--proxy-file` argument is parsed but never passed into the downloader function. - The proxy file format doesn't match what the tool expects (e.g., missing scheme like `http://`, wrong delimiter), and it silently falls back to a direct connection. **Things to try** 1. **Set proxy environment variables as a catch-all.** Most HTTP libraries honor these even when the tool doesn't pass the proxy explicitly: ```bash export HTTP_PROXY="http://127.0.0.1:8080" export HTTPS_PROXY="http://127.0.0.1:8080" # also set lowercase http_proxy / https_proxy — some libs only read those user-scanner -P proxies.txt ... ``` 2. **Verify the proxy file format.** Check the tool's `--help` or README for the expected format (often one `scheme://host:port` per line). A malformed file may be silently ignored. 3. **Update the tool** and search its issue tracker/PRs for terms like "proxy," "pdf," or "download" — this may already be a known, fixed bug. 4. **Check for separate options.** Some tools have distinct flags for media handling (e.g., a `--no-media` / `--skip-downloads` toggle, or a separate proxy setting for downloads). 5. **Patch the source** if nothing else works: find where PDFs are fetched (grep for `.pdf`, `urlretrieve`, `requests.get`, `stream=True`) and make that call use the same proxied session or pass `proxies=proxy_dict` explicitly. **Confirming the fix** Run a local intercepting proxy like `mitmproxy` and point the tool at it. If PDF requests show up in the mitmproxy flow list, traffic is routed correctly; if downloads succeed but nothing appears, they're still bypassing the proxy. If you can share a link to the tool's repo or the relevant download code, I can give you a more specific fix.

これは PR #692 で修正されています。バージョン 1.5.2.1(コミット 780d077a468035c6afd6b4a0f987317db651528b)では、pdf_generator.fetch_and_resize_image() が httpx.get() を直接呼び出しています。httpx 0.28.1 では、これにより proxy=None のクライアントが作成されるため、get_proxy()/set_proxy_manager() で設定されたプロキシが使用されず、PDF の画像リクエストによってオペレーターの IP が露出する可能性があります。

PR #692 を含むリリースにアップグレードするか、ソースからそのパッチを適用してください:

git fetch origin pull/692/head:pr-692
git checkout pr-692
python -m pip install -e ".[pdf]"

このパッチは、PDF のメディアダウンロードを get_proxy() 経由でルーティングし、get_global_timeout() を尊重し、プロキシが失敗した場合に直接接続へ暗黙的にフォールバックしないようにします。http://127.0.0.1:1 のような到達不能なプロキシを設定して修正を確認してください: メディアのダウンロードが失敗またはスキップされ、宛先サーバーが直接のリクエストを一切受け取らないことを確認します。フォークを維持している場合は、user_scanner/core/pdf_generator.py 内の直接の httpx.get() 呼び出しを、スキャナーの共有プロキシリクエストヘルパー、または get_proxy() と get_global_timeout() を使用する明示的なクライアントに置き換えてください。

参照 Issue #688
トラブル対応
マルチサイトの user-scanner スキャンで warmup_url が最初のサイトでのみ実行される問題を修正する方法

これは、コミット 780d077a468035c6afd6b4a0f987317db651528b における user-scanner 1.5.2.1 に影響します。_warmed キャッシュは (impersonate, proxy) のみをキーとしているため、クリアランス Cookie がサイト固有であるにもかかわらず、あるオリジンでウォームアップが成功すると、共有セッションが他のすべてのオリジンでもウォームアップ済みとしてマークされます。

影響を受けるコミットの2つ後のコミットでマージされた PR #680 を含む main ブランチのバージョンにアップグレードして修正してください:

python -m pip install -U git+https://github.com/kaifcodec/user-scanner.git@main

チェックアウトから作業している場合:

git pull origin main
python -m pip install -e .

アップグレードできない場合は、PR #680 を cherry-pick またはマージしてください。修正では、ウォームアップ状態をブラウザ/プロキシのみではなく、セッション/ブラウザに warmup_url またはオリジン固有のクリアランスコンテキストを加えたものでスコープする必要があります。失敗したウォームアップは、他のサイトの状態をクリアせずに再試行可能でなければなりません。一時的な回避策として、共有の _warmed セットがサイト間で再利用されないよう、各オリジンを個別のプロセスで実行してください。

同じブラウザでプロキシなしの状態で2つの異なるオリジンをリクエストして検証してください: 各オリジンは通常のリクエストの前に独自のウォームアップリクエストを1回送信し、繰り返しのリクエストではウォームアップ済みの状態が再利用され、同時実行または失敗したウォームアップが安全に処理されることを確認してください。

参照 Issue #689
トラブル対応
user-scanner Screener がすべてのメールアドレスに対して "Unexpected response body structure" を返す問題を修正するにはどうすればよいですか?

v1.5.1では、screener.inがエラーマークアップを<ul class="errorlist">から<ul class="errorlist" id="id_password_error">に変更したため、email_scan/other/screener.py内の完全一致文字列チェックが失敗します。68行目付近のマーカーチェックを、追加の属性を許容する正規表現に置き換えてください:

import re

_REQUIRED = re.compile(r'<ul class="errorlist"[^>]*>\s*<li>This field is required\.</li>')

if _REQUIRED.search(res_text):
    return Result.available(url=show_url)

以前のチェックは次のとおりです:

if '<ul class="errorlist"><li>This field is required.</li>' in res_text:
    return Result.available(url=show_url)

インストールされたパッケージファイルにパッチを適用した後、再実行してください:

user-scanner -e john.smith.4471@gmail.com -m screener --all

taken分岐は、プレーンテキストUser account with this Email already existsにマッチするため、影響を受けていない可能性が高いです。モジュールを保守する場合は、CSRF/トークンの欠落と分類不能なPOSTレスポンスに対して個別のエラーメッセージを使用し、将来のマークアップ変更を診断しやすくしてください。

参照 Issue #611