Browse Source

Merge pull request #602 from matiu/rate-limiter

adds configurable rate limitation to createWallet
activeAddress
Ivan Socolsky 8 years ago
committed by GitHub
parent
commit
ecb9560555
  1. 2
      README.md
  2. 14
      lib/common/defaults.js
  3. 12
      lib/expressapp.js
  4. 14
      package.json

2
README.md

@ -31,6 +31,8 @@ BWS needs mongoDB. You can configure the connection at `config.js`
BWS supports SSL and Clustering. For a detailed guide on installing BWS with extra features see [Installing BWS](https://github.com/bitpay/bitcore-wallet-service/blob/master/installation.md). BWS supports SSL and Clustering. For a detailed guide on installing BWS with extra features see [Installing BWS](https://github.com/bitpay/bitcore-wallet-service/blob/master/installation.md).
BWS uses by default a Request Rate Limitation to CreateWallet endpoint. If you need to modify it, check defaults.js' `Defaults.RateLimit`
# Security Considerations # Security Considerations
* Private keys are never sent to BWS. Copayers store them locally. * Private keys are never sent to BWS. Copayers store them locally.
* Extended public keys are stored on BWS. This allows BWS to easily check wallet balance, send offline notifications to copayers, etc. * Extended public keys are stored on BWS. This allows BWS to easily check wallet balance, send offline notifications to copayers, etc.

14
lib/common/defaults.js

@ -90,4 +90,18 @@ Defaults.NOTIFICATIONS_TIMESPAN = 60;
Defaults.SESSION_EXPIRATION = 1 * 60 * 60; // 1 hour to session expiration Defaults.SESSION_EXPIRATION = 1 * 60 * 60; // 1 hour to session expiration
Defaults.RateLimit = {
createWallet: {
windowMs: 60 * 60 * 1000, // hour window
delayAfter: 10, // begin slowing down responses after the 3rd request
delayMs: 3000, // slow down subsequent responses by 3 seconds per request
max: 20, // start blocking after 20 request
message: "Too many wallets created from this IP, please try again after an hour"
},
// otherPosts: {
// windowMs: 60 * 60 * 1000, // 1 hour window
// max: 1200 , // 1 post every 3 sec average, max.
// },
};
module.exports = Defaults; module.exports = Defaults;

12
lib/expressapp.js

@ -7,6 +7,7 @@ var log = require('npmlog');
var express = require('express'); var express = require('express');
var bodyParser = require('body-parser'); var bodyParser = require('body-parser');
var compression = require('compression'); var compression = require('compression');
var RateLimit = require('express-rate-limit');
var Common = require('./common'); var Common = require('./common');
var Defaults = Common.Defaults; var Defaults = Common.Defaults;
@ -81,9 +82,9 @@ ExpressApp.prototype.start = function(opts, cb) {
this.app.use(morgan(logFormat, logOpts)); this.app.use(morgan(logFormat, logOpts));
} }
var router = express.Router(); var router = express.Router();
function returnError(err, res, req) { function returnError(err, res, req) {
if (err instanceof WalletService.ClientError) { if (err instanceof WalletService.ClientError) {
@ -169,7 +170,16 @@ ExpressApp.prototype.start = function(opts, cb) {
}); });
}; };
if (Defaults.RateLimit.createWallet) {
log.info('', 'Limiting wallet creation per IP: %d req/h', (Defaults.RateLimit.createWallet.max / Defaults.RateLimit.createWallet.windowMs * 60 * 60 * 1000).toFixed(2))
var createWalletLimiter = new RateLimit(Defaults.RateLimit.createWallet);
router.use(/\/v\d+\/wallets\/$/, createWalletLimiter)
}
// DEPRECATED // DEPRECATED
router.post('/v1/wallets/', function(req, res) { router.post('/v1/wallets/', function(req, res) {
logDeprecated(req); logDeprecated(req);
var server; var server;

14
package.json

@ -3,6 +3,7 @@
"description": "A service for Mutisig HD Bitcoin Wallets", "description": "A service for Mutisig HD Bitcoin Wallets",
"author": "BitPay Inc", "author": "BitPay Inc",
"version": "1.13.0", "version": "1.13.0",
"licence": "MIT",
"keywords": [ "keywords": [
"bitcoin", "bitcoin",
"copay", "copay",
@ -26,6 +27,7 @@
"coveralls": "^2.11.2", "coveralls": "^2.11.2",
"email-validator": "^1.0.1", "email-validator": "^1.0.1",
"express": "^4.10.0", "express": "^4.10.0",
"express-rate-limit": "^2.6.0",
"inherits": "^2.0.1", "inherits": "^2.0.1",
"json-stable-stringify": "^1.0.0", "json-stable-stringify": "^1.0.0",
"locker": "^0.1.0", "locker": "^0.1.0",
@ -68,14 +70,18 @@
"coveralls": "./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" "coveralls": "./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
}, },
"bitcoreNode": "./bitcorenode", "bitcoreNode": "./bitcorenode",
"contributors": [{ "contributors": [
{
"name": "Braydon Fuller", "name": "Braydon Fuller",
"email": "braydon@bitpay.com" "email": "braydon@bitpay.com"
}, { },
{
"name": "Ivan Socolsky", "name": "Ivan Socolsky",
"email": "ivan@bitpay.com" "email": "ivan@bitpay.com"
}, { },
{
"name": "Matias Alejo Garcia", "name": "Matias Alejo Garcia",
"email": "ematiu@gmail.com" "email": "ematiu@gmail.com"
}] }
]
} }

Loading…
Cancel
Save