Socket
Socket
Sign inDemoInstall

express-ipfilter

Package Overview
Dependencies
Maintainers
1
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-ipfilter - npm Package Compare versions

Comparing version 0.3.1 to 1.0.1

2

index.js
module.exports = {
IpFilter: require('./lib/ipfilter'),
IpDeniedError: require('./lib/deniedError')
};
}

@@ -1,12 +0,11 @@

'use strict';
module.exports = function IpDeniedError(message, extra) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.message = message || 'The requesting IP was denied';
this.extra = extra;
this.status = this.statusCode = 403;
};
require('util').inherits(module.exports, Error);
//# sourceMappingURL=deniedError.js.map
module.exports = class IpDeniedError extends Error {
constructor(message, extra) {
message = message || 'The requesting IP was denied'
super(message)
this.message = message
this.name = this.constructor.name
Error.captureStackTrace(this, this.constructor)
this.extra = extra
this.status = this.statusCode = 403
}
}

@@ -7,3 +7,3 @@ /*!

'use strict';
'use strict'

@@ -13,10 +13,8 @@ /**

*/
const _ = require('lodash')
const iputil = require('ip')
const rangeCheck = require('range_check')
const IpDeniedError = require('./deniedError')
const proxyaddr = require('proxy-addr')
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _ = require('lodash');
var iputil = require('ip');
var rangeCheck = require('range_check');
var IpDeniedError = require('./deniedError');
/**

@@ -29,3 +27,3 @@ * express-ipfilter:

*
* var ipfilter = require('ipfilter'),
* const ipfilter = require('ipfilter'),
* ips = ['127.0.0.1'];

@@ -42,5 +40,4 @@ * getIps = function() { return ['127.0.0.1']; };

* - `log` console log actions. Defaults to true.
* - `allowPrivateIPs` whether to allow private IPs.
* - `allowedHeaders` Array of headers to check for forwarded IPs.
* - 'excluding' routes that should be excluded from ip filtering
* - 'trustProxy' trust proxy settings just like in express. The trust proxy setting is implemented using the proxy-addr package. (http://expressjs.com/en/guide/behind-proxies.html)
*

@@ -52,70 +49,84 @@ * @param [ips] {Array} IP addresses or {Function} that returns the array of IP addresses

module.exports = function ipfilter(ips, opts) {
ips = ips || false;
ips = ips || false
var getIps = _.isFunction(ips) ? ips : function () {
return ips;
};
var logger = function logger(message) {
console.log(message);
};
var settings = _.defaults(opts || {}, {
mode: 'deny',
log: true,
logF: logger,
allowedHeaders: [],
allowPrivateIPs: false,
excluding: [],
detectIp: getClientIp
});
const getIps = _.isFunction(ips) ? ips : () => ips
const logger = message => console.log(message)
function getClientIp(req) {
var ipAddress;
/**
* Compile "proxy trust" value to function. (from express)
*
* @param {Boolean|String|Number|Array|Function} val
* @return {Function}
* @api private
*/
const compileTrust = val => {
if (typeof val === 'function') return val
var headerIp = _.reduce(settings.allowedHeaders, function (acc, header) {
var testIp = req.headers[header];
if (testIp != '') {
acc = testIp;
}
return acc;
}, '');
if (headerIp) {
var splitHeaderIp = headerIp.split(',');
ipAddress = splitHeaderIp[0];
if (val === true) {
// Support plain true/falses
return () => true
}
if (!ipAddress) {
ipAddress = req.connection.remoteAddress;
if (typeof val === 'number') {
// Support trusting hop count
return (a, i) => i < val
}
if (!ipAddress) {
return '';
if (typeof val === 'string') {
// Support comma-separated values
val = val.split(',')
}
if (iputil.isV6Format(ipAddress) && ~ipAddress.indexOf('::ffff')) {
ipAddress = ipAddress.split('::ffff:')[1];
return proxyaddr.compile(val || [])
}
const settings = _.defaults(opts || {}, {
mode: 'deny',
log: true,
logF: logger,
excluding: [],
trustProxy: false // This is the default used by express.
})
if (!_.isFunction(settings.detectIp)) {
settings.detectIp = req => proxyaddr(req, compileTrust(settings.trustProxy))
}
const testExplicitIp = (ip, constraint, mode) => {
if (ip === constraint) {
return mode === 'allow'
} else {
return mode === 'deny'
}
}
if (iputil.isV4Format(ipAddress) && ~ipAddress.indexOf(':')) {
ipAddress = ipAddress.split(':')[0];
const testCidrBlock = (ip, constraint, mode) => {
if (rangeCheck.inRange(ip, constraint)) {
return mode === 'allow'
} else {
return mode === 'deny'
}
return ipAddress;
}
var matchClientIp = function matchClientIp(ip) {
var mode = settings.mode.toLowerCase();
const testRange = (ip, constraint, mode) => {
const filteredSet = _.filter(getIps(), constraint => {
if (constraint.length > 1) {
const startIp = iputil.toLong(constraint[0])
const endIp = iputil.toLong(constraint[1])
const longIp = iputil.toLong(ip)
return longIp >= startIp && longIp <= endIp
} else {
return ip === constraint[0]
}
})
var result = _.invoke(getIps(), testIp, ip, mode);
if (mode === 'allow') {
return _.some(result);
if (filteredSet.length > 0) {
return mode === 'allow'
} else {
return _.every(result);
return mode === 'deny'
}
};
}
var testIp = function testIp(ip, mode) {
var constraint = this;
const testIp = function(ip, mode) {
const constraint = this

@@ -125,80 +136,57 @@ // Check if it is an array or a string

if (rangeCheck.validRange(constraint)) {
return testCidrBlock(ip, constraint, mode);
return testCidrBlock(ip, constraint, mode)
} else {
return testExplicitIp(ip, constraint, mode);
return testExplicitIp(ip, constraint, mode)
}
}
if ((typeof constraint === 'undefined' ? 'undefined' : _typeof(constraint)) === 'object') {
return testRange(ip, constraint, mode);
if (typeof constraint === 'object') {
return testRange(ip, constraint, mode)
}
};
}
var testExplicitIp = function testExplicitIp(ip, constraint, mode) {
if (ip === constraint) {
return mode === 'allow';
} else {
return mode === 'deny';
}
};
const matchClientIp = ip => {
const mode = settings.mode.toLowerCase()
var testCidrBlock = function testCidrBlock(ip, constraint, mode) {
if (rangeCheck.inRange(ip, constraint)) {
return mode === 'allow';
} else {
return mode === 'deny';
}
};
const result = _.invokeMap(getIps(), testIp, ip, mode)
var testRange = function testRange(ip, constraint, mode) {
var filteredSet = _.filter(getIps(), function (constraint) {
if (constraint.length > 1) {
var startIp = iputil.toLong(constraint[0]);
var endIp = iputil.toLong(constraint[1]);
var longIp = iputil.toLong(ip);
return longIp >= startIp && longIp <= endIp;
} else {
return ip === constraint[0];
}
});
if (filteredSet.length > 0) {
return mode === 'allow';
if (mode === 'allow') {
return _.some(result)
} else {
return mode === 'deny';
return _.every(result)
}
};
}
var error = function error(ip, next) {
var err = new IpDeniedError('Access denied to IP address: ' + ip);
return next(err);
};
const error = (ip, next) => {
const err = new IpDeniedError('Access denied to IP address: ' + ip)
return next(err)
}
return function (req, res, next) {
return (req, res, next) => {
if (settings.excluding.length > 0) {
var results = _.filter(settings.excluding, function (exclude) {
var regex = new RegExp(exclude);
return regex.test(req.url);
});
const results = _.filter(settings.excluding, exclude => {
const regex = new RegExp(exclude)
return regex.test(req.url)
})
if (results.length > 0) {
if (settings.log && settings.logLevel !== 'deny') {
settings.logF('Access granted for excluded path: ' + results[0]);
settings.logF('Access granted for excluded path: ' + results[0])
}
return next();
return next()
}
}
var _ips = getIps();
const _ips = getIps()
if (!_ips || !_ips.length) {
if (settings.mode == 'allow') {
// ip list is empty, thus no one allowed
return error('0.0.0.0/0', next);
return error('0.0.0.0/0', next)
} else {
// there are no blocked ips, skip
return next();
return next()
}
}
var ip = settings.detectIp(req);
const ip = settings.detectIp(req)

@@ -208,6 +196,6 @@ if (matchClientIp(ip, req)) {

if (settings.log && settings.logLevel !== 'deny') {
settings.logF('Access granted to IP address: ' + ip);
settings.logF('Access granted to IP address: ' + ip)
}
return next();
return next()
}

@@ -217,8 +205,7 @@

if (settings.log && settings.logLevel !== 'allow') {
settings.logF('Access denied to IP address: ' + ip);
settings.logF('Access denied to IP address: ' + ip)
}
return error(ip, next);
};
};
//# sourceMappingURL=ipfilter.js.map
return error(ip, next)
}
}
{
"name": "express-ipfilter",
"version": "1.0.1",
"description": "A light-weight IP address based filtering system",
"version": "0.3.1",
"author": "BaM Interactive",
"dependencies": {
"ip": "~1.1.0",
"lodash": "~3.10.1",
"range_check": "^1.2.0"
},
"devDependencies": {
"babel-preset-es2015": "^6.6.0",
"grunt": "^0.4.5",
"grunt-babel": "^6.0.0",
"grunt-check-dependencies": "^0.12.0",
"grunt-cli": "^1.2.0",
"grunt-contrib-copy": "^0.8.2",
"grunt-contrib-watch": "^0.6.1",
"grunt-eslint": "^19.0.0",
"grunt-mocha-istanbul": "^3.0.1",
"grunt-mocha-test": "~0.12.7",
"istanbul": "^0.4.0",
"load-grunt-tasks": "^3.3.0",
"minimatch": "^3.0.3",
"mocha": "^2.5.3",
"mocha-junit-reporter": "^1.9.1",
"publish": "^0.5.0"
},
"keywords": [
"middleware",
"ipfilter",
"express",
"ip ban",
"ip filter",
"ipban",
"ip ban",
"express"
"ipfilter",
"middleware"
],
"repository": {
"type": "git",
"url": "http://github.com/baminteractive/express-ipfilter.git"
},
"repository": "https://github.com/casz/express-ipfilter",
"license": "MIT",
"author": "casz",
"main": "index.js",
"files": [
"/index.js",
"/lib"
],
"scripts": {
"test": "mocha -R spec",
"push": "publish"
"test": "jest",
"postversion": "npm run test && git push && git push --tags && npm publish"
},
"license": "MIT"
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.js": [
"eslint --fix",
"git add"
],
"*.{json,css,md}": [
"prettier --write",
"git add"
]
},
"prettier": {
"bracketSpacing": true,
"semi": false,
"singleQuote": true
},
"eslintConfig": {
"env": {
"node": true,
"es6": true
},
"extends": [
"eslint:recommended",
"plugin:jest/recommended",
"prettier"
],
"parserOptions": {
"ecmaVersion": 6
},
"plugins": [
"prettier",
"jest"
],
"rules": {
"prettier/prettier": "warn",
"no-console": "off",
"no-unused-vars": "warn",
"no-var": "warn",
"no-use-before-define": "warn",
"prefer-arrow-callback": "warn"
}
},
"eslintIgnore": [
"coverage",
"example"
],
"jest": {
"collectCoverage": true,
"collectCoverageFrom": [
"index.js",
"lib/**"
]
},
"dependencies": {
"ip": "~1.1.0",
"lodash": "^4.17.11",
"proxy-addr": "^2.0.4",
"range_check": "^1.2.0"
},
"devDependencies": {
"eslint": "^5.16.0",
"eslint-config-prettier": "^4.1.0",
"eslint-plugin-jest": "^22.4.1",
"eslint-plugin-prettier": "^3.0.1",
"jest": "^24.7.1",
"lint-staged": "^8.1.5",
"prettier": "^1.16.4"
},
"engines": {
"node": ">=8.9.0"
}
}

@@ -1,11 +0,5 @@

express-ipfilter: A light-weight IP address based filtering system
=================================================================================
# express-ipfilter: A light-weight IP address based filtering system
This package provides easy IP based access control. This can be achieved either by blacklisting certain IPs and whitelisting all others, or whitelisting certain IPs and blacklisting all others.
[![Circle CI](https://circleci.com/gh/baminteractive/express-ipfilter/tree/master.svg?style=svg)](https://circleci.com/gh/baminteractive/express-ipfilter/tree/master)
## Version
0.3.1
## Installation

@@ -19,4 +13,2 @@

> NOTE: Starting with version 0.1.0, allow forwarded IP addresses through headers (forward, Cloudflare, Codio) are disabled by **default**. You must explicitly enable them by adding them to the `allowedHeaders` list.
Blacklisting certain IP addresses, while allowing all other IPs:

@@ -26,11 +18,11 @@

// Init dependencies
var express = require('express'),
ipfilter = require('express-ipfilter').IpFilter;
const express = require('express')
const ipfilter = require('express-ipfilter').IpFilter
// Blacklist the following IPs
var ips = ['127.0.0.1'];
const ips = ['127.0.0.1']
// Create the server
app.use(ipfilter(ips));
app.listen(3000);
app.use(ipfilter(ips))
app.listen(3000)
```

@@ -43,12 +35,12 @@

// Init dependencies
var express = require('express'),
ipfilter = require('express-ipfilter').IpFilter;
const express = require('express')
const ipfilter = require('express-ipfilter').IpFilter
// Whitelist the following IPs
var ips = ['127.0.0.1'];
const ips = ['127.0.0.1']
// Create the server
app.use(ipfilter(ips, {mode: 'allow'}));
app.use(ipfilter(ips, { mode: 'allow' }))
module.exports = app;
module.exports = app
```

@@ -59,8 +51,8 @@

```javascript
var ips = ['127.0.0.1/24'];
const ips = ['127.0.0.1/24']
// Create the server
app.use(ipfilter(ips, {mode: 'allow'}));
app.use(ipfilter(ips, { mode: 'allow' }))
module.exports = app;
module.exports = app
```

@@ -71,8 +63,8 @@

```javascript
var ips = [['127.0.0.1','127.0.0.10']];
const ips = [['127.0.0.1', '127.0.0.10']]
// Create the server
app.use(ipfilter(ips, {mode: 'allow'}));
app.use(ipfilter(ips, { mode: 'allow' }))
module.exports = app;
module.exports = app
```

@@ -83,8 +75,10 @@

```javascript
var ips = function() { return ['127.0.0.1']; };
const ips = function() {
return ['127.0.0.1']
}
// Create the server
app.use(ipfilter(ips, {mode: 'allow'}));
app.use(ipfilter(ips, { mode: 'allow' }))
module.exports = app;
module.exports = app
```

@@ -96,10 +90,10 @@

```
```javascript
if (app.get('env') === 'development') {
app.use(function(err, req, res, _next) {
console.log('Error handler', err);
if(err instanceof IpDeniedError){
res.status(401);
}else{
res.status(err.status || 500);
app.use((err, req, res, _next) => {
console.log('Error handler', err)
if (err instanceof IpDeniedError) {
res.status(401)
} else {
res.status(err.status || 500)
}

@@ -110,4 +104,4 @@

error: err
});
});
})
})
}

@@ -118,13 +112,12 @@ ```

## Options
| Property | Description | Type | Default|
| ------------- |-------------| -----|--------|
| mode | whether to *deny* or *allow* to the IPs provided | string|deny|
| log | console log actions | boolean|true|
| logLevel | level of logging (*all*,*deny*,*allow*) | string | all
| allowedHeaders | an array of strings for header names that are acceptable for retrieving an IP address | array | [] |
| excluding | routes that should be excluded from ip filtering | array|[]|
| detectIp | define a custom function that takes an Express request object and returns an IP address to test against | function | built-in detection |
| Property | Description | Type | Default |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- | ------------------ |
| mode | whether to _deny_ or _allow_ to the IPs provided | string | deny |
| log | console log actions | boolean | true |
| logLevel | level of logging (_all_,_deny_,_allow_) | string | all |
| excluding | routes that should be excluded from ip filtering | array | [] |
| detectIp | define a custom function that takes an Express request object and returns an IP address to test against | function | built-in detection |
| trustProxy | This setting is implemented using the proxy-addr package. Check the [documentation](https://www.npmjs.com/package/proxy-addr) for the trust parameter. | boolean, array, string, number, function | false |

@@ -135,13 +128,12 @@ > A note on detectIp

```
function customDetection(req){
var ipAddress;
```javascript
const customDetection = req => {
var ipAddress
ipAddress = req.connection.remoteAddress.replace(/\//g, '.');
ipAddress = req.connection.remoteAddress.replace(/\//g, '.')
return ipAddress;
return ipAddress
}
ipfilter(ids, {detectIp: customDetection});
ipfilter(ids, { detectIp: customDetection })
```

@@ -153,144 +145,12 @@

### Building from source
You can run `grunt` to build the source. This will run `eslint` and `babel` against `src/ipfilter.js`.
There is an included `example` project that will load the package from the local build for testing.
### Running Tests
Run tests by using
Run tests by using `npm test`
`grunt test`
This will run `eslint`,`babel`, and `mocha` and output coverage data into `coverage`. Any pull request you submit needs to be accompanied by a test.
## Changelog
0.3.1
* Fixes critical bug that allowed access when ips is empty and mode == 'allow'.
* Adds minor speed improvements for middleware.
* Minor spelling and documentation fixes in README
Moved to [GitHub Releases](https://github.com/casz/express-ipfilter/releases)
0.3.0
* Adds the ability to pass IPs by function so that we can dynamically retrieve white/black listed addresses.
0.2.6
- Minor change to the Contributing Guidelines to include updating the version numbers
0.2.5
* Added fields `status` and `statusCode` to the IpDeniedError object, which both equal `403`.
0.2.4
* For IPv4 addresses that have a port (as experienced with Azure web apps), the port is now stripped before comparing it with the contents of the whitelist or blacklist. Fixes issue #49.
0.2.3
* Fixed a bug that sent all logging through instead of just denied requests
0.2.2
* Added a customization point for IP detection
* Fixed a bug with IPv4 over IPv6
0.2.1
* Add log level property.
0.2.0
* Changed how error handling works
* Removed settings for specific vendor ip addresses and added `allowedHeaders` to support those header-based IP addresses.
* You must now specifically require `IpFilter`, i.e. `var ipfilter = require('express-ipfilter').IpFilter;`
* If you want to handle errors you must require the error type as well `var IpDeniedError = require('express-ipfilter').IpDeniedError;`
0.1.1
* Added a favicon to the example to suppress the 404 error looking for it.
0.1.0
* Changed default behavior of the library to disable reading forwarded IP headers. They must now be explicitly enabled.
* Using `res.send` when a failure occurs to allow for different formats of `errorMessage`
0.0.25
* Switched from netmask to range_check (uses ipaddr.js)
* Added support for IPv6 CIDR
* Fixed issue with mixed IPv4 and IPv6 rules
0.0.24
* Added lib to version control
0.0.23
* added codio x-real-ip header
0.0.22
* Added IPv6 Support
* Added build tools
* Added test coverage and reporting
0.0.20
* Added a setting to explicitly allow CloudFlare and Forwarded IPs. By default they are set to not allow these headers. Thanks to @longstone!
0.0.19
* Added detection for CloudFlare forwarded ips - https://github.com/baminteractive/express-ipfilter/commit/9aa43af14f5a003bad3145eef658f429808818f9 (@lafama)
0.0.18
* Fixing bug when array of CIDR blocks are used
0.0.16
* Fixing bug when no IP address can be determined
0.0.15
* Minor bug fix
0.0.14
* Adding the ability to have exclusion urls
0.0.12
* Diagnostic Options
0.0.11
* Bug Fix for port logic
0.0.10
* Added support for IPs with port numbers
0.0.9
* Fixing deploy issues
0.0.8
* Auto deploys for npm
0.0.7
* Add support ip ranges.
0.0.6
* Fixed a bug when using console output
0.0.5
* Added ability to block by subnet mask (i.e. 127.0.0.1/24)
* Added tests for cidr functionality
0.0.4
* Add tests
* Update docs
* Refactor, and restyle
0.0.1
* First revision
## Credits
BaM Interactive - [code.bamideas.com](http://code.bamideas.com)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc