From feed624cdc507fdeeefbc4e14c93bfc354f9f1dc Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 5 Jun 2017 18:44:48 -0400 Subject: webcpanel: rate limit login attempts --- modules/webcpanel/pages/index.cpp | 33 +++++++++++++++++++++++++++++++++ modules/webcpanel/pages/index.h | 7 ++++++- 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'modules/webcpanel/pages') diff --git a/modules/webcpanel/pages/index.cpp b/modules/webcpanel/pages/index.cpp index 8fdd11352..227a348fd 100644 --- a/modules/webcpanel/pages/index.cpp +++ b/modules/webcpanel/pages/index.cpp @@ -36,6 +36,14 @@ class WebpanelRequest : public IdentifyRequest return; } + // Rate limit logins to 1/sec + time_t *last_login = na->nc->GetExt("webcpanel_last_login"); + if (last_login != NULL && Anope::CurTime == *last_login) + { + this->OnFail(); + return; + } + Anope::string id; for (int i = 0; i < 64; ++i) { @@ -48,6 +56,7 @@ class WebpanelRequest : public IdentifyRequest na->Extend("webcpanel_id", id); na->Extend("webcpanel_ip", client->GetIP()); + na->nc->Extend("webcpanel_last_login", Anope::CurTime); { HTTPReply::cookie c; @@ -91,6 +100,30 @@ bool WebCPanel::Index::OnRequest(HTTPProvider *server, const Anope::string &page if (!user.empty() && !pass.empty()) { // Rate limit check. + Anope::string ip = client->clientaddr.addr(); + + Anope::hash_map::iterator it = last_login_attempt.find(ip); + if (it != last_login_attempt.end()) + { + time_t last_time = it->second; + + if (last_time == Anope::CurTime) + { + replacements["INVALID_LOGIN"] = "Rate limited"; + TemplateFileServer page("login.html"); + page.Serve(server, page_name, client, message, reply, replacements); + return true; + } + } + + // don't let ip hash grow too long + if (Anope::CurTime > last_clear + FLUSH_TIME) + { + last_login_attempt.clear(); + last_clear = Anope::CurTime; + } + + last_login_attempt[ip] = Anope::CurTime; WebpanelRequest *req = new WebpanelRequest(me, reply, message, server, page_name, client, replacements, user, pass); FOREACH_MOD(OnCheckAuthentication, (NULL, req)); diff --git a/modules/webcpanel/pages/index.h b/modules/webcpanel/pages/index.h index 76e3d12a1..771cbf8fc 100644 --- a/modules/webcpanel/pages/index.h +++ b/modules/webcpanel/pages/index.h @@ -12,8 +12,13 @@ namespace WebCPanel class Index : public WebPanelPage { + static const int FLUSH_TIME = 60; + + Anope::hash_map last_login_attempt; + time_t last_clear; + public: - Index(const Anope::string &u) : WebPanelPage(u) { } + Index(const Anope::string &u) : WebPanelPage(u), last_clear(0) { } bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override; }; -- cgit