Bot Detection Validation Test
Bot Detection Validation Test
Relevant source files
Purpose and Scope
This page documents the Bot Detection Validation Test module, which validates the effectiveness of anti-bot security controls in WebSocket applications. This test is part of WSHawk's defensive validation suite and is designed for blue teams to assess whether their bot detection measures can identify automated browsers and resist common evasion techniques.
For information about other defensive validation tests, see Defensive Validation. For DNS exfiltration testing, see DNS Exfiltration Prevention Test. For origin validation testing, see CSWSH Test.
Overview
The Bot Detection Validation Test simulates automated browser attacks to determine if anti-bot measures properly detect and block headless browsers. The module executes two progressive test phases: basic headless detection (using standard automation tools) and evasion resistance (using anti-detection techniques). This validation helps organizations identify gaps in their bot protection before attackers exploit them for credential stuffing, automated scraping, or account takeover attempts.
Sources: wshawk/defensive_validation.py L194-L348
docs/DEFENSIVE_VALIDATION.md L40-L61
Module Architecture
Bot Detection Validator Component Hierarchy
The BotDetectionValidator class inherits from DefensiveValidationModule and implements two test methods that progressively evaluate bot detection capabilities. The validator converts the WebSocket URL to HTTP/HTTPS for browser testing and analyzes the response for bot detection indicators.
Sources: wshawk/defensive_validation.py L194-L211
wshawk/defensive_validation.py L334-L347
Class Structure and Initialization
BotDetectionValidator Class
| Component | Type | Description |
| --- | --- | --- |
| Base Class | DefensiveValidationModule | Provides finding management via add_finding() |
| Constructor | __init__(target_url, oast_domain) | Initializes validator with target URL |
| Attributes | target_url, findings | Stores target and accumulates test results |
| Entry Point | run_all_tests() | Orchestrates test execution sequence |
The BotDetectionValidator class is instantiated with a target WebSocket URL. It inherits finding management capabilities from the base class, allowing it to record test results with CVSS scoring.
BotDetectionValidator Class Inheritance
Sources: wshawk/defensive_validation.py L27-L46
wshawk/defensive_validation.py L194-L210
Test Types and Execution Flow
Test Execution Sequence
The run_all_tests() method implements a conditional execution pattern where the second test only runs if the first test fails. This progressive testing approach reduces unnecessary testing when basic detection is working properly.
Bot Detection Test Execution Flow
The execution logic at wshawk/defensive_validation.py L343-L346
checks if the basic test detected the headless browser (detected=True) or was skipped (skipped=True). Only when detection fails does the validator proceed to the more sophisticated evasion resistance test.
Sources: wshawk/defensive_validation.py L334-L347
Basic Headless Detection Test
Implementation Details
The test_basic_headless_detection() method launches a standard Playwright headless browser without any evasion techniques, navigating to the HTTP/HTTPS equivalent of the target WebSocket URL. It analyzes the page content for bot detection indicators.
Basic Headless Detection Test Workflow
The test defines a list of blocked_indicators that are commonly present in bot detection pages: 'access denied', 'bot detected', 'automated', 'captcha', 'cloudflare', and 'please verify'. The page content is checked against these indicators using case-insensitive substring matching.
Sources: wshawk/defensive_validation.py L212-L264
wshawk/defensive_validation.py L232-L235
Detection Indicators
| Indicator String | Purpose | Common Source |
| --- | --- | --- |
| 'access denied' | Generic access block message | WAFs, custom security |
| 'bot detected' | Explicit bot detection message | Anti-bot services |
| 'automated' | Automation detection message | CAPTCHA services |
| 'captcha' | CAPTCHA challenge present | reCAPTCHA, hCaptcha |
| 'cloudflare' | Cloudflare bot management | Cloudflare |
| 'please verify' | Verification request | Various services |
The presence of any indicator in the page content (case-insensitive) signifies that the target's bot detection successfully identified the headless browser.
Sources: wshawk/defensive_validation.py L232-L235
URL Conversion Logic
The validator converts WebSocket URLs to HTTP(S) for browser testing:
ws://→http://wss://→https://
This conversion occurs at wshawk/defensive_validation.py L229
using Python's str.replace() method chained twice to handle both protocols.
Sources: wshawk/defensive_validation.py L229
Evasion Resistance Test
Anti-Detection Techniques Applied
The test_evasion_resistance() method launches a headless browser with sophisticated evasion techniques designed to bypass common bot detection mechanisms. This simulates what actual attackers might use.
Evasion Resistance Test Techniques
The test implements three primary evasion strategies at wshawk/defensive_validation.py L286-L296
:
- navigator.webdriver Override: Sets the
navigator.webdriverproperty tofalse, masking the automation driver - Plugins Spoofing: Populates
navigator.pluginswith dummy entries to simulate a real browser - Languages Array: Sets
navigator.languagesto common values (['en-US', 'en'])
Additionally, a realistic User-Agent string is configured at wshawk/defensive_validation.py L279-L282
to match a genuine Windows Chrome browser.
Sources: wshawk/defensive_validation.py L266-L333
wshawk/defensive_validation.py L286-L296
JavaScript Injection Script
The anti-detection script is injected using page.add_init_script(), which executes JavaScript before any page content loads. The script uses Object.defineProperty() to override native browser properties, making the manipulation harder to detect.
This code is embedded at wshawk/defensive_validation.py L286-L296
as a multi-line string passed to add_init_script().
Sources: wshawk/defensive_validation.py L286-L296
Findings and CVSS Scoring
Finding Structure
Each test generates a structured finding using the inherited add_finding() method from DefensiveValidationModule. The finding dictionary contains standardized fields for vulnerability tracking.
| Field | Type | Description |
| --- | --- | --- |
| test | str | Test name identifier |
| vulnerable | bool | Whether target is vulnerable |
| severity | str | "CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO" |
| description | str | Detailed finding description |
| recommendation | str | Remediation guidance |
| cvss | float | CVSS v3.1 score (0.0-10.0) |
| timestamp | float | Unix timestamp of finding |
Sources: wshawk/defensive_validation.py L35-L46
CVSS Score Assignments
Bot Detection CVSS Scoring Matrix
| Test Scenario | CVSS Score | Severity | Finding Call | | --- | --- | --- | --- | | Basic Detection Fails | 5.3 | MEDIUM | wshawk/defensive_validation.py L251-L261 | | Evasion Resistance Fails | 7.8 | HIGH | wshawk/defensive_validation.py L320-L329 | | Basic Detection Succeeds | N/A | INFO | wshawk/defensive_validation.py L242-L249 | | Evasion Resistance Succeeds | N/A | INFO | wshawk/defensive_validation.py L310-L318 |
The higher CVSS score for evasion resistance failure (7.8 vs 5.3) reflects the increased risk when anti-bot measures cannot detect sophisticated evasion techniques that attackers commonly employ.
Sources: wshawk/defensive_validation.py L242-L261
wshawk/defensive_validation.py L310-L329
docs/DEFENSIVE_VALIDATION.md L58-L61
Recommendation Strings
Basic Detection Failure Recommendations
When the basic headless detection test fails, the validator generates specific recommendations at wshawk/defensive_validation.py L256-L259
:
"Implement or improve bot detection. Consider:
navigator.webdriver checks, User-Agent validation,
behavioral analysis, commercial bot detection."
The recommendation suggests four defense layers:
- navigator.webdriver checks: Detect the automation flag
- User-Agent validation: Verify header consistency
- Behavioral analysis: Track mouse/keyboard patterns
- Commercial bot detection: Use specialized services (Cloudflare, DataDome, PerimeterX, Akamai)
Sources: wshawk/defensive_validation.py L256-L259
Evasion Resistance Failure Recommendations
For evasion resistance failures, the validator escalates urgency and suggests advanced techniques at wshawk/defensive_validation.py L325-L327
:
"URGENT: Upgrade bot detection. Consider behavioral analysis,
canvas/WebGL fingerprinting, TLS fingerprinting, or commercial services."
The "URGENT:" prefix signals critical priority. Advanced techniques include:
- Behavioral analysis: Timing patterns, mouse movements
- Canvas/WebGL fingerprinting: Rendering inconsistencies
- TLS fingerprinting: Connection-level identification
- Commercial services: Enterprise-grade detection
Sources: wshawk/defensive_validation.py L325-L327
Integration with Defensive Validation Suite
Execution in run_defensive_validation()
The BotDetectionValidator is invoked as the second test in the defensive validation sequence by run_defensive_validation() at wshawk/defensive_validation.py L506-L512
:
Bot Detection in Defensive Validation Pipeline
The bot detection validator runs independently (without a WebSocket connection) since it tests the HTTP/HTTPS endpoint rather than the WebSocket itself. Error handling wraps the test at wshawk/defensive_validation.py L507-L512
catching exceptions and logging errors without halting the entire validation suite.
Sources: wshawk/defensive_validation.py L506-L512
wshawk/defensive_validation.py L478-L557
Playwright Dependency Handling
Import and Error Handling
The validator gracefully handles missing Playwright installations using try-except import blocks at wshawk/defensive_validation.py L218-L221
and wshawk/defensive_validation.py L270-L273
:
When Playwright is unavailable, the test returns a result dictionary with skipped=True, preventing false vulnerabilities from being reported. The conditional execution logic at wshawk/defensive_validation.py L343-L346
checks for this flag before proceeding to the evasion test.
Sources: wshawk/defensive_validation.py L218-L221
wshawk/defensive_validation.py L270-L273
wshawk/defensive_validation.py L343-L346
Usage Patterns
Command-Line Invocation
The bot detection test executes automatically when running wshawk-defensive:
The CLI command invokes run_defensive_validation() which orchestrates all defensive tests including bot detection.
Sources: README.md L147-L150
docs/DEFENSIVE_VALIDATION.md L140-L147
Programmatic API Usage
For isolated bot detection testing:
This pattern is documented at docs/DEFENSIVE_VALIDATION.md L176-L179
Sources: docs/DEFENSIVE_VALIDATION.md L176-L179
docs/DEFENSIVE_VALIDATION.md L149-L190
Output Example
Console Output Format
When the bot detection test runs, it produces structured console output showing test progress and findings:
[*] Validating Bot Detection Effectiveness...
======================================================================
DEFENSIVE VALIDATION SUMMARY
======================================================================
Findings:
CRITICAL: 0
HIGH: 1
MEDIUM: 1
[MEDIUM] Basic Headless Detection
Description: Anti-bot system failed to detect basic headless browser.
Recommendation: Implement or improve bot detection. Consider: navigator.webdriver checks, User-Agent validation, behavioral analysis, commercial bot detection.
CVSS: 5.3
[HIGH] Evasion Resistance Test
Description: Anti-bot system failed to detect headless browser with evasion.
Recommendation: URGENT: Upgrade bot detection. Consider behavioral analysis, canvas/WebGL fingerprinting, TLS fingerprinting, or commercial services.
CVSS: 7.8
The output format is generated by run_defensive_validation() at wshawk/defensive_validation.py L534-L556
which aggregates findings from all validators and prints them with severity-based formatting.
Sources: docs/DEFENSIVE_VALIDATION.md L230-L234
wshawk/defensive_validation.py L534-L556
Technical Limitations
Current Implementation Constraints
| Limitation | Description | Impact |
| --- | --- | --- |
| Playwright Required | Tests cannot run without Playwright installed | Returns skipped=True when unavailable |
| HTTP/HTTPS Only | Tests browser endpoint, not WebSocket directly | Cannot validate WebSocket-specific bot detection |
| Pattern Matching | Uses simple substring matching for detection | May miss non-English or custom block pages |
| Static Indicators | Fixed list of 6 detection indicators | May not detect newer bot detection services |
| No JavaScript Execution | Only checks initial page load | Doesn't test dynamic bot challenges |
The blocked indicators list at wshawk/defensive_validation.py L232-L235
is static and hardcoded. Extending this list requires modifying the source code.
Sources: docs/DEFENSIVE_VALIDATION.md L428-L431
wshawk/defensive_validation.py L232-L235
Attack Scenarios Validated
The bot detection test validates defenses against three common attack patterns:
1. Credential Stuffing Attacks
Automated login attempts using stolen credentials. The test validates whether the target can detect and block automation tools commonly used for credential stuffing.
2. Automated Scraping
Web scraping bots that extract data from applications. The test confirms that headless browsers used for scraping are properly identified.
3. Account Takeover Attempts
Automated account compromise attempts. The test verifies that bot detection mechanisms prevent automated account manipulation.
These attack scenarios are documented at docs/DEFENSIVE_VALIDATION.md L44-L47
as the defensive goals that the bot detection test helps validate.
Sources: docs/DEFENSIVE_VALIDATION.md L44-L47