惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
Arctic Wolf
博客园 - 聂微东
F
Fortinet All Blogs
云风的 BLOG
云风的 BLOG
小众软件
小众软件
V
Visual Studio Blog
博客园 - 三生石上(FineUI控件)
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The Cloudflare Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园_首页
L
LangChain Blog
A
About on SuperTechFans
阮一峰的网络日志
阮一峰的网络日志
I
Intezer
T
The Blog of Author Tim Ferriss
Security Latest
Security Latest
C
CXSECURITY Database RSS Feed - CXSecurity.com
Know Your Adversary
Know Your Adversary
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
P
Palo Alto Networks Blog
Scott Helme
Scott Helme
S
Secure Thoughts
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
Attack and Defense Labs
Attack and Defense Labs
P
Privacy & Cybersecurity Law Blog
O
OpenAI News
H
Heimdal Security Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Help Net Security
Help Net Security
C
Cyber Attacks, Cyber Crime and Cyber Security
Blog — PlanetScale
Blog — PlanetScale
GbyAI
GbyAI
G
Google Developers Blog
博客园 - Franky
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
K
Kaspersky official blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
Tor Project blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tenable Blog
Google Online Security Blog
Google Online Security Blog
PCI Perspectives
PCI Perspectives

Supabase Blog

AI Agents Know About Supabase. They Don't Always Use It Right. Custom OIDC Providers for Supabase Auth 100,000 GitHub stars Supabase docs over SSH Navigating Regional Network Blocks Supabase Joins the Stripe Projects Developer Preview Log Drains: Now available on Pro Supabase Storage: major performance, security, and reliability updates Supabase incident on February 12, 2026 Hydra joins Supabase X / Twitter OAuth 2.0 is now available for Supabase Auth BKND joins Supabase Supabase is now an official Claude connector Supabase PrivateLink is now available Introducing: Postgres Best Practices When to use Read Replicas vs. bigger compute Introducing TRAE SOLO integration with Supabase Supabase Security Retro: 2025 Sync Stripe Data to Your Supabase Database in One Click Building ChatGPT Apps with Supabase Edge Functions and mcp-use Own Your Observability: Supabase Metrics API Introducing iceberg-js: A JavaScript Client for Apache Iceberg Introducing Supabase for Platforms Adding Async Streaming to Postgres Foreign Data Wrappers Build "Sign in with Your App" using Supabase Auth Introducing Seven New Email Templates for Supabase Auth The new Supabase power for Kiro Introducing Supabase ETL Introducing Analytics Buckets Introducing Vector Buckets Snap, Inc. Launches Snap Cloud, Powered by Supabase Triplit joins Supabase Supabase Series E 1000 Y Combinator Founders Choose Supabase gm 👋 web3, welcome aboard to Sign in with Web3 (Solana, Ethereum) Announcing the Supabase Remote MCP Server Enterprise speed, enterprise standards with Bolt Cloud + Supabase PostgREST 13 Lovable Cloud + Supabase: The Default Platform for AI Builders Processing large jobs with Edge Functions, Cron, and Queues Defense in Depth for MCP Servers OrioleDB Patent: now freely available to the Postgres community Supabase Launch Week 15 Hackathon Winner Announcement The Vibe Coder's Guide to Supabase Environments Testing for Vibe Coders: From Zero to Production Confidence The Vibe Coding Master Checklist Vibe Coding: Best Practices for Prompting Supabase Auth: Build vs. Buy Top 10 Launches of Launch Week 15 Supabase Launch Week 15 Hackathon Storage: 10x Larger Uploads, 3x Cheaper Cached Egress, and 2x Egress Quota Persistent Storage and 97% Faster Cold Starts for Edge Functions Algolia Connector for Supabase New Observability Features in Supabase Improved Security Controls and A New Home for Security Introducing Branching 2.0 Stripe-To-Postgres Sync Engine as standalone Library Supabase Analytics Buckets with Iceberg Support Create a Supabase backend using Figma Make Introducing JWT Signing Keys Supabase UI: Platform Kit Build a Personalized AI Assistant with Postgres Announcing Multigres: Vitess for Postgres Building on open table formats Open Data Standards: Postgres, OTel, and Iceberg Simplifying back-end complexity with Supabase Data APIs PostgreSQL Event Triggers without superuser access Top 10 Launches of Launch Week 14 Supabase MCP Server Data API Routes to Nearest Read Replica Declarative Schemas for Simpler Database Management Realtime: Broadcast from Database Keeping Tabs on What's New in Supabase Studio Edge Functions: Deploy from the Dashboard + Deno 2.1 Automatic Embeddings in Postgres Introducing the Supabase UI Library Supabase Auth: Bring Your Own Clerk Postgres Language Server: Initial Release Migrating from Fauna to Supabase Migrating from the MongoDB Data API to Supabase Dedicated Poolers Postgres as a Graph Database: (Ab)using pgRouting AI Hackathon at Y Combinator Calendars in Postgres using Foreign Data Wrappers Supabase Launch Week 13 Hackathon Winners How to Hack the Base! Running Durable Workflows in Postgres using DBOS database.build v2: Bring-your-own-LLM Restore to a New Project Hack the Base! with Supabase Top 10 Launches of Launch Week 13 Supabase Queues High Performance Disk Supabase Cron Supabase CLI v2: Config as Code Supabase Edge Functions: Introducing Background Tasks, Ephemeral Storage, and WebSockets Supabase AI Assistant v2 OrioleDB Public Alpha Executing Dynamic JavaScript Code on Supabase with Edge Functions ClickHouse Partnership, improved Postgres Replication, and Disk Management
Protecting your Supabase projects from npm supply chain attacks
Katerina Skroumpelou · 2026-05-26 · via Supabase Blog

Protecting your Supabase projects from npm supply chain attacks

There has been a growing trend of supply chain attacks on Node Package Manager (NPM). In addition, we have seen other creative attacks, including a typosquat package named supabase-javascript that appeared on npm, copying our name to phish developers. We reported it. npm took it down a few hours later, long enough that the package picked up real downloads.

If you build on Supabase, this matters to you. Edge Functions pull from npm. The Supabase CLI is on npm. supabase-js, @supabase/ssr, and @supabase/server are all on npm. Any of these is a credential leak waiting for the wrong update to land.

This post lays out what we are doing about it and what you should do today.

We kicked off a coordinated response across the company. The work in flight:

  • Publishing a canonical security guide in our docs. A single, agent-readable page that tells you exactly what to do.
  • Hardening our own GitHub Actions. Our security team finished a pass on pull_request_target usage across the Supabase org months ago and is close to enforcing pinned action SHAs across every repo.
  • Adding security notes to secret-handling APIs. TSDoc and JSDoc on functions like createClient so editor hovers warn when you are working with sensitive credentials.
  • Comms across every channel. Our goal is to educate as many people as we can, whether or not they are Supabase customers.

Supply chain attacks share a shape. The attacker does not break into your computer. They get you to invite their code in, and they do that by getting their code into a package you already trust. The recipes vary, but the three most common patterns are these:

  • Maintainer compromise. An attacker steals an npm publish token or phishes a maintainer, then publishes a new version of a popular package with malicious code added. The next time you run npm install against that range, you are running their code.
  • Typosquatting. An attacker registers a package name a few letters away from a real one, like supabase-javascript instead of @supabase/supabase-js. They wait for a developer or, increasingly, an AI coding agent to mistype the name. AI agents hallucinate package names regularly, and that is now a primary attack vector against teams that vibe-code their dependencies.
  • Build pipeline compromise. This is what hit TanStack. An attacker found a vulnerable GitHub Actions workflow, poisoned the build cache from a fork PR, and waited for the next legitimate release run to pick up the poisoned cache and publish their code under the real maintainer's identity. No stolen tokens. No compromised laptops. The attacker rode the official release train.

Once the malicious code lands on disk in your node_modules, npm's lifecycle scripts run it. By the time npm install returns, the attacker has already read your environment variables, your AWS instance metadata, your kubeconfig, your .npmrc token, your .git-credentials, and your SSH private keys. The TanStack payload exfiltrated through the Session messenger network, which is end-to-end encrypted and has no fixed command-and-control address. You cannot block it at the firewall.

The TanStack postmortem describes the full chain and is worth reading if you maintain a public open source project. The short version: every link in the chain (a pull_request_target workflow, an unsecured Actions cache, a long-lived OIDC publish token) was a known issue with public mitigations. The attack worked because nobody had connected the dots in advance.

Most of what follows takes minutes. The goal is layered defense: no single mitigation stops every attack, but together they raise the cost enough that attackers go bother someone else.

Upgrade to pnpm 11 (or the npm v11 equivalent)#

pnpm 11 sets minimumReleaseAge to 24 hours by default, blocks exotic subdependencies by default, and ships a new Allow Builds model that controls which dependencies are permitted to run install scripts. If your AI coding agent picked pnpm 10.x for you, fix that. Tell it to use pnpm 11.

Then set minimumReleaseAge higher than the default. Three to seven days is a reasonable starting point for most projects. Most malicious npm packages are caught and pulled within twenty-four to forty-eight hours, so a three-day window catches the long tail of detections without throttling legitimate updates too much. Configure it in your project's pnpm-workspace.yaml or .npmrc:


_10

minimumReleaseAge: 4320 # minutes, equals 3 days


Pin versions, especially for security-sensitive dependencies#

The ^ and ~ ranges in your package.json are a polite way of telling npm "trust me, take the next minor or patch version." Supply chain attacks exploit exactly that trust. Pin exact versions for anything that touches authentication, secrets, networking, or user data. Use ^ only where you actively want updates and have a process to vet them.

Commit your lockfile and review changes to it#

A lockfile records exactly which version of which package, with which hash, you installed. If an attacker republishes a tarball under the same version number, the hash mismatch fails the install. Commit pnpm-lock.yaml, package-lock.json, or yarn.lock to your repo. Treat lockfile diffs as code review surface, not noise. A pull request that bumps fifty transitive dependencies for no obvious reason deserves a careful read before it merges.

Disable npm install scripts where you can#

Most supply chain payloads run through preinstall, install, or postinstall lifecycle scripts. If your project does not need them, turn them off globally:


_10

npm config set ignore-scripts true


Or scope it to the project via .npmrc:

The trade-off is that some packages with native code (bcrypt, sharp, and similar) will not build without scripts. Use pnpm's Allow Builds model to allowlist the specific packages you actually need rather than allowing every package on the registry to run code at install time.

Verify package names every single time you install#

Typosquats target the moment of carelessness. Before you pnpm add anything, especially anything an AI agent suggested, check that:

  • The scope is correct. Official Supabase packages live under @supabase/. A package named supabase-javascript or supabase-server without the scope is not ours and never has been.
  • The maintainer is the expected one. The npm page lists current maintainers; a brand-new maintainer on a long-established package is a signal worth a closer look.
  • The download counts and the linked GitHub repo match what you expect for a real, established package.

Pin your GitHub Actions to commit SHAs, not tags#

If you maintain a public repo, this is the single biggest change you can make. A tag like @v5 is a moving target. The maintainer of that action (or an attacker who compromised that maintainer) can republish the tag with new code, and your workflow will pick it up on the next run. Pin to the full commit SHA instead:


_10

- uses: actions/checkout@1f9a0c22da41e6ebfa534300ef656b67ce0c5b94 # v6.0.2


Renovate and Dependabot both understand this syntax and will update the comment when a new release is published, so you still get visibility without giving up safety.

Avoid pull_request_target with code checkout#

If your workflow uses pull_request_target and then checks out code from the PR, you are running attacker-controlled code in a context that has access to your repo's secrets and cache. This is the exact pattern that compromised TanStack. Use pull_request for anything that touches PR code. Reserve pull_request_target for trusted, no-checkout operations like labeling or commenting on the PR.

Rotate credentials if you think you were exposed#

If you ran npm install on a day when a package you depend on turned out to be compromised, treat the install host as potentially compromised too. Rotate everything reachable from that machine: AWS, GCP, Kubernetes, Vault, GitHub, npm, SSH, and any Supabase service-role keys. Audit your service-role key usage in the Supabase dashboard for access patterns you do not recognize. It is an annoying afternoon. It is not as annoying as a customer breach.

Consider a scanner as a second line of defense#

Tools like Socket.dev, npq, and Snyk monitor the npm registry and flag suspicious package behavior in real time. None of them are a silver bullet, and none of them substitute for the practices above. They are a useful second line of defense for teams that already have the basics in place.

This kind of attack will keep happening. The cost of pulling one off keeps dropping; the payoff (credentials to dozens of production systems in a single shot) keeps rising. The good news is that the defenses are well understood, cheap to implement, and effective when stacked. Pin your versions. Wait for the dust to settle on new releases. Lock your CI down. Verify what you install. Tell your AI agents to do the same.

If you have suggestions, requests, or your own war stories about how you handle this on your team, find me on Discord or on Twitter.

Paste this into Claude Code, Codex, Cursor, or whatever agent you use. Read every change before you accept it. Do not skim.


_34

Audit this repo for npm supply-chain hygiene. Apply the changes below and report what you did. Do not push, open PRs, install new dependencies, or rotate credentials without explicit approval.

_34

_34

Package manager:

_34

_34

- Upgrade to pnpm 11+ (or the latest yarn / npm / bun) if older.

_34

- Set a 7-day quarantine on new versions for the package manager in use:

_34

- pnpm: `minimumReleaseAge: 10080` in `pnpm-workspace.yaml`.

_34

- npm: `min-release-age=7` in `.npmrc`.

_34

- yarn (berry): `npmMinimalAgeGate: '7d'` in `.yarnrc.yml`.

_34

- bun: `minimumReleaseAge = 604800` under `[install]` in `bunfig.toml`.

_34

- Block lifecycle scripts by default. pnpm: declare an explicit `allowBuilds` list in `pnpm-workspace.yaml`. npm/bun: set `ignore-scripts=true`. yarn defaults to `enableScripts: false` — confirm it is not overridden.

_34

- Block non-registry transitive refs. pnpm: `blockExoticSubdeps: true`. npm: set `allow-git=root`, `allow-remote=root`, `allow-file=root`, `allow-directory=root` in `.npmrc`. yarn: use `approvedGitRepositories` as an explicit allowlist.

_34

- Pin the package manager itself: set `packageManager` in `package.json` to an exact version plus sha512 hash (e.g. `pnpm@10.4.1+sha512.<hash>`).

_34

_34

Lockfile and dependencies:

_34

_34

- Confirm `pnpm-lock.yaml`, `package-lock.json`, or `yarn.lock` is committed (not gitignored). CI installs must use `--frozen-lockfile` (pnpm/yarn) or `npm ci`. Flag any job that runs a non-frozen install.

_34

- For dependencies handling auth, secrets, networking, crypto, or user data, replace `^`/`~` ranges with exact versions. List what you changed.

_34

- Verify every Supabase import uses the exact `@supabase/` scope. Flag unscoped lookalikes (`supabase-js`, `supabase-javascript`, etc.) as possible typosquats.

_34

_34

GitHub Actions (if present):

_34

_34

- Repin every third-party `uses:` reference to a 40-character commit SHA, with the original tag as a trailing comment.

_34

- Flag every workflow using `pull_request_target` that checks out PR code or runs PR-controlled build steps. Propose a `pull_request` rewrite. Do not silently change trigger types.

_34

- Add a non-blocking `npm audit signatures` step to install workflows.

_34

_34

Flag for human (do not auto-enable):

_34

_34

- Dependabot alerts and secret scanning, if disabled.

_34

_34

Report:

_34

_34

- One line per file changed, with the reason.

_34

- A separate list of items flagged for human review rather than automatically changed.