How we defend Forms Service from automated attacks without frustrating users
Forms Service is constantly under attack. Bots try to scrape forms, attackers test stolen credentials, and malicious actors send spam at scale. CAPTCHA is our primary defense.
But there's a cost: always-on CAPTCHA frustrates legitimate users and reduces conversion rates. This document explains how we've solved that trade-off using five targeted rules that activate CAPTCHA only when we detect suspicious patterns.
CAPTCHA protects against four major threat vectors:
The fundamental trade-off: No CAPTCHA means attackers win. Always-on CAPTCHA means users lose. Our five rules split the difference: CAPTCHA activates only when we detect something genuinely suspicious.
More than 500 requests from the same IP address in less than 20 minutes.
A single attacker (or compromised machine) firing requests as fast as possible. The pattern suggests credential stuffing, form scraping, or direct API abuse. The 500-request threshold is high enough to miss legitimate bulk users but low enough to catch obvious attacks.
Legitimate high-volume users behind a shared corporate IP might see unexpected CAPTCHA. The 20-minute window is tight enough that it only applies during the burst, not to the entire IP range for the day.
This is your first line of defense. It catches the most common attack pattern: repeated requests from a single source in quick succession.
The request comes from an IP address in your internal blacklist.
Known malicious IP addresses from previous attacks, external threat feeds, or manual security team additions. This includes botnets, proxy services, and data center IPs commonly used for abuse.
Users behind blacklisted IPs see CAPTCHA on every interaction. There are no false negatives—if an IP is blacklisted, you've decided to trust that decision completely.
Persistent blocking of repeat offenders. IPs stay blacklisted until explicitly removed by your security team. Fast, decisive, no nuance.
The service receives more than 2x the average request volume for this hour in the current hour bucket.
Sudden traffic spikes that deviate sharply from your baseline. This catches DDoS attacks from many IPs simultaneously, or coordinated attacks that deliberately distribute load to bypass single-source rate limits.
Legitimate traffic spikes also trigger this rule. A viral post, breaking news driving users to your forms, or a successful product launch will all look suspicious. When this rule fires, all users see CAPTCHA. This is your nuclear option—powerful but expensive.
Use when Rules 1 and 2 aren't catching sustained abuse. The 2-week historical baseline prevents false positives from gradual growth. Coordinate with product before major campaigns that might spike traffic.
The same request body is submitted more than 5 times in less than 30 seconds.
Identical form field values. Not the same form type, but the exact same text, selections, and file uploads. For example: a user submits "feedback: 'Great product'" five times in 10 seconds.
Automated form submission tools, spam campaigns, and copy-paste attacks. Simple, obvious automation that doesn't require external intelligence like IP blacklists or historical baselines.
Low impact overall. Duplicate submissions are usually accidental (user hit submit twice). CAPTCHA prevents the duplicate while users understand why it's happening. The 30-second window is tight enough that legitimate workflows almost never hit it.
Lightweight defense against obvious automation without requiring complex infrastructure. An attacker can bypass this by varying payloads even slightly, which is intentional—it prevents legitimate bulk feedback from false-positiving.
A security administrator manually enables CAPTCHA via the admin panel for specific requests.
Active threats identified by humans. Suspected data breaches, coordinated spam campaigns, or edge cases that automated rules aren't catching. This is where human judgment intervenes.
Highest impact. Affects all requests matching the admin's filter criteria. Use only when other rules fail or during active security incidents. Always set a time limit to avoid accidental persistent lockouts.
The human override. When you have context that automated rules don't. Always disable it once the threat passes.
Real-world examples:
The five rules form a layered defense system:
| Rule | Speed | Precision | Primary Purpose |
|---|---|---|---|
| Rule 1: Rate Limit | Instant (real-time counting) | High | Catch obvious attackers |
| Rule 2: Blacklist | Instant (lookup) | Very high | Block known repeat offenders |
| Rule 3: Spike Detection | Delayed (baseline lookup) | Medium | Defend against distributed attacks |
| Rule 4: Payload Dedup | Instant | High | Catch copy-paste automation |
| Rule 5: Admin Override | Instant | Manual (human judgment) | Handle edge cases and novel threats |
Typical attack progression: Most attacks trigger Rule 1 within seconds. Repeat offenders get added to Rule 2 after analysis. Distributed attacks that bypass Rule 1 are caught by Rule 3 or Rule 4. Novel threats or edge cases are handled by Rule 5.
Current CAPTCHA rule settings:
Metrics to track:
Set alerts for:
Check which rule triggered:
Possible causes and solutions:
Reach out to the appropriate team: