Combating SPAM user registration on Magento

There has been a recent resurgence of Magento SPAM user registrations, often predominantly from a single country. These highly distributed attacks (in terms of source IPs) can overwhelm a small Magento store and traditional WAF's aren't always as effective as you would hope.

There are however some lines of defence you can put in place to help mitigate these attacks.

Identifying the attack

Using the incident diagnosis dashboard on Kibana - you can quickly identify the URLs being targeted, the source IPs and even country.

  1. Connect to the VPN for your stack
  2. Visit the dashboard, http://kibana.magestack.com/#/dashboard/elasticsearch/local-incident-diagnosis

Traffic by status code

Traffic by IP

Traffic by user agent

Traffic by country code

Traffic by URI


Enable CAPTCHA

The first line of defence; in Magento 1.7 and above, a new feature was introduced, CAPTCHA. This adds a challenge for automated bots to be able to enter a random value as displayed in the image on the page. CAPTCHA can be enabled on,

  • Create user
  • Login
  • Forgot password
  • Checkout as guest
  • Register during checkout

There's a balance to be struck between not compromising customer experience and combating an attack you might be experiencing. So my suggestion would be to take a reactive approach and only enable CAPTCHA on the areas you are seeing an attack. You can use the top URL panel from Kibana to know what the attacker is targeting.

Blocking by IP

This is probably the least best approach to handling this type of situation, as an attacker is unlikely to be using a single IP (except in the example above) - and if they were, would likely change the source of the attack once they have been detected. This approach also doesn't really scale (you can't forever watch Kibana blocking a single IP at a time).

But nevertheless, in some cases, it may just work.

To block by IP on the whole stack, you can add the following rule to the global Nginx configuration file. You can find this file in,

/microcloud/domains/.nginx-global-general.pre.conf

Then you can block individual IPs like so, Eg. to block 10.10.5.5

deny 10.10.5.5;

Blocking by User Agent

The browser user-agent can be faked, so blocking by user agent can range from highly effective to highly damaging. This means caution should be taken in looking at the user agent itself to see that it isn't one typically used by a customer.

Eg. MJ12-Bot, AHrefsBot etc. are strictly bots - and if you don't use these services, you can block them without hesitation

Blocking by user-agent is a straightforward process,

if ($http_user_agent ~* "YandexBot") {
  return 403;
}

Blocking by Country Code

MageStack's native GeoIP identification means that all requests get tagged with an origin country using MaxMind's GeoIP database. Whilst not a 100% accurate source, it again can be highly effective in blocking a large range of sources without individually blocking IP addresses on their own.

Blocking by country code is again a straightforward process where you can identify the country potentially at fault - and prevent it accessing your website.

Using two letter country codes you can block countries in a single statement,

if ($geoip_country_code ~* (ua)) {
  return 403;
}

Rate limiting requests

The power of MageStack's filtering rules mean that you can create focused rate limiting rules for any number of combinations (URL, country code, user agent etc.) - allowing you to still grant access, with restrictions on the volume of repeat requests that can be made.

There are many examples of how to rate limit requests, where customer registration could be limited like so,

location ~* /customer/account/(create(post)?|index|login) {
  if ($request_method = "POST") {
    set $magestack_custom_limit one_per_sixty_seconds;
  }
  // Disable rate limiter for specific IPs
  if ($remote_addr ~ "(my.ip.addr.ess|my.ip.addr.ess)") {
    set $magestack_custom_limit "";
  }
  // Disable rate limiter for specific countries
  if ($geoip_country_code ~ "(aa|bb)") {
    set $magestack_custom_limit "";
  }
  limit_req zone=custom_one_per_sixty_seconds;
}

Cleaning up created users

Once you've got your mechanisms in place to help prevent further SPAM registrations, its time to clean up the records created. I've made a quick shell script for Magento that you can download.

  1. Download the gist to the Magento shell directory
    wget --no-check-certificate https://gist.githubusercontent.com/blessani/e700e35d9ecbade2021c8e0f6d95a8c0/raw/b5b46c1f53e4f12ea093e2e1b7cb03103e51808e/customer.php -qO shell/customer.php
  2. Execute the script in dry run (print only) using matching data you observed in the Magento admin "Manage customers" pane,
    php shell/customer.php --lastname "%drive.google.com%" --print
  3. After reviewing the results, re-run the command with the delete option
    php shell/customer.php --lastname "%drive.google.com%" --delete