Pre-clone security scanner for GitHub repositories.
Built the night I was targeted by a North Korean APT recruitment scam.
Note: VS Code 1.109+ (February 2026) disables automatic task execution by default. Older versions remain vulnerable, the
.githooks/vector is unaffected by the patch, and the VS Code fix can be socially engineered around via the workspace trust prompt.
pip install repo-guard
# Scan a public repository
repo-guard scan https://github.com/owner/repo
# With a GitHub token for higher rate limits or private repos
repo-guard scan https://github.com/owner/repo --token ghp_xxxx
# Machine-readable JSON output
repo-guard scan https://github.com/owner/repo --jsonWhy this tool exists
A recruiter contacted me on LinkedIn — fake persona, impossible job history, claimed CEO of a real crypto startup. Offered a paid advisory role and invited me to review a GitHub repository as the first step. Standard playbook.
Before running anything, I inspected the code manually. What I found:
.vscode/tasks.jsonconfigured to silently execute code the moment the project opens in VS Code — no prompt, no warning.githooks/post-checkoutdownloading and executing a remote payload from an external server across Mac, Linux, and Windows simultaneously, all output suppressed behind 40 lines of decoy comments- Private key social engineering via the .env.local README instruction, a backup vector in case the malware delivery fails or gets caught
The campaign is consistent with documented North Korean Lazarus Group / Contagious Interview recruitment scams targeting Web3 developers. Reports were filed with the FBI IC3, RCMP, Vercel, GitHub, LinkedIn, and Basescan.
No existing tool caught this. So I built one.
Most security tooling focuses on dependencies and known malware signatures. Nobody was scanning:
.vscode/tasks.jsonfor auto-execution configuration.githooks/for hidden payload delivery- Repository metadata for trust signals (account age, suspended contributors, force-push history)
These are the exact vectors used in developer-targeted APT campaigns.
repo-guard fills that gap. It is not a replacement for Snyk, Socket.dev,
or npm audit — those run after you clone. This runs before.
repo-guard fetches repository metadata via the GitHub API without cloning. It runs four independent modules and produces a color-coded risk report.
| Module | What It Detects |
|---|---|
| Trust Score | Account/repo metadata heuristics — age, followers, contributors, force-push indicators |
| Hook Scanner | Malicious git hooks in .githooks/ — execution patterns, base64 payloads, comment-to-code ratio |
| VS Code Scanner | Auto-execution configuration in .vscode/tasks.json and .vscode/settings.json — runOn: folderOpen, allowAutomaticTasks |
| IOC Extractor | Indicators of compromise — URLs, domains, Ethereum addresses, IPs, base64 payloads — with optional VirusTotal enrichment |
Usage: repo-guard scan [OPTIONS] GITHUB_URL Scan a GitHub repository for security risks without cloning. Options: --token TEXT GitHub Personal Access Token (or set REPO_GUARD_TOKEN). --vt-key TEXT VirusTotal API key for IOC enrichment (or set REPO_GUARD_VT_KEY). --json Output results as JSON. --preview Preview suspicious file contents in terminal. --recruiter TEXT Recruiter context: LinkedIn URL or message text. --help Show this message and exit.
# Scan with recruiter context
repo-guard scan https://github.com/owner/repo --recruiter "linkedin.com/in/recruiter"
# Preview flagged files without downloading
repo-guard scan https://github.com/owner/repo --preview
# With VirusTotal enrichment
repo-guard scan https://github.com/owner/repo --vt-key vt_xxxx
# Pipe JSON to jq
repo-guard scan https://github.com/owner/repo --json | jq '.modules[].severity'Detection is entirely deterministic — scored signals, regex patterns, and API lookups. No repository contents are sent to external AI APIs.
Public repositories only by default. Private repository scanning requires
a GitHub personal access token (--token).
- Not a replacement for a full security audit
- Public repos only without
--token - VirusTotal free tier: 500 lookups/day
--previewand--recruiterflags are scaffolded, full implementation coming in v0.2.0
- Python 3.10+
requests,rich,click(installed automatically)
git clone https://github.com/WBChain3/repo-guard
cd repo-guard
pip install -e ".[dev]"
# Run tests
pytest
# Run with coverage
pytest --cov=repo_guardAll tests use mocked HTTP and on-disk fixtures. No live API calls.
repo_guard/
├── repo_guard/
│ ├── cli.py
│ ├── github_client.py
│ ├── models.py
│ ├── reporter.py
│ └── modules/
│ ├── trust_score.py
│ ├── hook_scanner.py
│ ├── vscode_scanner.py
│ └── ioc_extractor.py
├── tests/
│ ├── fixtures/
│ │ ├── flexpay_mock/
│ │ └── clean_repo/
│ ├── conftest.py
│ └── test_*.py
├── ARCHITECT_DECISIONS.md
├── IOC_FEED.md
└── pyproject.toml
See IOC_FEED.md for findings from real-world scans. Community IOC submissions welcome - open an issue or PR.
MIT
