TIFU: I used .npmignore
TIFU: I used .npmignore
Aug 24, 2024|Last edited: Feb 17, 2025
type
status
date
slug
summary
tags
category
icon
password
Tweet

How .npmignore Led to a Security Nightmare

Today, I learned the hard way that even the smallest oversight can lead to catastrophic consequences. It all started when I decided to use .npmignore to manage which files should be excluded from my npm package. Little did I know, this would result in an accidental leak of sensitive information.

The Setup

I was working on a new project and wanted to make sure that only the necessary files were included in my npm package. So, I created a .npmignore file to exclude things like my node_modules directory and other development artifacts. Feeling pretty confident, I published my package to the npm repository.

The Mistake

What I didn’t realise was that by having the .npmignore file, the .gitignore file would be ignored completely.
It is not a merge!
If you want to include something that is excluded by your .gitignore file, you can create an empty .npmignore file to override it.
Instead of excluding my .env file, which contained API keys and other secrets, I accidentally included it by not excluding it again on .npmignore . This meant that when I published my package, all my secrets were exposed to the public.

The Fallout

I quickly realised my mistake when I saw an alert that my API keys is publicly visible. Panic set in as I scrambled to check the resources my api keys could access and revoke all the compromised keys. I had to go through the tedious process of updating my secrets across multiple services..

Lessons Learned

  1. Do not be lazy and use .npmignore . Just stick to files in package.json
  1. Use files in package.json instead
  1. If you use .env file look into using mozialla/sops
  1. Automate security checks: Implement automated security checks to catch issues before they make it to production.
  1. Review before you publish: Always review the contents of your package before hitting the publish button.
 
 
project(go-ratelimit): genesis, perplexed by benchmarking #1Design Decision: Async Query Based Change Capture Vs Event Based Message Queue
Loading...