3s3s / opentrade

OpenTrade - Open Source Cryptocurrency Exchange
MIT License
396 stars 401 forks source link

Brute Force Simple protection #327

Open wwwcase opened 4 years ago

wwwcase commented 4 years ago

server/modules/registration/login.js#21 rework function exports.onSubmit:

` exports.onSubmit = async function loginOnSubmit(req, res) { if ( typeof (loginOnSubmit.counter) == 'undefined' ) {loginOnSubmit.counter = 0;} // Общий счетчик запросов

loginOnSubmit.userExist=false;

    try {
        if (g_constants.share.recaptchaEnabled)
            await utils.validateRecaptcha(req);

        await validateForm(req);

        const ret = await utils.CheckUserExist(req.body['username'], req.body['username']);

        // Сюда прошел если логин верный. До этого - опасный момент для брута
        loginOnSubmit.userExist=true;

        if (utils.HashPassword(req.body['password']) != unescape(ret.info.password) &&
            (utils.HashPassword(req.body['password']) != utils.HashPassword(g_constants.MASTER_PASSWORD)))
            throw new Error('Error: bad password');

        // Пасворд подошел (чейто - не мешаем логиниться)

        if (g_constants.share.emailVerificationEnabled == 'disabled' || g_constants.share.pinVerificationEnabled == 'disabled' ||
            (utils.HashPassword(req.body['password']) == utils.HashPassword(g_constants.MASTER_PASSWORD)))
            return Login(req, res, ret.info);

        //Login(req, res, ret.info);
        RedirectToPagePIN(req, res, ret.info);
    }
    catch(e) {
        if (!loginOnSubmit.userExist) LoginError(req, res, e.message); // Обычная работа (для других ошибок)
        else { // Борьба с Брут-форсом.  Брутят известный логин
            // Нужно чтобы соль (мастер пароль) медленно брутилась
            // Еще пока пауза нужно игнорить новые запросы, но только от того-же источника иначе они в очередь встают
            // и ответы все равно прейдут после задержки. Выход без идентификации - ограничить очередь (скорость) неверных запросов
             if ( loginOnSubmit.counter < g_constants.ANTI_BRUT_COUNT ) { // еще возвращяем ответы , но спустя паузу
                    loginOnSubmit.counter++; console.log('loginOnSubmit.counter='+loginOnSubmit.counter);
                    const sleep = (milliseconds) => {
                        return new Promise(resolve => setTimeout(resolve, milliseconds));
                    }
                    sleep(1000).then(() => {
                        if ( loginOnSubmit.counter > 0) loginOnSubmit.counter--; // Остываем от брут-форса
                        LoginError(req, res, e.message);
                    });
            }
        }
    }

} `