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

defang-sentinel

v1.1.0

Published

Defang and refang IOCs (hxxps://evil[.]com) in text, logs and reports with several styles, and a CI check that fails when threat reports, tickets or docs contain live, clickable or half-defanged URLs, domains, IPs or emails. CLI, library and GitHub Action

Readme

defang-sentinel

npm version CI Node License: MIT

Defang and refang indicators of compromise, and stop live malicious links from getting into threat reports, tickets and docs.

Threat-intel write-ups, incident tickets and detection repos are full of malicious URLs, domains and IPs. A single clickable https:// link to a C2 server in a Markdown report is an accident waiting to happen. defang-sentinel does three jobs:

  1. defang: rewrite live indicators as safe text (https://evil.com → hxxps://evil[.]com) in four styles.
  2. refang: turn defanged indicators back into usable ones for tooling (hxxps[://]evil[.]com → https://evil.com).
  3. check (default): scan files or directories and fail CI when a report contains live, clickable or half-defanged indicators.

CLI, library and GitHub Action. Node.js 18+, zero runtime dependencies.

Features

  • Detects URLs (http/https/ftp/sftp/ws), domains (validated against gTLD/ccTLD lists, with file names such as setup.py ignored), public IPv4/IPv6 addresses (private, loopback and documentation ranges ignored unless --include-private; version strings like v1.2.3.4 skipped) and email addresses.
  • Clickable link detection (live-link, high): Markdown links [text](https://…), reference links, autolinks <https://…> and HTML href attributes. Defanged link text doesn't help if the href is still live.
  • Half-defanged detection (partial-defang): hxxp://evil.com or evil[.]com.badhost.ru look safe at a glance but still contain a live host.
  • Reference allowlist: links to MITRE ATT&CK, NVD, CVE.org, CISA, NCSC, VirusTotal, abuse.ch, urlscan, GitHub and others are expected in reports and allowed by default (--no-reference-domains turns this off). Add your own with --ignore-domain or ignoreDomains in the config.
  • Defang styles (--style): brackets (default) hxxps://www[.]evil[.]com/a.php, full hxxps[://]www[.]evil[.]com/a[.]php, dot hxxps://www[dot]evil[dot]com, minimal hxxps://www.evil[.]com. Emails become user[@]domain[.]com; IPv6 colons become [:].
  • Refang understands hxxp, hXXps, h[xx]p, fxp, [.], (.), {.}, [dot], (dot), \., [:], [://], [@], (at), [at].
  • defang/refang can rewrite files in place (--write) and are idempotent. Defanging already-defanged text changes nothing.
  • check walks directories for text formats (.md, .txt, .html, .csv, .json, .yml, .eml, .log, .yar…; change with --ext), skips binaries and node_modules, and can ignore fenced code blocks (--skip-code).

Fix mode, code-aware rewriting and hooks

defang-sentinel check --fix --skip-code docs/      # defang live IOCs in place, leave code blocks alone
defang-sentinel defang --style paren report.md     # hxxps://evil(.)com
defang-sentinel hook install                        # git pre-commit hook

Styles: brackets, full, dot, minimal, paren, colon. refang(defangValue(x, type, style)) === x for every style.

Library: import { defangText, refangText, refangValue, defangValue, fix, installHook, splitCode } from 'defang-sentinel' (or require). This is the stable defang/refang API that other packages (e.g. ioc-sentinel) build on.

pre-commit framework users can add repo: https://github.com/MrLouisWright/defang-sentinel with hook id defang-sentinel or defang-sentinel-fix.

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 | |---|---|---| | live-link | high | Clickable Markdown/HTML link or autolink to a live URL | | live-url | high | URL not defanged | | partial-defang | medium | Token carries defang markers but still has a live host | | live-domain | medium | Domain not defanged | | live-ip | medium | Public IPv4/IPv6 not defanged | | live-email | low | Email address not defanged |

Install and run

echo 'C2: https://evil.com/gate.php 45.9.148.3' | npx defang-sentinel defang -
# C2: hxxps://evil[.]com/gate.php 45[.]9[.]148[.]3

npx defang-sentinel refang iocs.txt > iocs-live.txt
npx defang-sentinel defang --write reports/2026-10-apt.md

npx defang-sentinel reports/ --skip-code --ignore-domain 'mycompany.com,*.mycompany.com'

Library

import { defangText, refang, defangValue, check } from 'defang-sentinel';

defangText('see https://evil.com', { style: 'brackets' }).text; // 'see hxxps://evil[.]com'
refang('hxxps[://]evil[.]com');                                  // 'https://evil.com'
defangValue('[email protected]');                                     // 'bad[@]phish[.]ru'
const report = check(['reports/'], { skipCode: true });

Configuration

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

{
  "failOn": "medium",
  "severity": { "live-url": "high" },
  "allow": [
    { "rule": "live-url", "match": "*cdn.example.net*", "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 live-* 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 medium).
  • 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/defang-sentinel@v1
    with:
      targets: 'reports/'
      fail-on: medium
      sarif: defang-sentinel.sarif
  - uses: github/codeql-action/upload-sarif@v3
    if: always()
    with: { sarif_file: defang-sentinel.sarif }

Inputs: targets, fail-on, config, sarif, json, job-summary (Markdown report in the job summary, default true), args (extra CLI flags), ignore-domains. 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 defang-sentinel helps you, a link back is appreciated:

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

License

MIT © Louis Wright (Louis Wright)