Get started in 2 minutes
1. Install
You need Python 3.10–3.13 (3.13 recommended). Install it as a standalone tool:
uv tool install malware-detector-pypipx install malware-detector-pydocker pull ghcr.io/benzid-wael/malware-detector:latestThat single install includes the core engines (Semgrep and GuardDog). You don't need to install anything else.
Check that it worked:
malware-detector --helpShorter name
Every command also works as mdetect, e.g. mdetect scan .
Python 3.14 isn't supported yet
One of GuardDog's dependencies (pygit2) has no Python 3.14 build yet. If your default Python is 3.14, use uv tool install --python 3.13 malware-detector-py.
2. Scan something
From the root of any project:
malware-detector scan .A clean project looks like this:
✓ malware-detector: no findings in .
Scanned 42 files (Python 30 · JavaScript 12) with semgrep + heuristics in 2.4s.The last line confirms what was checked, so a clean result means something.
If something is found, you get a ranked list, with the most serious findings first:
malware-detector: CRITICAL — 2 finding(s) in .
[CRITICAL] scripts/sync.py:4 py-env-exfiltration
Environment / credential data flows to a network sink.
[MEDIUM] scripts/sync.py:3 sensitive-credential-file-access
Reference to a credential / secret-bearing file path (possible credential harvesting).
Scanned 42 files (Python 30 · JavaScript 12) with semgrep + heuristics in 2.4s.Add --explain to see which engine raised each finding and the line it matched.
Dependency and build directories (node_modules, .venv, dist, vendor, minified bundles…) are skipped by default, so the report covers your code. Change that →
3. Vet a package before you trust it
Download a package and scan it before you add it as a dependency:
npm pack some-package && tar xzf some-package-*.tgz
malware-detector deps ./package4. Make it automatic
A one-off scan is useful. Running it on every change is where it really pays off. Pick one:
- Git hook: blocks malicious code before it is committed. Takes 30 seconds to set up.
- CI: gates every pull request and sends alerts to GitHub's Security tab.
What's next
- Reading the results: severities, exit codes, JSON and SARIF.
- Suppressing findings: accept a known false positive once, with a reason.
- How it works: what runs when you press enter.