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

:

  1. navigator.webdriver Override: Sets the navigator.webdriver property to false, masking the automation driver
  2. Plugins Spoofing: Populates navigator.plugins with dummy entries to simulate a real browser
  3. Languages Array: Sets navigator.languages to 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:

  1. navigator.webdriver checks: Detect the automation flag
  2. User-Agent validation: Verify header consistency
  3. Behavioral analysis: Track mouse/keyboard patterns
  4. 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

wshawk/defensive_validation.py L199-L210