A production-grade, high-performance, and secure security operations toolkit designed to scan, detect, remediate, and merge fixes for supply-chain malware injections across an entire GitHub Organization or a local environment.
In modern software ecosystems, supply-chain attacks are increasingly stealthy and destructive. A common vector involves injecting malicious payloads that steal sensitive environment credentials (such as AUTH_API_KEY) and transmit them to rogue endpoints.
This toolkit was engineered to combat a specific, highly evasive malware strain that attempts to run arbitrary code using several signatures:
- The Stealth IIFE Block: A multi-line Immediately Invoked Function Expression (IIFE) that reads
process.env.AUTH_API_KEY, decodes a remote payload viaatob(), and runs it viaeval(proxyInfo). - The Obfuscated Line Suffix: Suffix injections hidden behind 50+ spaces of whitespace at the end of otherwise normal code lines, executing
global['!']oreval(atob(...)). - Standalone Evals: Direct
eval(proxyInfo)oreval(atob(...))calls. - Leaked Credentials: Committed
.envfiles containingAUTH_API_KEYcredentials in repository histories.
Standard security scanners often fall short because scanning hundreds of repositories with active checkouts can trigger local Git hooks (pre-checkout, post-checkout, etc.) embedded in the malicious code, executing the malware during the scan.
This suite solves this by utilizing bare clones, no-shell command execution, and deterministic parsing to safely scan, remediate, and merge fixes without executing a single line of malicious repository code.
- Inert Bare Cloning (
--bare): The remote scanner clones only the repository's Git database without checking out files into a working directory. This completely bypasses all git hooks, neutralizing hook-based execution vectors. - Shallow Fetching (
--depth 1 --no-single-branch): Pulls down only the tip commit of every branch, bypassing decades of commit history. This minimizes network traffic and disk utilization when scanning hundreds of repositories. - No-Shell Process Execution (
execFile): Replaces vulnerableexeccalls withexecFile. Branch names and other parameters are passed as direct array elements to thegitbinary instead of being parsed by a system shell, neutralizing command-injection vulnerabilities. - Token Redaction & Privacy: All standard output, error messages, and logs are wrapped by a redaction parser. The GitHub PAT is automatically masked (
***REDACTED***) before write or screen log operations. - Batching and Rate Limit Resilience: Executes scans in concurrent queues of 10 with a 1-second delay between batches, respecting GitHub's secondary rate limits and preventing local file descriptor exhaustion.
- Strict Garbage Collection: All temporary cloning operations (under
/tmp/git-scannerand/tmp/git-fixer) are wrapped intry...finallyblocks to guarantee immediate directory deletion, even on failure.
- Node.js (v18+ recommended)
- Git CLI installed and authenticated
- Clone this repository locally.
- Install dependencies:
pnpm install
- Copy the environment configuration template:
cp .env.example .env
- Edit
.envto configure your tokens and target. By default, the scan targets organizations (GITHUB_ACCOUNT_TYPE=org). Set it touserto scan a personal user account, orall-orgsto scan all organizations the authenticated user belongs to:GITHUB_TOKEN=github_pat_your_token_here GITHUB_ACCOUNT_TYPE=org ORG_NAME=your-github-org-name REPORT_OUTPUT_DIR=./reports LOCAL_SCAN_PATH=../my-workspace GIT_TIMEOUT=60
The suite consists of four primary scripts, each covering a specific stage of the detection and remediation lifecycle.
graph TD
A[scanner.js] -->|Generates reports/| B(JSON / HTML / MD Reports)
C[local_scanner.js] -->|Generates local_reports/| D(JSON / HTML / MD Reports)
B -->|Inputs into| E[remediator.js]
E -->|Creates Security Fix PRs| F[GitHub Organization]
F -->|PRs merged by| G[merger.js]
Scans all repositories in the configured GitHub Organization across all branches for malware signatures.
- Run Command:
pnpm start [options]
- Options:
--limit=<number>: Restricts the scan to the first N repositories (useful for verification testing).
- Environment Configuration:
GITHUB_TOKEN: The GitHub PAT with permission to list and clone repositories (requiresreposcope for private user repositories).GITHUB_ACCOUNT_TYPE: Set toorg(default) for a single GitHub Organization,userto scan a personal user account, orall-orgsto scan all organizations the user belongs to.ORG_NAME: Target GitHub Organization name. Required ifGITHUB_ACCOUNT_TYPEisorg, ignored/optional ifuserorall-orgs.EXCLUDE_ORGS(Optional): Comma-separated list of organization names to skip when usingall-orgsmode.REPORT_OUTPUT_DIR: Target folder for the generated reports (defaults to./reports).SCAN_LIMIT(Optional): Restricts the scan to the first N repositories. The--limitCLI flag overrides this setting if both are present.TEST_REPO_NAME(Optional): Restricts scanning to a single repository for testing.
- Output:
reports/security_audit_report.json: Flat and nested statistics of all scanned, clean, and infected repositories.reports/security_audit_report.md: Markdown summary tables listing infections.reports/security_audit_report.html: An interactive dark-mode dashboard to search, filter, and inspect findings.
A dependency-free tool that recursively scans local directories for the same malware signatures. Ideal for pre-commit checks, CI/CD pipelines, or offline audits.
- Run Command:
pnpm scan-local [options]
- Options:
--path=<dir>: The target local directory to scan. If omitted, readsLOCAL_SCAN_PATHfrom.env. If the target directory contains a.gitorpackage.json, it is scanned as a single project. Otherwise, each subdirectory is scanned as an independent project.--output=<dir>: The output directory for reports (defaults to./local_reports).-h, --help: Displays the help message.
- Output:
- Generates
security_audit_report.json,security_audit_report.md, andsecurity_audit_report.htmlunder./local_reports/.
- Generates
Processes the infected repositories found by the scanner, removes the malicious code blocks, and prepares patches.
Warning
By default, the remediator runs in Dry-Run Mode to safely preview modifications. You must explicitly supply the --run flag to execute live changes on GitHub.
- Run Command:
pnpm remediate [options]
- Options:
--run: Disables Dry-Run mode. Performs live commits, pushes, and PR creation.--direct-push: Pushes cleaned branches directly to their remote tracking branches (bypasses PR creation).--repo=<owner/repo>: Restricts remediation to a single repository.--branch=<name>: Restricts remediation to a specific branch name.--limit=<number>: Limits execution to the first N infected repositories.--offset=<number>: Skips the first N repositories (useful for chunking/batching).--timeout=<seconds>: Set a custom execution timeout for Git commands (defaults to60).-h, --help: Displays the help menu.
- How Cleanup Works:
- Clones the repository locally.
- Dynamically locates compromised branches (via
reports/security_audit_report.jsonor live analysis). - Deletes any committed
.envfiles containingAUTH_API_KEY. - Parses source code line-by-line using precise regular expressions to remove the IIFE malware blocks, trailing line obfuscation, and standalone evals without affecting legitimate surrounding code.
- In Dry-Run Mode: Outputs a
git diffto the terminal and discards changes. - In Live Mode: Commits the clean code and pushes. By default, it pushes to a new branch (
security-fix/[branch-name]-[random-id]) and opens a Pull Request on GitHub. With--direct-push, it pushes directly into the infected branch.
Locates and merges the security pull requests created by the Remediator script.
Warning
By default, the merger runs in Dry-Run Mode. You must explicitly supply the --run flag to execute merges.
- Run Command:
pnpm merge-prs [options]
- Options:
--run: Disables Dry-Run mode. Squash-merges open PRs and deletes their temporary remote branches.--limit=<number>: Restricts execution to the first N pull requests.-h, --help: Displays the help menu.
- How it Works:
- Searches the organization for open Pull Requests containing
"Security Fix:"in the title. - Squash-merges each matching PR using the message:
security: merge automated supply-chain fix for [target-branch]. - Deletes the temporary source branch on GitHub.
- Gracefully skips conflict-blocked PRs or branches blocked by branch-protection rules to process remaining entries.
- Searches the organization for open Pull Requests containing
A utility tool to recursively scan local directories for Git repositories and convert their remote tracking URLs from HTTPS to SSH format (e.g. converting https://github.com/owner/repo.git to git@github.com:owner/repo.git). This is helpful when switching authentication methods or credential configurations across many checked-out repositories.
- Run Command:
pnpm to-ssh [options]
- Options:
--path=<dir>: The target local directory to scan recursively for git repositories. If omitted, defaults to the current working directory.--concurrency=<number>: Concurrency limit for processing repositories (default:20).--run: Disables Dry-Run mode. Performs live remote URL updates in git configs.-h, --help: Displays the help menu.
- How it Works:
- Recursively locates all Git repositories containing
.gitdirectories, skipping common build/dependency folders (likenode_modules,dist,build, etc.). - Identifies all remote configurations for each repository.
- Converts HTTPS URLs to SSH format.
- Redacts any HTTP/HTTPS credentials/tokens in output logs to prevent token leakage.
- In Dry-Run Mode: Logs the proposed URL changes without saving.
- In Live Mode: Updates the git configuration for the matching remotes via safe command execution.
- Recursively locates all Git repositories containing
The HTML dashboards (security_audit_report.html) generated by both the Remote and Local scanners feature dynamic dark-themed UIs built on top of JetBrains Mono and Inter. They allow operators to search, filter by scan status, and review the exact line numbers and code snippets flagged during the audit.
Due to browser security policies regarding local file access (CORS), opening the HTML file directly in a browser via the file:// protocol may fail to fetch the corresponding JSON report.
To load the dashboard with its data, run a simple local web server from your report directory:
# Serve Remote Reports
npx http-server ./reports
# Serve Local Reports
npx http-server ./local_reportsThen navigate to the URL printed in the terminal (typically http://localhost:8080).
To perform a safe, end-to-end audit and repair cycle, follow these stages:
Run a full organization scan to generate the threat report:
pnpm startVerify the changes that the remediator will make. Review the printed diffs to ensure no legitimate code is broken:
pnpm remediateRun the remediator with live execution. This pushes changes to separate branches and creates pull requests on GitHub for peer review:
pnpm remediate --runAfter auditing the created PRs, automate the merging process to close the security loop:
pnpm merge-prs --run