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

@scruple/security

v0.3.2

Published

Advisory semantic rules for security-sensitive code.

Readme

@scruple/security

Advisory semantic rules for security-sensitive JavaScript and TypeScript, packaged as a plugin for Scruple.

pnpm add --save-dev @scruple/security

Each rule examines a selected function and a limited excerpt from the same file. It never sends the entire file as surrounding context. The request records each size limit and whether any source was cut short.

  • security/no-user-controlled-authorization identifies visible authorization decisions that trust client-supplied authority claims such as roles, permissions, scopes, or tenant access.
  • security/no-sensitive-data-exposure identifies visible sensitive values sent to the deliberately bounded sink set below without visible projection, masking, or sanitization.
  • security/no-untrusted-command-execution checks direct request-controlled command or dynamic-code flows.
  • security/no-untrusted-mass-assignment checks direct request-object persistence and assignment.
  • security/no-unsafe-redirect checks direct request-controlled redirect targets.

The rules explicitly abstain when trust provenance, middleware, helper behavior, data sensitivity, or an access boundary is not established by the bounded evidence. A general security/require-permission-checks rule is intentionally not included: per-file function evidence cannot reliably prove that permission enforcement is absent from router middleware, decorators, framework policy, or callers.

Sensitive-output sink boundary

no-sensitive-data-exposure selects these statically named JavaScript/TypeScript calls:

  • Response/rendering: download, end, json, jsonp, redirect, render, respondWith, send, sendFile, sendStatus, write, and Response.json.
  • Files: imported appendFile, appendFileSync, writeFile, and writeFileSync; the corresponding fs/promises methods; Bun.write; and Deno.writeFile/Deno.writeTextFile.
  • Streams: pipe and pipeline.

Logging remains owned by observability/no-sensitive-logs. Unconfigured custom output wrappers are not guessed: when a helper contract or the destination is hidden, the rule preserves insufficient_context rather than assuming that the helper leaks or protects data.

Evidence budgets

A security request can include up to:

  • 4,000 characters from the function
  • 2,000 characters of surrounding code from the same file
  • 10 imports of up to 500 characters each
  • 20 calls of up to 1,000 characters each

The request records the original size and whether each section was cut short. These limits apply to the evidence sent to the provider, not to the source location used for the diagnostic.

The parser currently does not expose NewExpression or variable-initializer facts. Therefore the rule can select direct create/update/assignment flows, but cannot soundly prove the identity chain in const model = new Model(req.body); await model.save() without brittle source matching. Arbitrary .save() calls are intentionally not selected. Constructor-to-save support should be added once the parser exposes that relationship.

Security linting is not a security guarantee. These rules are advisory review signals, can miss vulnerabilities, and can report false positives. Use them alongside threat modeling, least-privilege design, code review, dependency and secret scanning, security tests, and runtime controls.

Follow the published quickstart, browse the rule registry, compare providers, or write a custom rule.