reCAPTCHA in Orchard Core Forms Prevent brute-force attacks and spam on Orchard Core Forms using reCAPTCHA

ReCaptcha Users in Orchard Core to Protect Logon, Register, and Password Forms

In this Orchard Core tutorial I’ll be presenting a security feature, called ReCaptcha Users, that is included in Orchard Core. ReCaptcha Users enables reCAPTCHA on the user logon, registration, reset password, and change password forms. It’s disabled out-of-the-box in the Orchard Core built-in themes, but I think it’s worth enabling even on your personal Orchard Core CMS websites. If this is your first time using ReCaptcha Users, you may wonder how it works. The goal of this tutorial is to dive a little deeper into ReCAPTCHA Users as well as provide code examples on how an Orchard Core Developer can modify it’s default configuration as well as extend it.

ReCaptcha in Orchard Core

Before I begin looking at the ReCaptcha Users feature in Orchard Core, however, it’s important to understand that ReCaptcha and ReCaptcha Users are separate features in Orchard Core. The ReCaptcha feature enables the core reCAPTCHA services. Once enabled, you are prompted to configure your site key and secret key in the reCAPTCHA settings. The ReCaptcha feature is often enabled with Orchard Core Forms and Orchard Core Workflows to prevent bot abuse of non-user account related forms on the website, such as a contact form. Using the ReCaptcha Widget and a Validate ReCaptcha Workflow Activity one can help alleviate form abuse on the Orchard Core website.

ReCaptcha and ReCaptcha User Features in Orchard Core

ReCaptcha Users in Orchard Core

ReCaptcha Users is a separate feature from ReCaptcha that harnesses the functionality of reCAPTCHA to help prevent abuse of your user account related forms, such as the logon, register, reset password, and change password forms used by Orchard Core. ReCaptcha Users depends on ReCaptcha and will automatically enable ReCaptcha if it hasn’t been enabled already. If this is the case, you will need to configure your reCAPTCHA settings with your site key and secret key.

If you’re using the built-in user account forms in Orchard Core, you don’t need to do anything but enable ReCaptcha Users to help prevent abuse of those forms. However, if you enable the feature and sign out of Orchard Core and attempt to sign back in, it might surprise you to not see a reCAPTCHA challenge on the Orchard Core logon page. The answer to that mystery requires a deeper understanding of the ReCaptcha Users feature. To keep things easier to understand I will focus on the logon process, but the concepts mentioned apply to registration and password related forms in Orchard Core as well.

ReCaptcha Users uses an ASP.NET Core result filter and a logon form event handler to help decide when to add the reCAPTCHA challenge to the logon form. The result filter calls into a ReCaptcha service in Orchard Core to determine if the reCAPTCHA challenge should be added to the form. The ReCaptcha service queries a collection of robot detectors to determine if the current logon request is possibly from a robot. If any of those robot detectors determine that the request is probably from a robot, the reCAPTCHA challenge is added to the logon form.

reCAPTCHA added to Orchard Core Logon Form

IpAddressRobotDetector in Orchard Core

Orchard Core ships with one robot detector, IpAddressRobotDetector. This robot detector keeps track of the number of consecutive invalid logon attempts by an IP address. These logon attempts are forwarded to the IpAddressRobotDetector by the custom logon form event handler that I mentioned above. If the number of consecutive invalid logon attempts for an IP address exceeds a certain threshold, the IpAddressRobotDetector responds that the request may be coming from a robot. Hearing this, the result filter adds the reCAPTCHA challenge to the Orchard Core logon form.

The default threshold is part of the ReCaptcha settings.

public int DetectionThreshold { get; set; } = 5;

Unless configured otherwise, the IpAddressRobotDetector will allow 5 consecutive, unsuccessful logon attempts before recommending the reCAPTCHA challenge be added to the Orchard Core logon form on the 6th attempt. You can, of course, modify this detection threshold, but this is why the reCAPTCHA challenge won’t be initially displayed on the logon page after activating the ReCaptcha Users feature in Orchard Core.

Re-Configuring ReCaptcha’s Detection Threshold

An application may require a different detection threshold other than 5. In fact, the client may request that the reCAPTCHA challenge always be required on the Orchard Core logon page. To satisfy such a request, you can modify the ReCaptcha settings. Either in the Startup class of your Orchard Core CMS website or as part of the Startup class in a custom Orchard Core CMS module, you can modify the ReCaptcha settings to your desired threshold.

services.Configure<ReCaptchaSettings>(config =>
    config.DetectionThreshold = -1
);

In this case I am setting the DetectionTheshold property to -1, which always adds the reCAPTCHA challenge to the Orchard Core logon form. The IpAddressRobotDetector will recommend the reCAPTCHA challenge anytime the number of consecutive unsuccessful logon attempts exceeds the default threshold, and 0 > -1.

Custom Robot Detectors - IDetectRobots

In addition to modifying the ReCaptcha settings, you are also free to create your own robot detectors by creating a custom class that implements IDetectRobots. As the name of the interface suggests, classes that implement IDetectRobots are recommendation services used by the ReCaptcha service to determine if a request is from a human or robot. The IpAddressRobotDetector is one such robot detector.

Let’s create our own custom robot detector, called BetterSafeThanSorryRobotDetector, in Orchard Core that always says the current logon request is from a robot, causing the reCAPTCHA challenge to be added to the logon form.

public class BetterSafeThanSorryRobotDetector : IDetectRobots
{
    public RobotDetectionResult DetectRobot()
    {
        return new RobotDetectionResult
        {
            IsRobot = true
        };
    }

    public void FlagAsRobot() { }

    public void IsNotARobot() { }
}

We can then add our custom robot detector to the dependency injection container so that it is consumed and called by the ReCaptcha service when determining if the reCAPTCHA challenge needs to be added to the logon form.

services.AddSingleton<IDetectRobots, BetterSafeThanSorryRobotDetector>();

Again, this can be added directly to the Orchard Core Website's Startup class or to the Startup class of a custom Orchard Core Module.

Conclusion

In this Orchard Core tutorial we discussed the ReCaptcha and ReCaptcha Users Features in Orchard Core and took a deeper look at how the reCAPTCHA challenge is added to various user account forms in Orchard Core to protect the logon, register, password reset, and change password forms.

Using the Orchard Core logon process as our primary example, we discussed the role of the custom logon form event handler and result filter used in concert with the ReCaptcha service and robot detectors in Orchard Core to determine if a request is from a human or robot. We then looked at the IpAddressRobotDetector and how it uses a default threshold as part of the ReCaptcha Settings to determine if a request is a human or robot based on the number of consecutive unsuccessful logon attempts per IP address.

Using this knowledge, we re-configured the ReCaptcha settings in Orchard Core to change the default threshold used by the IpAddressRobotDetector as well as created a custom robot detector, called BetterSafeThanSorryRobotRobotDetector, which suggests every request is from a robot, causing the reCAPTCHA challenge to be added to all user account forms at all times.