HackerSpray
Repel hackers with this library by blocking brute force and malicious attempts on sensitive URLs
Install / Use
/learn @oazabir/HackerSprayREADME
HackerSpray

A .NET library to defend websites and web APIs against brute force and Denial-of-Service attacks.
It comes as .NET 4 and .NET Core library.
Features:
- Protect login, registration, password reset pages against brute force and DOS attacks.
- Block users from performing any action too many times.
- Prevent too many hits from any IP or IP Range.
- Blacklist/Whitelist specific IP, IP range, username, URLs, transactions for a period.
An example scenario is a Bank Login page, where brute force password attempts on user accounts and DOS attack on Login page are a regular event. Using this library, you can protect login page from brute force attacks, blocking too many usernames from certain IPs, or too many hits from a range of IP trying to do DOS attack, or even simple 3 invalid login attempts per username, per 15 mins.
This high performance, very lightweight library protects you from hitting the database too many times on pages or APIs that are target for attacks, thus lowering web server and database CPU, increasing the scalability of the overall application.
Show me the speed
Let's compare the performance of a Login page which does authentication with a database.
Server throughput increase
When attack is going on and expensive .net code is getting hit, you get high CPU and low throughput. But as soon as HackerSpray starts blocking traffic, CPU on webserve goes down and server throughput shots high up.

Response time
When ASP.NET code is executing, response time is avg 36ms, as you see on the top 2 lines. But when HackerSpray is blocking requests, response time is low, at around 8ms.

Prevent code execution
When HackerSpray starts blocking requests, it blocks from HttpModule responding with Http Response Code 406. In the below graph, you can see when requests are getting blocked, Login code is no longer getting hit.

How it works
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.
Example calls:
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);
HackerSpray is a fully non-blocking IO, .NET 4.5 async library, maximizing use of Redis pipeline to produce least amount of network traffic and latency. It uses the StackExchange.Redis client.
There's a convenient DefendAsync overload for ASP.NET Controllers. Here's an example how you can protect the Login() method:
[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()
);
}
This DefendAsync allows you to wrap your existing Controller code with the defence.
You put the existing code in your Controller methods inside the async (success, fail) delegate.
Then while returning the response object, you wrap the return object with success() or fail().
HackerSpray will then maintain success and failure counters.
If there are too many success or failed attempt as per the configuration, it will block further execution
of the code inside the delegate, thus protecting your expensive business logic from attacks.
Why not use a firewall?
Couple of reasons:
- Firewalls have no intelligence on what business transaction is being performed. Thus you cannot implement brute force check against transactions. It is either URL or IP.
- If a firewall has to implement brute force attack detection, it has to read the whole payload and then inspect for patterns. This requires high CPU Á Memory usage on Firewall. In case of https, it requires you to terminate https at firewall level so that it can read the received data.
- Most firewalls have basic scripting language to configure rules. Some do support javascript like language, but check the CPU cost of that and the price tag. With HackerSpray, you get .net code, so the sky is the limit.
- Firewalls have limited storage for logs and shipping logs from firewall to analysis engines puts stress on the firewall, especially when you are under attack. Many a times we experience Firewall CPU exhaustion when it is blocking DOS, while it is writing all those attacks in a log and also shipping the logs to our analysis servers.
With that being said, you should use Firewall for certain cases and HackerSpray for different cases. You should use Firewall to limit maximum number of connections per IP, maximum number of connections opened to a webserver, rate limit, blacklisted IP and URLs. More than that, go for HackerSpray. It is better to perform CPU intensive operations at webserver level, because you have plenty of them. Usually you have only one active firewall and thus best not to put CPU intensive operation on them.
Getting Started
.NET 4
Get the HackerSpray library and HTTP Module to defend your website using:
Install-Package HackerSpray
It will do all the configuration to enable HackerSpray for your web project.
.NET core
For .NET Core, use:
Install-Package HackerSprayCore
It will do nothing to enable HackerSpray for your web project. You need to do the following:
Step 1: Add hackerspray.json in the configuration
{
"HackerSpray": {
"Redis": "127.0.0.1",
"Prefix": "AuthTest-Core:",
"Keys": [
"POST /Account/Login 100 00:10:00 key+origin",
"GET /Account/Login 100 00:10:00 key+origin",
"GET /Home/ 10000 00:10:00 key+origin"
]
}
}
On your Startup.cs, load this config file:
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
Add this line--> .AddJsonFile("hackerspray.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
Step 2: Add the HackerSpray service in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
.
.
services.AddHackerSpray(Configuration.GetSection("HackerSpray"));
}
Step 3: Add HackerSpray middleware in Startup.service
Add app.UseXForwardedFor(); and app.UseHackerSpray(); right after UseStaticFiles() and before UseMvc();
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
.
.
.
app.UseStaticFiles();
app.UseXForwardedFor();
app.UseHackerSpray();
.
.
.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Run Redis server
If you have installed from Nuget, redis will be downloaded and stored in packages folder.
Configuring HackerSpray
In the web.config or hackerspray.json you need to specify which paths to protect using the HttpModule or Middleware:
<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" inte
Related Skills
node-connect
351.8kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
110.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
351.8kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
351.8kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
