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 🙏

© 2024 – Pkg Stats / Ryan Hefner

cloudflare-ip

v0.0.7

Published

Check if an IP address is one of Cloudflare's

Downloads

3,484

Readme

cloudflare-ip NPM version Build Status Dependency Status

Check if an IP address is in Cloudflare's IP address range.

Cloudflare's IP addresses are pubicly available.


Why: If your app is behind a reverse proxy like Cloudflare, then you generally don't want to handle requests that bypass it. At the very least, you'll want to ensure that the user cannot spoof their IP address by setting headers that you thought you could depend on like X-Forwarded-For.

Chuck this library into some upstream middleware to short-circuit on requests that aren't coming from Cloudflare.

Scroll down to the Enforcing X-Forwarded-For section for some further thoughts.

Install

npm install --save cloudflare-ip

Usage

const cloudflareIp = require('cloudflare-ip');

// non-cloudflare ips should be false
cloudflareIp('66.249.66.1')                // false
cloudflareIp('1.1.1.1')                    // false
// localhost should be false
cloudflareIp('127.0.0.1'))                 // false
cloudflareIp('::1'))                       // false
// garbage should be false
cloudflareIp()                             // false
cloudflareIp('')                           // false
cloudflareIp(0)                            // false
cloudflareIp('chicken')                    // false
// cloudflare ips should pass
cloudflareIp('103.21.244.0'))              // true
cloudflareIp('2400:cb00:0000::0000'))      // true

Syncing with Cloudflare

Scrape Cloudflare's list and update the ips.json file:

npm run update-list

If this produces a change, then this library needs to be updated.

Enforcing X-Forwarded-For

The X-Forwarded-For request header is an array of IP addresses ordered from upstream to downstream. When a proxy forwards a request, it typically appends the connecting IP address to this list before sending it on.

You only trust a given index of X-Forwarded-For when it's a length that you expect. For example, if you're using Nginx and you configure it to never relay the upstream header, then you'll know an honest request would always have an X-Forwarded-For of length one.

If your reverse proxy relays and appends to this header, then the user can spoof their own X-Forwarded-For header if you're not careful.

Here are some examples to think about when validating requests.

Example 1: App <- Heroku <- Cloudflare

If your app is running on Heroku behind Cloudflare, then an honest request will look like:

ip: herokuLoadBalancer
x-forwarded-for: [realUser, cloudflare]

If you assert that the 2nd value of X-Forwarded-For is a Cloudflare IP address in the naive attempt to ensure that requests are coming through Cloudflare, then a dishonest user can connect directly to your Heroku server with a spoofed X-Forwarded-For [spoofUser, spoofCloudflare] and your app will see this:

ip: herokuLoadBalancer
x-forwarded-for: [spoofUser, spoofCloudflare, realUser]

So by checking the 2nd value of X-Forwarded-For, you would be validating a spoofable IP address.

The simplest solution in this example would be to validate the 2nd X-Forwarded-For IP address but also ensure that X-Forwarded-For has exactly two IP addresses.

Example middleware:

app.use(function * (next) {
  if (config.NODE_ENV !== 'production') yield next
  if (!this.get('x-forwarded-for')) return
  const fwd = this.get('x-forwarded-for').split(',')
  if (fwd.length !== 2) return
  if (!cloudflareIp(fwd[1])) return
  yield next
})

Example 2: App <- Cloudflare

If your app is running on port 80 and is only behind Cloudflare, then an honest request will look like:

ip: cloudflare
x-forwarded-for: [realUser]

You could validate that the connecting IP address is Cloudflare's and that X-Forwarded-For has a length of one before trusting the first value of X-Forwarded-For to be the user's IP address.

Development

npm test

License

MIT