What Happens When Attackers Target Your Login Page
Every website with a login form is a target. It does not matter if you run a small business in Lugano or a multinational operation. Automated tools scan the internet for login pages 24 hours a day, 7 days a week. When they find one, they start trying passwords.
This is not a theoretical risk. Akamai reported over 193 billion credential stuffing attacks in 2020 alone. Cloudflare blocks millions of brute force attempts per day across their network. Your site is part of that target surface whether you know it or not.
The reason these attacks persist is simple: they work. Default credentials, weak passwords, and missing rate limiting give attackers easy wins. A single compromised admin panel can lead to data theft, website defacement, malware injection, or ransomware deployment.
This article breaks down exactly how brute force and credential stuffing attacks operate, presents real statistics on automated login attempts, and walks through every countermeasure you should have in place.
How Brute Force Attacks Work
A brute force attack is the simplest form of password cracking: try every possible combination until one works. In practice, modern brute force tools are far more sophisticated than trying "aaaaaa" then "aaaaab." They use optimized strategies to find valid credentials faster.
Pure Brute Force
The attacker tries every possible character combination for a given length. For a 6-character password using lowercase letters, that is 308 million combinations. For an 8-character password with uppercase, lowercase, numbers, and symbols, it is over 6 quadrillion combinations.
Pure brute force is slow against strong passwords. But against weak ones (like "admin1" or "password"), it works in seconds.
Dictionary Attacks
Instead of trying every combination, dictionary attacks use lists of common passwords. These wordlists contain millions of entries compiled from previous data breaches. The top passwords appear in virtually every breach database:
- 123456 (used by over 23 million accounts in breach databases)
- password
- 123456789
- qwerty
- 12345678
- admin
- welcome
- letmein
Dictionary attacks are fast because they skip unlikely combinations and focus on passwords people actually use. A wordlist of 10 million common passwords can be tested against a web login in hours, depending on the rate limiting in place.
Credential Stuffing
Credential stuffing is the most effective variant. The attacker takes username-password pairs from a previous data breach (LinkedIn, Adobe, Dropbox, or any of the thousands of breaches that have leaked billions of credentials) and tries them on your site.
Why does this work? Because people reuse passwords. Studies consistently show that 60-65% of people use the same password across multiple services. If your employee used the same password for their LinkedIn account and your company WordPress admin panel, a LinkedIn breach gives the attacker access to your website.
Credential stuffing is harder to detect than brute force because each login attempt uses a valid-looking username and a plausible password. There are no patterns of sequential guessing to flag.
Hybrid Attacks
Hybrid attacks combine dictionary words with common modifications: appending numbers (password1, password123), replacing letters with symbols (p@ssw0rd), capitalizing the first letter (Password). These catch users who think they are being clever by making minor modifications to common words.
The Tools Attackers Use
You do not need to be a skilled hacker to run brute force attacks. The tools are free, open source, and well documented:
- Hydra: A parallelized login cracker that supports dozens of protocols including HTTP forms, SSH, FTP, and SMTP. It can run thousands of attempts per minute against a web login.
- Burp Suite: A web security testing platform with an Intruder module designed for automated login attacks. The community edition is free.
- WPScan: A WordPress-specific scanner that includes brute force capabilities for wp-login.php and XML-RPC endpoints.
- Sentry MBA, OpenBullet: Credential stuffing tools that use "configs" shared in underground forums. Each config is tailored for a specific website's login form.
The barrier to entry is extremely low. A teenager with a laptop and a wordlist can launch a brute force attack in minutes.
Statistics on Automated Login Attempts
The scale of automated login attacks is staggering:
| Metric | Value | Source |
|---|---|---|
| Credential stuffing attacks in 2020 | 193 billion | Akamai |
| Percentage of all login traffic that is malicious | Over 90% on some sites | Shape Security |
| Average cost of a credential stuffing attack | USD 6 million per year | Ponemon Institute |
| WordPress sites attacked via brute force per day | Over 900,000 | Wordfence |
| Time to crack "password123" with brute force | Less than 1 second | Hive Systems |
| Percentage of users reusing passwords | 60-65% | Google/Harris Poll |
If you run a WordPress site, Wordfence data shows that brute force attacks on wp-login.php and xmlrpc.php represent one of the top three attack vectors. Every WordPress site we audit for businesses in Ticino shows evidence of brute force attempts in the access logs.
Why Default Credentials Remain Attack Vector Number One
It sounds absurd in 2022, but default credentials are still the most effective way into a system. Here is why:
- CMS installations: WordPress, Joomla, and Drupal installations often keep the default "admin" username. The attacker already knows half the credentials.
- Network equipment: Routers, switches, and IoT devices ship with default credentials (admin/admin, admin/password, root/root). Many are never changed.
- Development environments: Staging servers, development databases, and test instances often use simple credentials that accidentally make it to production.
- Third-party plugins: Some WordPress plugins and themes create admin accounts with default passwords during installation.
The Mirai botnet, which took down major internet services in 2016, worked by trying just 62 default username/password combinations against IoT devices. That was enough to build a botnet of over 600,000 devices.
Countermeasure 1: Rate Limiting
Rate limiting is your first line of defense. It restricts the number of login attempts from a single source within a time window.
How to Implement Rate Limiting
At the application level, track failed login attempts per IP address and per username. After a threshold (for example, 5 failed attempts in 15 minutes), add an increasing delay before the next attempt is processed.
At the server level, tools like nginx can enforce rate limits on specific endpoints:
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
This configuration limits each IP address to 5 requests per minute on the login endpoint. Legitimate users will never hit this limit. Automated tools will be throttled significantly.
Limitations
Simple IP-based rate limiting is not enough by itself. Sophisticated attackers distribute their attempts across thousands of IP addresses using botnets or proxy networks. You need additional layers.
Countermeasure 2: CAPTCHA
CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) adds a challenge that is easy for humans but difficult for bots.
Options
- reCAPTCHA v2: The "I'm not a robot" checkbox. Works well but adds friction.
- reCAPTCHA v3: Invisible, scores each request from 0.0 to 1.0 based on behavioral analysis. No friction for users, but requires tuning the threshold.
- hCaptcha: A privacy-focused alternative to reCAPTCHA. Especially relevant for Swiss businesses concerned about data processing under nLPD.
- Cloudflare Turnstile: Cloudflare's CAPTCHA alternative. Free, privacy-preserving, and frictionless in most cases.
When to Show CAPTCHA
Do not show CAPTCHA on every login attempt. That annoys legitimate users. Show it after 2-3 failed attempts from the same IP or for the same username. This way, normal users with a typo are not bothered, but automated tools are blocked after their first few tries.
Countermeasure 3: Account Lockout Policies
Account lockout temporarily disables an account after a number of failed login attempts.
Implementation
- After 5 failed attempts, lock the account for 15 minutes.
- After 10 failed attempts, lock for 1 hour.
- After 20 failed attempts, lock until manual review.
The Denial of Service Risk
Account lockout has a significant downside: an attacker can deliberately lock out legitimate users by trying wrong passwords against their accounts. This is a denial-of-service attack against specific users.
To mitigate this, combine lockout with other signals. Lock based on IP + username combination rather than username alone. Send notification emails when accounts are locked so users know what happened. Provide an alternative recovery path (email reset link) that bypasses the lockout.
Countermeasure 4: IP Blocking
Blocking IP addresses that generate excessive failed login attempts removes known bad actors from the equation.
Static Blocking
Maintain a blocklist of known malicious IP ranges. This is useful for blocking entire hosting providers or geographic regions that consistently generate attacks but no legitimate traffic.
Dynamic Blocking
Automatically block IPs that exceed a threshold of failed login attempts. This is where tools like fail2ban come in (covered in detail below).
Geo-Blocking
If your website serves customers only in Switzerland, you can restrict login access to Swiss IP addresses. This eliminates attacks originating from other countries. It is not foolproof (VPNs exist) but reduces the attack surface dramatically.
Countermeasure 5: fail2ban
fail2ban is a server-level intrusion prevention tool that monitors log files for signs of malicious activity and automatically bans the offending IP addresses.
How fail2ban Works
- fail2ban monitors log files (e.g., /var/log/auth.log, /var/log/nginx/access.log).
- It applies filter rules to identify failed login attempts.
- When an IP exceeds the configured threshold (e.g., 5 failures in 10 minutes), fail2ban adds a firewall rule to block that IP.
- After a configurable ban time, the IP is automatically unblocked.
Configuration for Web Logins
For a WordPress site, a fail2ban jail configuration looks like this:
[wordpress-login]
enabled = true
filter = wordpress-login
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 300
bantime = 3600
This bans any IP that generates 5 failed login attempts within 5 minutes (300 seconds) for 1 hour (3600 seconds). fail2ban operates at the firewall level, so banned IPs cannot even reach your web server. This is more efficient than application-level blocking because the connection is dropped before the server processes the request.
Why fail2ban Is a Must for Self-Hosted Sites
If you host your website on a VPS or dedicated server (common for businesses in Switzerland that want data residency), fail2ban should be installed and configured for every exposed service: SSH, web login, FTP, SMTP. It is lightweight, free, and dramatically reduces the volume of automated attacks that reach your application.
Countermeasure 6: Cloudflare WAF (Web Application Firewall)
A WAF sits between the internet and your web server, filtering malicious traffic before it reaches your application. Cloudflare is the most widely used option, but alternatives include Sucuri, AWS WAF, and Imperva.
How Cloudflare WAF Stops Brute Force
- Bot detection: Cloudflare uses machine learning to distinguish automated tools from real browsers. Known bot signatures are blocked automatically.
- Rate limiting rules: You can create custom rules that limit login attempts per IP, per session, or per other criteria.
- Managed rulesets: Cloudflare maintains rulesets that block known attack patterns, including brute force tools.
- Challenge pages: Suspicious traffic is presented with a JavaScript challenge or CAPTCHA before reaching your login page.
- IP reputation: Cloudflare maintains a reputation database of IP addresses. IPs associated with malicious activity across Cloudflare's entire network are automatically challenged or blocked.
Configuration for Login Protection
In Cloudflare's dashboard, create a firewall rule that targets your login URL (e.g., /wp-login.php or /admin/login). Apply a "Managed Challenge" action for all requests to this URL. Then create a rate limiting rule: if an IP makes more than 5 POST requests to the login URL in 1 minute, block for 1 hour.
For businesses in Ticino and across Switzerland, Cloudflare's free plan includes basic WAF features. The Pro plan (USD 20/month) adds the full managed ruleset. This is one of the highest-value security investments you can make for a website. For a broader perspective on web security for business sites, see our article on website security for business.
Countermeasure 7: Two-Factor Authentication (2FA)
Two-factor authentication is the single most effective defense against brute force and credential stuffing. Even if an attacker obtains the correct password, they cannot log in without the second factor.
Types of 2FA
- TOTP (Time-based One-Time Password): Apps like Google Authenticator, Authy, or Microsoft Authenticator generate a 6-digit code that changes every 30 seconds. This is the standard recommendation for most business websites.
- Hardware security keys: Physical devices (YubiKey, Google Titan) that use the FIDO2/WebAuthn protocol. The most secure option, immune to phishing.
- SMS codes: A code sent via text message. Better than no 2FA, but vulnerable to SIM swapping attacks. Not recommended as the primary 2FA method.
- Email codes: A code sent to the user's email. Better than nothing but depends on the security of the email account.
Implementing 2FA on WordPress
For WordPress, several plugins provide 2FA:
- WP 2FA: Free, supports TOTP and email codes. Can enforce 2FA for all users or specific roles.
- Two Factor Authentication (by Plugin Contributors): Lightweight, supports TOTP and backup codes.
- Wordfence: Includes 2FA as part of its broader security suite.
For custom web applications, libraries exist for every framework: speakeasy for Node.js, pyotp for Python, OTPHP for PHP.
Why 2FA Solves Credential Stuffing
Credential stuffing works because stolen passwords are valid. But a stolen password combined with 2FA is useless. The attacker has the password but cannot generate the TOTP code. This one measure eliminates the entire credential stuffing attack vector.
Implementing Login Security Properly: A Layered Approach
No single countermeasure is sufficient. The correct approach is defense in depth, where multiple layers work together so that a failure in one layer is caught by the next.
Layer 1: Network Level (WAF + IP Blocking)
Cloudflare WAF or equivalent filters out known bots, applies rate limits, and blocks IP addresses with bad reputation. This stops the bulk of automated traffic before it reaches your server.
Layer 2: Server Level (fail2ban + Rate Limiting)
fail2ban monitors logs and blocks IPs that bypass the WAF. Server-level rate limiting (nginx or Apache) provides an additional throttle on login endpoints.
Layer 3: Application Level (CAPTCHA + Account Lockout)
After a few failed attempts, the application shows a CAPTCHA. After more failures, the account is temporarily locked. These measures catch attackers who have bypassed the network and server layers.
Layer 4: Authentication Level (2FA + Strong Passwords)
Even if all other layers fail and the attacker guesses the correct password, 2FA prevents login. This is your last line of defense, and it is extremely effective.
Recommended Configuration Summary
| Layer | Tool | Configuration |
|---|---|---|
| Network | Cloudflare WAF | Managed Challenge on login URL, rate limit 5 req/min |
| Server | fail2ban | Ban IP after 5 failures in 5 minutes, ban duration 1 hour |
| Server | nginx rate limit | 5 requests/minute per IP on login endpoint |
| Application | CAPTCHA | Show after 3 failed attempts per IP or username |
| Application | Account lockout | Lock after 10 failures, unlock after 15 minutes |
| Authentication | 2FA (TOTP) | Mandatory for all admin and editor accounts |
Additional Hardening Measures
Rename or Hide the Login URL
For WordPress, the default login URL is /wp-login.php. Every bot on the internet knows this. Plugins like WPS Hide Login let you change it to a custom URL (e.g., /my-secret-login). This does not provide real security (security through obscurity), but it eliminates a massive amount of automated noise in your logs.
Disable XML-RPC
WordPress's XML-RPC interface (xmlrpc.php) allows login attempts that bypass wp-login.php protections. Attackers use the system.multicall method to test hundreds of passwords in a single request. Unless you specifically need XML-RPC (for Jetpack or the WordPress mobile app), disable it entirely. For more on WordPress-specific vulnerabilities, see our article on WordPress security and updates.
Enforce Strong Password Policies
Require passwords that are at least 12 characters long and check them against known breach databases (the HaveIBeenPwned API provides this service for free). Do not enforce arbitrary complexity rules (must include uppercase, number, symbol) because they lead to predictable patterns like "Password1!". Length matters more than complexity.
Use Unique Usernames
Do not use "admin" as a username. In WordPress, do not let the display name match the login username. Use email-based login where possible, as email addresses are harder to enumerate than usernames.
Monitor Login Activity
Log all login attempts (successful and failed) with timestamps, IP addresses, and usernames. Review these logs regularly. Set up alerts for unusual patterns: successful logins from new locations, multiple failed attempts against a single account, or logins at unusual hours.
What to Do If You Suspect an Ongoing Brute Force Attack
- Check your access logs. Look for repeated POST requests to your login URL from the same IP or from many different IPs targeting the same endpoint.
- Enable or tighten rate limiting immediately. If you do not have rate limiting in place, add it now.
- Activate Cloudflare "Under Attack" mode if you use Cloudflare. This presents a JavaScript challenge to every visitor, which blocks most automated tools.
- Force password resets for all admin and editor accounts, especially if you suspect credentials may have been compromised.
- Enable 2FA on all privileged accounts if it is not already active.
- Check for successful unauthorized logins in your application logs. If you find any, treat this as a security incident and follow your incident response plan.
The Cost of Doing Nothing
Brute force defense is not expensive. Cloudflare's free plan covers basic protection. fail2ban is free open-source software. 2FA plugins for WordPress are free. The total cost of implementing all the countermeasures described in this article is close to zero for most websites.
The cost of a successful attack, on the other hand, ranges from website defacement (reputation damage, cleanup costs) to full data breach (legal liability under nLPD and GDPR, customer notification costs, regulatory fines). For a Swiss SME, a data breach can easily cost CHF 50,000 to 200,000 when you factor in incident response, legal fees, customer communication, and lost business.
If you manage a business website and your login page has no rate limiting, no CAPTCHA, no 2FA, and uses default credentials, you are not just at risk. You are already being attacked. The only question is whether the attackers have succeeded yet.
Next Steps
At Envestis in Lugano, we perform security assessments that include testing login protections against brute force attacks. We check rate limiting, CAPTCHA implementation, 2FA configuration, and server-level defenses. We then implement the fixes, layered from network to application level.
If you want to know whether your website login is properly protected, or if you need help implementing the countermeasures described here, get in touch. A login that can be brute-forced is not a theoretical vulnerability. It is an open door.
Want to know if your site is secure?
Request a free security audit. In 48 hours you get a complete report.
Request Free Audit