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

cookie-sentinel

v1.1.1

Published

Audit Set-Cookie headers for security issues: missing Secure/HttpOnly/SameSite, __Host-/__Secure- prefix violations, broad Domain/Path, long expiry, cookies over HTTP, oversized cookies, JWTs and emails in values, duplicates and Partitioned misuse, with a

Readme

cookie-sentinel

CI npm version License: MIT Node

Audit the cookies your site sets before attackers do.

cookie-sentinel fetches your pages (following every redirect), collects every Set-Cookie header from every hop and audits each cookie against modern browser rules and security best practice. Every finding comes with a severity and a concrete fix. It also audits raw Set-Cookie lines offline from a file or stdin.

cookie-sentinel is the dedicated cookie authority in the sentinel set — use header-sentinel for HTTP security headers only (it keeps a minimal cookie presence check and points here for depth).

CLI, library and GitHub Action. Node.js 18+, zero runtime dependencies. Optional Playwright / Puppeteer peer dependencies for JavaScript-set cookies.

Tests live under test/ and run in GitHub Actions CI (including import + require checks).

Rules

| Rule | Default severity | What it catches | |---|---|---| | missing-secure | high (session-like) / medium | Cookie on an HTTPS site without Secure | | cookie-over-http | high (session-like) / medium | Cookie set by a plain http:// response | | missing-httponly | high | Session-like cookie (configurable name patterns) without HttpOnly | | samesite-missing | medium (session-like) / low | No SameSite attribute | | samesite-none | medium (session-like) / low | SameSite=None (cross-site sending, CSRF exposure) | | samesite-none-insecure | high | SameSite=None without Secure: browsers reject it | | samesite-invalid | medium | SameSite value that isn't Strict/Lax/None | | host-prefix | high | __Host- cookie without Secure, with Domain, without Path=/, or set over HTTP; mis-cased prefixes | | secure-prefix | high | __Secure- cookie without Secure or set over HTTP | | broad-domain | medium (session-like) / low; high for a TLD | Domain= a parent domain (sent to and overwritable by every subdomain) or Domain on a session cookie | | domain-mismatch | low | Domain that doesn't match the host (cookie rejected) | | broad-path | info | Sensitive cookie with Path=/ | | long-expiry | medium (session-like > 30 days) / low (> 400 days) | Excessive Expires/Max-Age | | large-cookie | low (> 3072 B) / medium (> 4096 B) | Very large cookies | | sensitive-jwt | medium; high without HttpOnly | JWT in a cookie value (payload claims are readable) | | jwt-alg-none | critical | Unsigned JWT (alg: none) | | sensitive-email | medium | Email address in a value (plain, URL-encoded, base64 or JWT claims) | | duplicate-cookie | low / medium | Same cookie set twice in one response, or one name set with different Domain/Path scopes (cookie tossing) | | partitioned-insecure | high | Partitioned without Secure | | partitioned-misuse | low | Partitioned without SameSite=None, or on session cookies |

Deletion cookies (Max-Age<=0 or an expiry in the past) are ignored. Default session-like names include sess, sid, auth, token, jwt, login, remember, access, refresh, PHPSESSID, JSESSIONID, connect.sid and others. csrf/xsrf cookies are excluded from the HttpOnly check.

Classification (Open Cookie Database)

Each cookie is classified offline against a bundled snapshot of the Open Cookie Database (no network at runtime):

  • Party: first-party vs third-party (from Domain / page host)
  • Purpose: tracking vs essential (from OCDB category)
  • Vendor / category when the name matches the catalogue

Refresh the snapshot when you maintain the package:

npm run update-ocdb

Install and run

npx cookie-sentinel https://example.com
npx cookie-sentinel https://example.com -p /login -p /account --fail-on medium
npx cookie-sentinel https://app.example.com --crawl urls.txt          # URLs or paths, one per line
npx cookie-sentinel https://app.example.com --crawl-depth 2 --max-pages 40   # follow same-origin links
npx cookie-sentinel https://app.example.com/account -H "Cookie: session=…"   # audit logged-in pages
npx cookie-sentinel https://app.example.com --headers-file auth.json --cookies-file jar.txt
npx cookie-sentinel https://app.example.com --browser playwright      # optional peer dep
COOKIE_SENTINEL_BEARER=… npx cookie-sentinel https://api.example.com/me
curl -si https://example.com | npx cookie-sentinel --input -              # offline
npx cookie-sentinel --input set-cookies.txt --origin https://app.example.com -f sarif > cookies.sarif

Options

| Option | Description | |---|---| | <url…> | URLs to fetch (https:// assumed if no scheme). Redirects are followed and cookies from every hop are audited | | -p, --path <path> | Extra path to fetch on every URL (repeatable) | | --crawl <file> | File of URLs or paths, one per line (# comments allowed) | | --crawl-depth <n> | Follow same-origin links up to depth n (0 = off) | | --max-pages <n> | Cap when crawling (default 25) | | -H, --header "Name: value" | Request header (repeatable), e.g. Cookie or Authorization | | --headers-file <file> | JSON headers for scripted auth | | --cookies-file <file> | Cookie jar file (JSON, name=value lines, or Netscape format) | | --bearer <token> | Authorization: Bearer shortcut (or COOKIE_SENTINEL_BEARER) | | --browser <engine> | playwright or puppeteer (optional peer dependencies) | | -i, --input <file\|-> | Audit raw Set-Cookie lines offline | | --origin <url> | URL context for --input (default https://example.com/) | | -c, --config <file> | JSON config (default .cookie-sentinel.json if present) | | -f, --format | text (default), json, sarif, markdown | | --fail-on <sev> | critical, high (default), medium, low, info or none | | --no-classify | Skip Open Cookie Database enrichment |

Exit codes: 0 passed, 1 findings at or above --fail-on, 2 usage error or every target failed to fetch.

Configuration

.cookie-sentinel.json:

{
  "failOn": "medium",
  "urls": ["https://app.example.com"],
  "paths": ["/login", "/account"],
  "headers": { "Accept-Language": "en" },
  "headersFile": "staging-headers.json",
  "cookiesFile": "staging-cookies.txt",
  "login": {
    "url": "https://app.example.com/api/login",
    "method": "POST",
    "headers": { "Content-Type": "application/json" },
    "body": "{\"user\":\"ci\",\"pass\":\"…\"}",
    "expectStatus": 200
  },
  "crawl": { "maxDepth": 2, "maxPages": 30 },
  "browser": { "engine": "playwright" },
  "sessionPatterns": ["^acme_u$"],
  "severity": { "broad-path": "off" },
  "allow": [{ "rule": "*", "cookie": "_ga*", "reason": "analytics allowlist" }]
}

GitHub Action

permissions:
  contents: read
  security-events: write
jobs:
  cookies:
    runs-on: ubuntu-latest
    steps:
      - uses: MrLouisWright/cookie-sentinel@<sha>
        with:
          urls: https://staging.example.com
          paths: /login /account
          bearer: ${{ secrets.STAGING_TOKEN }}
          fail-on: medium
          args: --crawl-depth 1 --max-pages 20
          sarif: cookies.sarif

Releases are published to npm with provenance (see release workflow).

Library

ESM and CommonJS:

import { auditUrls, auditSetCookies, formatText, classifyCookie } from 'cookie-sentinel';
// const { auditUrls } = require('cookie-sentinel'); // Node 18+

const report = await auditUrls(['https://example.com'], {
  paths: ['/login'],
  crawl: { maxDepth: 1, maxPages: 10 },
  headers: { Cookie: 'sid=…' },
});
console.log(formatText(report, { failOn: 'high' }));
console.log(report.classificationSummary);

Build types locally: npm run build (generates dist/index.cjs and dist/*.d.ts).

License

MIT © Louis Wright