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

rls-recon

v0.1.0

Published

Audit your own Supabase project's Row Level Security from the outside: what can the public anon key actually read, write, or list? Zero dependencies, read-only by default.

Readme

rls-recon

Audit your own Supabase project's Row Level Security from the outside, using nothing but the two things every client app already exposes: the project URL and the public anon key. One command answers the question that matters: what can an anonymous stranger actually read, write, or list?

Zero dependencies. Node 18+. Read-only by default.

AUTHORIZATION REQUIRED. Run rls-recon only against projects you own or have explicit written authorization to test. See Responsible use and disclaimer below. It is not optional reading.

Why

Supabase's anon key is public by design; it ships in every browser bundle and mobile app. The entire security model rests on Row Level Security being configured correctly on every table, every RPC, and every storage bucket. Most projects get this wrong somewhere, and the failure is silent: everything works in the app while the data sits open to anyone with curl.

rls-recon makes the same requests an anonymous caller would make and reports exactly what your policies allow. It does not bypass anything. It asks the server "what does this key get?" and shows you the answer.

Usage

node bin/rls-recon.mjs --url https://your-project.supabase.co --anon-key YOUR_ANON_KEY

Flags:

  • --probe-writes also test anonymous INSERT. Requires --i-own-this-project. Inserts one canary row per table built from column defaults and deletes it immediately after, matched on the returned values.
  • --i-own-this-project attestation required to enable write probes.
  • --delay-ms N pause between requests (default 150; sequential and gentle on purpose).
  • --timeout-ms N per-request timeout (default 10000).
  • --json raw JSON result instead of the report.

Exit codes: 0 no anonymous data access found, 1 findings present, 2 error. The non-zero exit makes it usable as a CI gate: RLS regressions break the build instead of reaching production.

Example output

rls-recon report for https://your-project.supabase.co
probed at 2026-08-23T14:00:00.000Z with the provided anon key

TABLES (4 exposed in the API schema)
  READABLE  profiles  (rows exposed: 1204, columns: id, full_name, email, phone, created_at)
  READABLE  orders  (rows exposed: 57, columns: id, user_id, total_cents, status)
  READABLE  products  (rows exposed: 340, columns: id, name, price_cents)
  denied    audit_log

RPC FUNCTIONS (2 exposed to this key)
  exposed   search_docs
  exposed   nearby_clinics

STORAGE
  bucket    avatars  (public, OBJECTS LISTABLE)
  bucket    invoices  (private, OBJECTS LISTABLE)

SUMMARY
  readable tables:            3
  writable tables:            0
  buckets visible:            yes
  buckets with listed objects: 2

FINDINGS PRESENT: anonymous callers can reach data. Exit code 1.

What it does

  1. Discovers the tables, views, and RPC functions the API schema exposes to your key (the server publishes this itself at /rest/v1/).
  2. Read-probes each table with a single GET ...?limit=1 and a count header: a 200 means the anon role can read it, and the report shows how many rows and which columns.
  3. Lists storage buckets and checks whether object listing works for each. A "private" bucket that allows listing is still leaking.
  4. Write-probes (opt-in only): inserts a canary row from column defaults, deletes exactly that row, and reports whether anonymous inserts are possible.

What it does not do

  • No bypass attempts. It uses only the credentials you provide and never tries to escalate past them. No SQL injection probing, no auth tricks, no service-key hunting.
  • No target discovery. It takes an explicit --url. There is no enumeration, no search integration, no batch mode. It can only point where you point it.
  • No unfiltered writes. It never issues UPDATE or DELETE probes against existing rows. Write probes insert a clearly-marked canary and remove it.
  • No concurrency. Requests are sequential with a delay. It cannot be mistaken for a denial-of-service attempt.

Tests

npm test

The suite runs the full probe pipeline against a mock Supabase project: discovery, read probes, canary insert/delete with cleanup verification, storage listing, finding detection, exit-code logic, and report rendering. No network required.

Responsible use and disclaimer

rls-recon is a defensive audit tool. It exists so you can verify the security posture of systems you are responsible for.

  • Run it only against projects you own or have explicit written authorization to test. If you are not sure whether you are authorized, you are not.
  • You are solely responsible for how you use this tool and for complying with all applicable laws and the terms of service of any system you run it against.
  • The author provides this tool as-is, without warranty of any kind (see LICENSE), and accepts no liability for any misuse of this tool or for any damage, claim, or loss arising from its use or inability to be used.
  • A clean result is not a guarantee of security. rls-recon checks anonymous access through the public API surface; it is one layer of an audit, not the audit.

License

MIT