HackerSpray

HackerSpray uses Redis to maintain high-performance counters for actions and origin IPs. You call Hacker.Defend(key, ip) to check if a certain key or IP has made too many hits. You can maintain blacklists for key, IP or IP Range. HackerSpray checks against too many hits on a key, too many hits on an IP, or IP falling within blacklists. It also allows blacklisting a certain key for a certain IP or blocking a certain key for all IPs on-the-fly. Handy when you want to block a user out of certain URLs.

It comes with a HttpModule, which protects your entire website.


var result = await Hacker.DefendAsync("/Account/LogOn", Request.UserHostAddress);

if (result == Hacker.Result.TooManyHitsFromOrigin) 
    await Hacker.BlacklistOriginAsync(Request.UserHostAddress, TimeSpan.FromMinutes(10)); 

else if (result == Hacker.Result.TooManyHitsOnKey) 
    await Hacker.BlacklistKeyAsync("/Account/LogOn", TimeSpan.FromMinutes(10));


 Hacker.DefendAsync("/Account/PasswordReset", Request.UserHostAddress, TimeSpan.FromMinutes(5), 100);
 Hacker.DefendAsync("Username" + username, Request.UserHostAddress);
 Hacker.DefendAsync("Comment", Request.UserHostAddress);


LoginController:


[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }
   return await Hacker.DefendAsync<ActionResult>(async (success, fail) =>
   {
       // This doesn't count login failures towards account lockout
       // To enable password failures to trigger account lockout, change to       shouldLockout: true
        var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
    switch (result)
    {
        case SignInStatus.Success:
            return await success(RedirectToLocal(returnUrl));
        case SignInStatus.LockedOut:
            return await fail(View("Lockout"));
        case SignInStatus.RequiresVerification:
            return await success(RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }));
        case SignInStatus.Failure:
        default:
            ModelState.AddModelError("", "Invalid login attempt.");
            return await fail(View(model));
    }
},
blocked => new HttpStatusCodeResult(HttpStatusCode.Forbidden),
    "ValidLogin:" + model.Email, 3, TimeSpan.FromMinutes(5),
    "InvalidLogin:" + model.Email, 4, TimeSpan.FromMinutes(5),
    Request.GetClientIp()
); }


In the web.config,  specify which paths to protect using the HttpModule.

<HackerSprayConfig redis="localhost" prefix="AuthTest:">
<keys>
  <add name="/Account/LogOn/" post="true" maxAttempts="100" interval="00:10:00" mode="perkeyperorigin" />
  <add name="/Home/" post="false" maxAttempts="10000" interval="00:01:00" mode="perorigin" />
  <add name="/" post="false" maxAttempts="10000" interval="00:01:00" mode="perorigin" />
</keys> 
</HackerSprayConfig>

redis - This is the connection string to Redis server.
prefix - All keys created in redis is prefixed with this.
keys - one entry per path that you want to protect
name - The Path to match
post - true = POST, false = GET
maxAttempts - max number of hits to allow
interval - hits for how long?
mode - How to count the hits and apply blocking
perkey - count hits from all IPs to this key. For ex, allow maximum 1000000 hits to Home page in 10 minutes period.
perorigin - While checking hits to this key, if the origin IP has produced more than the maxAttempts hit overall on any key, then block. For ex, allow 1000 hits per IP, to any key, but do this check on Login page hit.
perkeyorigin - Count hits to this key, per IP. For example, 1000 hits per IP on the Login page.

Comments

Popular Posts