Blocking/limiting brute force attacks

As of revision 5.1.16 it is possible to implement a logic for blocking/limiting “brute force” attacks or any abusive number of attempts to log in using the internal authentication.

A typical implémentation relies on the preAuth and postAuth platform hooks.

The simple example bellow quarantines a login for a configurable number of minutes after a configurable number of failed login:

package com.simplicite.commons.TestJava;

import java.util.Date;

import com.simplicite.util.AppLog;
import com.simplicite.util.Grant;
import com.simplicite.util.Tool;

public class PlatformHooks extends com.simplicite.util.engine.PlatformHooksInterface {
	private static final int NB_FAILURES = 3;
	private static final int NB_MINUTES = 5;
	private class Quarantine {
		public int count;
		public long date;

		public Quarantine(int count) {
			this.count = count; = new Date().getTime();
		public Quarantine(String q) {
			String[] qs = q.split(";");
			count = Tool.parseInt(qs[0]);
			date = Tool.parseLong(qs[1]);
		public String toString() {
			return count + ";" + date;

	private static final String QUARANTINE = "LOGIN_QUARANTINE_";

	private Quarantine getQuarantine(Grant sys, String login) {
		String q = sys.getParameter(QUARANTINE + login); // non persistent
		//String q = sys.getSystemParam(QUARANTINE + login); // persistent
		return Tool.isEmpty(q) ? null : new Quarantine(q);

	private void setQuarantine(Grant sys, String login, Quarantine quarantine) {
		// Store as a private system parameter
		sys.setParameter(QUARANTINE + login, quarantine.toString()); // non persitent
		//sys.setSystemParam(QUARANTINE + login, quarantine.toString(), true, false, false); // persistent

	private void delQuarantine(Grant sys, String login) {
		sys.removeParameter(QUARANTINE + login); // non persistent
		//sys.setSystemParam(QUARANTINE + login, null); // persistent

	public String preAuth(Grant sys, String provider, String login, String password) {
		Quarantine q = getQuarantine(sys, login);
		// If the number of failures hass reached the limit...
		if (q != null && q.count >= sys.getIntParameter("LOGIN_QUARANTINE_NB_FAILURES", NB_FAILURES)) {
			// ...and the quarantine delay is not expired...
			int nbMin = sys.getIntParameter("LOGIN_QUARANTINE_NB_MINUTES", NB_MINUTES);
			if (new Date( + nbMin * 60000).after(new Date()))
				// ...reject auth request
				return "Too many failures, try again in " + nbMin + " minutes";
				delQuarantine(sys, login);
		return null;

	public String postAuth(Grant sys, String provider, String login, boolean success) {
		// In case of failure...
		if (!success) {
			// ...count nb of failures...
			Quarantine q = getQuarantine(sys, login);
			setQuarantine(sys, login, new Quarantine(q == null ?  1 : q.count + 1));
		} else {
			// De-quarantine in case of success
			delQuarantine(sys, login);
		return null;

During the first erroneous sign in attempts, the usual message indicating a credentials check failure is returned:

Then after a configured number of erroneous sign in attempts, no further credential check is done for the configured next number of minutes and a custom message is returned:


I guess this implementation needs also a garbage collection of “dead” logon when user did not retry after nbMin minutes.

It might be a cron job that destroys old quarantine/locks from memory or DB after nbMin minutes.

Not in this example, the blacklist is temporary and reset after N minutes, especially if the sign in is successful