-
-
Notifications
You must be signed in to change notification settings - Fork 228
Description
@danielroe suggested me to open a public issue instead of a private one, so here it is.
Description
Images referenced in a package’s README are loaded directly from third-party servers.
This allows anyone who controls such an image to collect data about visitors who view the package page on https://npmx.dev
This is not an exploit in the traditional sense, but it creates an unintended privacy leak for users browsing packages.
What happens
When a README contains an image like:
the browser requests that image directly from the external server when someone opens the package page.
As a result, the image host can log detailed request metadata.
Proof of concept
Steps to reproduce:
- Host an image on a server you control (for example, a simple server or Vercel Serverless Function).
- Publish an npm package whose README includes that image.
- Open the package page on https://npmx.dev.
- Observe incoming requests on the image server.
Example test package:
Warning
The PoC below uses my own server with a real request logger.
No data is shared publicly, but requests are genuinely received and logged to demonstrate the issue
👉 https://npmx.dev/package/npmx-image-issue
When someone visits that page, the image server receives a request containing data such as:
- IP address
- User-Agent
- Accept / Accept-Language headers
- Referrer (
https://npmx.dev/) - Approximate location (depending on hosting provider)
- Browser and OS information
Example (redacted) request headers:
accept-language: en-US,en;q=0.9
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/145
referer: https://npmx.dev/
x-forwarded-for: XXX.XXX.XXX.XX
x-vercel-ip-country: XX
x-vercel-ip-city: XXXXX
...
Why this is a problem
Anyone browsing packages may unknowingly leak personal and device-related information to arbitrary third parties.
This affects all visitors, not just package authors.
Expected behavior
Viewing a package page should not directly expose visitor data to untrusted third-party servers.
Suggested solution
Proxy README images through a trusted image proxy, except for a small allowlist of well-known domains (for example, img.shields.io).
This is the same approach GitHub uses to prevent IP and metadata leakage:
- GitHub image proxy ("Camo"): https://github.com/atmos/camo
- GitHub docs:
https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-anonymized-urls - Blog post:
https://github.blog/news-insights/product-news/proxying-user-images/
Let's implement a fix for this issue!