From 407cd889cada0154faaa06ff4372e237cf260cf7 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sat, 13 Apr 2019 19:17:00 +0200 Subject: Added live counter for brute force detection --- src/main/kotlin/App.kt | 21 +++++++++++++++------ src/main/resources/js/login.js | 7 +++++++ src/main/resources/views/login.rocker.html | 12 +++++++++--- 3 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 src/main/resources/js/login.js (limited to 'src') diff --git a/src/main/kotlin/App.kt b/src/main/kotlin/App.kt index a958479..ce964e0 100644 --- a/src/main/kotlin/App.kt +++ b/src/main/kotlin/App.kt @@ -49,7 +49,7 @@ fun main() { */ get( "/login", - { ctx -> ctx.render("login.rocker.html", model("message", "")) }, + { ctx -> ctx.render("login.rocker.html", model("message", "", "counter", 0)) }, roles(Roles.GUEST) ) @@ -208,23 +208,32 @@ fun login(ctx: Context) { val difference = Interval(it.first.toInstant(), Instant()).toDuration().standardMinutes.toInt() if (difference < 60) lastHourAttempts += 1 } - val threshold = 4f.pow(lastHourAttempts) + val nextThreshold = 4f.pow(lastHourAttempts + 1) - if (lastAttemptDifference > threshold) { + if (lastAttemptDifference > 4f.pow(lastHourAttempts)) { if (databaseController.checkUser(username, password)) { ctx.cookieStore("uuid", databaseController.getUUID(username)) ctx.cookieStore("username", username) - ctx.render("login.rocker.html", model("message", "Login succeeded!")) + ctx.render("login.rocker.html", model("message", "Login succeeded!", "counter", 0)) } else { databaseController.loginAttempt(DateTime(), requestIp) - ctx.render("login.rocker.html", model("message", "Login failed!")) + ctx.render( + "login.rocker.html", + model( + "message", + "Login failed!", + "counter", if (nextThreshold / 60 > 60) 3600 else nextThreshold.toInt() + ) + ) } } else { databaseController.loginAttempt(DateTime(), requestIp) ctx.render( "login.rocker.html", model( - "message", "Please try again in ${if (threshold / 60 > 60) "3600" else threshold.toString()} seconds." + "message", + "Too many request.", + "counter", if (nextThreshold / 60 > 60) 3600 else nextThreshold.toInt() ) ) } diff --git a/src/main/resources/js/login.js b/src/main/resources/js/login.js new file mode 100644 index 0000000..f4e2bce --- /dev/null +++ b/src/main/resources/js/login.js @@ -0,0 +1,7 @@ +const tryAgain = document.getElementById("tryAgain"); +const countdown = document.getElementById("counter"); + +setInterval(() => { + if (Number(countdown.innerText) === 0) tryAgain.style.display = "none"; + countdown.innerText = Number(countdown.innerText) - 1; +}, 1000); diff --git a/src/main/resources/views/login.rocker.html b/src/main/resources/views/login.rocker.html index 66d9ba2..23a9aff 100644 --- a/src/main/resources/views/login.rocker.html +++ b/src/main/resources/views/login.rocker.html @@ -1,12 +1,17 @@ -@args (String message) +@args (String message, Integer counter) +@js => { + + +} -@layout.template("Login", RockerContent.NONE, RockerContent.NONE) -> { +@layout.template("Login", RockerContent.NONE, js) -> {
- +
+
@@ -15,6 +20,7 @@ @if(message.length() > 0) { @message + Please try again in @counter seconds. }
} -- cgit v1.2.3