How to use Zeroasterisk's Throttle with Softwarero's AccountsTemplates?

Hi! Unless there’s already a built-in throttling in trying to login that I’m missing already, how can I use @zeroasterisk’s meteor-throttle with Softwarero’s AccountsTemplates to prevent brute forcing the login page?

It should be very easy to do… I might just whip up a package for it… if you’re impatient

on server:

Accounts.validateNewUser
Accounts.validateLoginAttempt

So something like this? (Edited to work with connection id)

var userConnectionId = '';

Meteor.onConnection(function(conn) {
    userConnectionId = conn.id;
});

Accounts.validateNewUser(function(info) {  
    var key = 'validatenewuser-' + userConnectionId;
    var allowedCount = 5;
    var expireInMS = 10000;
    
    // throttle check
    if (!Throttle.checkThenSet(key, allowedCount, expireInMS))
       throw new Meteor.Error(500, i18n('Slow down cowboy, you are trying this too fast'));

    return true;
});

Accounts.validateLoginAttempt(function(info) {
    var key = 'validateloginattempt-' + userConnectionId;
    //Throttle code same as above
    //other code here
});

I guess use Meteor.default_connection._lastSessionId ?

Edit: The above’s client only, oops!

I guess insert something like this before the above functions:

 var userConnectionId = '';

 Meteor.onConnection(function(conn) {
 userConnectionId = conn.id;
 });

So – I got motivated and stayed up way too late, but came up with something kinda cool:

http://throttle-example.meteor.com/

$ meteor add zeroasterisk:throttle-accounts

if (Meteor.isServer) {
  // configure ThrottleAccounts.login - Accounts.validateLoginAttempt()
  ThrottleAccounts.login(
    'connection',
    2,
    (4 * 60000),
    'Nope - You are limited to 2 logins every 4 min (per DDP connection)'
  );
  ThrottleAccounts.login(
    'ip',
    2,
    (5 * 60000),
    'Nope - You are limited to 2 logins every 5 min (per client IP address)'
  );
  ThrottleAccounts.login(
    'user',
    2,
    60000,
    'Nope - You are limited to 2 login every 1 min (per user account - success only, if failed login, no throttle)'
  );
  ThrottleAccounts.login(
    'global',
    40,
    1000,
    'We are under heavy load - More than 40 logins every second... wait a few, and retry'
  );

  // configure ThrottleAccounts.create - Accounts.validateNewUser()
  ThrottleAccounts.create(
    'global',
    20,
    1000,
    'We are under heavy load - More than 20 creates every second... wait a few, and retry'
  );
}
1 Like

Haha! Terribly sorry to cause you to lose some sleep there! But this is pretty neat :wink:

Can we call multiple ThrottleAccounts like set one for ‘user’ + ‘global’, or ‘connect’ + ‘ip’ + ‘user’, or all of them, or just one of them at a time?

I think there’s a problem with the ‘connection’ throttler. I’m using ‘global’, ‘ip’ and ‘connection’ under my validateLoginAttempt function and it’s throwing its error message prematurely (I haven’t reached 8 login attempts yet)