npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@flagrix/scanner-core

v0.3.1

Published

Core security scanning logic for Flagrix — GitHub repo scanner and user profile scorer

Downloads

1,075

Readme

@flagrix/scanner-core

Open-source scanning engine behind Flagrix — detects malware, backdoors, and supply-chain attacks in GitHub repositories and GitHub profiles.

Built after real-world fake-recruiter campaigns ("coding assignment" repos that steal wallets, SSH keys, and browser sessions) started targeting developers. Flagrix scans before you clone.

What it detects

  • Known malicious npm packages (active campaign IOCs, typosquats)
  • Obfuscated JavaScript (hex arrays, eval chains, base64 droppers)
  • Supply-chain attacks (dependency confusion, install-time scripts)
  • Backdoors, reverse shells, and data-exfiltration patterns
  • Crypto miners and credential/wallet stealers
  • Suspicious install hooks (postinstall, curl-pipe-bash)
  • Social-engineering markers and repository anomalies

Signature data lives in the sibling repo flagrix-detection-rules.

Privacy — everything runs locally

All analysis happens on the caller's device — there is no Flagrix backend and no telemetry. The library's only network calls are to api.github.com (file contents and profile data) and api.npmjs.org (package download counts for typosquat checks). Nothing that gets scanned — file contents, repo names, results — is sent to Flagrix or any third-party server. The optional githubToken is used exclusively as an Authorization header on GitHub API requests; it is never transmitted anywhere else.

What gets scanned

A repo scan reads code files (.js, .jsx, .mjs, .cjs, .ts, .tsx, .py, .rb, .php, .go, .sh, .ps1, .psm1, .bat, .cmd, .vbs) plus dependency manifests (package.json, lockfiles, requirements.txt, setup.py, and similar), capped at 200 files and 1 MB per file per scan. Everything else — docs, images, data files, oversized blobs — is skipped, and the result says so: scanSummary.scannedFiles lists every file that was read, and scanSummary.skippedFiles lists what was skipped with a per-file reason (unsupported-type, over-file-limit, too-large, fetch-failed).

Usage

import { scanGitHubRepo, type SignatureDatabase } from "@flagrix/scanner-core"

const result = await scanGitHubRepo(
  { owner: "some-org", repo: "some-repo", branch: "main", url: "https://github.com/some-org/some-repo" },
  { signatures, githubToken } // token optional — raises rate limits, enables private repos
)

console.log(result.riskLevel) // "low" | "medium" | "high"
console.log(result.findings)  // detailed findings with severity + evidence
console.log(result.commitSha) // the exact commit the verdict applies to

Scans are pinned: the branch is resolved to a commit SHA up front and every file is read at that SHA, so a push mid-scan (or between scan and clone) can't invalidate the verdict silently — compare commitSha against the head you actually check out.

Also exported: scanGitHubUser (profile authenticity scoring) and the shared risk-calculation utilities. See src/index.ts for the full API.

The package also ships standalone scoreLinkedInProfile and scanPdfBytes / scanPdfFromUrl scanners. These aren't wired into the current Flagrix extension (which is GitHub-only) or backed by rules in flagrix-detection-rules — they're available for anyone building on the library, but should be treated as unmaintained until that changes.

GitHub API rate limits

scanGitHubRepo and scanGitHubUser call the GitHub REST API directly. A single repo scan issues one tree request plus up to 200 file-content requests (most repos need far fewer). Unauthenticated, GitHub allows 60 requests/hour — enough for scans of small repos. Pass a githubToken (a fine-grained or classic PAT, public_repo/repo scope) in the options to raise this to 5,000 requests/hour and to scan private repositories:

await scanGitHubRepo(repo, { signatures, githubToken })

Risk scoring

Findings are weighted by severity (critical 0.4, high 0.25, medium 0.15, low 0.05, info 0.01), summed, and capped at 1.0. The pre-cap sum is also returned as rawRiskScore, and factors[] carries one entry per deduped signal with the confidence-adjusted weight actually counted — factor weights always sum to rawRiskScore, so a consumer-rendered deduction breakdown reconciles with the score. getRiskLevel maps the score to a level using the shared RISK_THRESHOLDS (< 0.3 low, < 0.6 medium, otherwise high) — with one override: a single critical finding always forces high, since a lone backdoor or keylogger shouldn't average down to "review before cloning" just because nothing else in the repo was flagged. Pass findings as the scanner does (getRiskLevel(score, findings)) to get this floor; omit it to fall back to threshold-only scoring. The GitHub user scanner uses its own tuned thresholds because profile signals (account age, follower ratios) distribute differently from code findings.

Development

npm install
npm run build   # tsc → dist/
npm test        # vitest

Pure TypeScript with a single runtime dependency (franc-min for language detection). Callers inject network and storage — the primary consumer is the Flagrix Chrome extension, which currently uses the GitHub repo and profile scanners and supplies fetch results and signature data. See CONTRIBUTING.md to add a detector or report a false positive.

Disclaimer

Risk assessments are informational, not definitive malware or fraud determinations. Always verify through official channels.

AI Disclosure

This project leverages Claude AI for boilerplate generation, test-suite expansion, and optimization. All AI-generated code is strictly reviewed, refactored, and verified by human maintainers before merging.

License

MIT — see LICENSE.


Part of the Flagrix open-core security platform.