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

ioc-sentinel

v1.1.0

Published

IOC extractor for threat intel and incident response: pulls URLs, domains, IPv4/IPv6, emails, MD5/SHA1/SHA256/SHA512, CVEs, ATT&CK IDs, crypto wallets and registry keys from text, logs and reports, refangs defanged IOCs, filters noise and exports JSON, CS

Downloads

62

Readme

ioc-sentinel

npm version CI Node License: MIT

Extract indicators of compromise from threat reports, logs, emails and binaries, then export them as CSV, STIX 2.1, JSON or SARIF.

ioc-sentinel pulls IOCs out of any text: URLs, domains, IPv4/IPv6 addresses, email addresses, MD5/SHA1/SHA256/SHA512 hashes, CVE IDs, MITRE ATT&CK IDs, Bitcoin/Ethereum/Monero wallets, Windows registry keys and suspicious file names. It refangs defanged indicators (hxxps://evil[.]com, user[@]domain(dot)ru) before matching, removes the usual noise (private IPs, example.com, XML namespaces, setup.py-style file names) and can fail a pipeline when an IOC matches your watchlist.

CLI, library and GitHub Action. Node.js 18+, zero runtime dependencies. Binaries are never executed: printable ASCII and UTF-16LE strings are read statically.

Features

  • 16 IOC types: url, domain, ipv4, ipv6, email, md5, sha1, sha256, sha512, cve, attack, btc, eth, xmr, registry, filename (shortcuts: hash, ip, wallet).
  • Refanging: hxxp, hXXps, fxp, [.], (.), {.}, [dot], \., [:], [://], [@], (at).
  • Noise reduction: domains are checked against the gTLD/ccTLD list. Names ending in file extensions (.exe, .py, .md, .zip...) count as file names unless the analyst defanged them. Private, loopback, CGNAT, documentation, multicast and reserved IPs are dropped unless you pass --include-private. Repetitive hashes (000…) are ignored, Ethereum addresses aren't mistaken for SHA1, and legacy Bitcoin addresses are Base58Check-validated. A built-in benign-domain list can be replaced (--benign) or disabled (--no-benign).
  • Watchlist (-w known-bad.txt): one IOC per line, defanged values accepted, with an optional label after a space, tab or comma. Supports IPv4 CIDR ranges, parent domains (evil.com also matches cdn.evil.com and URLs on it) and URL prefixes. Hits produce watchlist-match (critical), so the default --fail-on critical fails only on known-bad indicators.
  • Inputs: files, whole directories (skips .git and node_modules), or stdin (-). Binary files are scanned via static string extraction.
  • Exports: --format csv|stix|list or --csv/--stix <file>, with --defang to make CSV/list output safe to paste. The STIX 2.1 bundle contains indicators with proper patterns ([file:hashes.'SHA-256' = '…']), plus vulnerability and attack-pattern objects for CVEs and ATT&CK IDs, using deterministic IDs. The JSON report has a deduplicated iocs array with counts and file:line sources.

Normalise, dedupe, export to MISP / OpenIOC

ioc-sentinel report.md --format misp > event.json      # MISP 'Add event from JSON'
ioc-sentinel report.md --openioc iocs.ioc --stix iocs.stix.json
ioc-sentinel sandbox.log --noise extended              # also drop microsoft.com, google.com, CDNs, CAs
  • IOCs are normalised (case, trailing dots, IPv6 compression, default ports) and deduplicated across defang variants.
  • Common resolver IPs and documentation domains are dropped as noise by default; watchlist entries always win.
  • Each IOC records where it came from: line, column, offset, and every occurrence in the aggregated report.
  • Refanging is provided by defang-sentinel; use that package directly if you only need defang/refang.

Module formats and types

Ships ESM and CommonJS (import and require both work, via exports), with TypeScript declarations generated from the source at build time. Tests run on Node 18/20/22 in GitHub Actions (test/), including require/import checks against the packed tarball; releases are published with npm provenance.

Rules

| Rule | Default | Meaning | |---|---|---| | watchlist-match | critical | IOC matches the watchlist | | ioc-url | medium | URL | | ioc-hash | medium | MD5/SHA1/SHA256/SHA512 | | ioc-crypto-wallet | medium | BTC/ETH/XMR address | | ioc-domain, ioc-ipv4, ioc-ipv6, ioc-email, ioc-registry-key | low | Network and host indicators | | ioc-file-name, ioc-cve, ioc-attack-technique | info | Context |

Use per-rule severity to tune what fails a build, e.g. make ioc-crypto-wallet critical in a repository that should never contain wallets.

Install and run

npx ioc-sentinel report.pdf.txt                       # human-readable list, grouped by file
npx ioc-sentinel ./case-42/ --format csv --defang > iocs.csv
cat alert.eml | npx ioc-sentinel - -w known-bad.txt   # exit 1 on a watchlist hit
npx ioc-sentinel logs/ --types url,domain,ip --stix iocs.stix.json --sarif iocs.sarif

Library

import { extract, refang, defang, scan, formatStix } from 'ioc-sentinel';

extract('C2: hxxp://evil[.]com/gate 185.220.101[.]4');
// [{ type: 'url', value: 'http://evil.com/gate', defanged: true, line: 1, ... }, { type: 'domain', ... }, { type: 'ipv4', ... }]

const report = scan(['./incident'], { watchlist: 'evil.com\n185.220.101.0/24' });
report.iocs;              // deduplicated, with counts and sources
formatStix(report);       // STIX 2.1 bundle

Configuration

Put a .ioc-sentinel.json in the working directory (or pass --config <file>). Every key is optional; CLI flags override the file.

{
  "failOn": "critical",
  "severity": { "ioc-ipv4": "high" },
  "allow": [
    { "rule": "ioc-ipv4", "match": "8.8.8.8", "reason": "Accepted risk, ticket SEC-123", "expires": "2027-03-31" }
  ]
}
  • severity changes the severity of any rule, or turns it off.
  • allow suppresses findings. Each entry needs a rule (globs such as ioc-* work) and a reason, and can be narrowed with target and match (a glob tested against the target, location and value). Suppressed findings are listed in the JSON report. When expires (YYYY-MM-DD) has passed, the finding comes back together with an allow-expired finding, so exceptions can't be forgotten. Entries that match nothing are reported as allow-unused (info).

Output and exit codes

  • --format text|json|sarif|markdown for stdout, plus --json, --sarif and --markdown <file> to write extra copies in one run. SARIF 2.1.0 works with GitHub code scanning.
  • --fail-on critical|high|medium|low|info|none (default critical).
  • Exit code 0: passed. 1: at least one finding at or above --fail-on. 2: usage or config error, or a target could not be checked.
  • --list-rules prints every rule with its default severity.

GitHub Action

permissions:
  contents: read
  security-events: write   # only for the SARIF upload
steps:
  - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
    with: { persist-credentials: false }
  - uses: MrLouisWright/ioc-sentinel@v1
    with:
      targets: 'reports/'
      fail-on: critical
      sarif: ioc-sentinel.sarif
  - uses: github/codeql-action/upload-sarif@v3
    if: always()
    with: { sarif_file: ioc-sentinel.sarif }

Inputs: targets, fail-on, config, sarif, json, job-summary (Markdown report in the job summary, default true), args (extra CLI flags), watchlist, types, stix, csv. Outputs: markdown-file, exit-code.

Requirements

Node.js 18 or newer. No runtime dependencies.

Support

If this project is useful to you, you can support its development with a donation: Buy me a coffee. It helps keep these tools maintained, documented and free for everyone.

Credit (optional)

Free to use under MIT, no attribution required. If ioc-sentinel helps you, a link back is appreciated:

<a href="https://louiswright.co.uk">Built with ioc-sentinel by Louis Wright</a>
[![Built with ioc-sentinel by Louis Wright](https://img.shields.io/badge/built%20with-ioc--sentinel-blue)](https://louiswright.co.uk)

License

MIT © Louis Wright (Louis Wright)