Overview
DVWA offers four distinct security levels that control the difficulty and realism of each vulnerability. You can change the security level at any time via the DVWA Security page in the main menu.
The current security level applies to all vulnerability modules simultaneously. This allows you to explore how the same vulnerability behaves with different security controls.
Changing Security Levels
To set your security level:
- Click DVWA Security in the navigation menu
- Select your desired level: Low, Medium, High, or Impossible
- Click Submit
- The change takes effect immediately for all modules
The default security level is set to Impossible in the configuration file. You’ll likely want to change this to Low when starting your learning journey.
The Four Security Levels
Low Level
Purpose: Completely vulnerable with no security measures
Characteristics:
- No input validation or sanitization
- No protection mechanisms whatsoever
- Raw user input directly processed
- Easiest to exploit
When to Use:
- Learning basic exploitation techniques
- Understanding how vulnerabilities manifest
- Teaching fundamental security concepts
- First-time exposure to a vulnerability type
- Demonstrating bad coding practices
Example (SQL Injection):
The query uses raw input directly controlled by the attacker:
$query = "SELECT * FROM users WHERE user_id = '$id';";
```sql
### Medium Level
**Purpose:** Bad security practices where developers tried but failed to secure the application
**Characteristics:**
- Weak or incomplete protection mechanisms
- Bypassable filters and validation
- Client-side security controls
- Insufficient sanitization
- Delays and rate limiting (in some modules)
**When to Use:**
- Refining exploitation techniques
- Learning to bypass weak defenses
- Understanding why certain protections fail
- Practicing filter evasion
- Realistic simulation of poorly secured applications
**Example (SQL Injection):**
Uses `mysql_real_escape_string()` but fails to use quotes around parameters:
```php
$id = mysqli_real_escape_string($connection, $_POST['id']);
$query = "SELECT * FROM users WHERE user_id = $id;";
Example (Brute Force):
Adds a 2-second sleep delay on failed login attempts, slowing but not preventing attacks.
High Level
Purpose: Harder and alternative bad practices with more sophisticated defenses
Characteristics:
- More complex security controls
- Additional layers of protection
- Anti-CSRF tokens (that don’t prevent all attacks)
- Session-based input handling
- Random delays and unpredictability
- May limit exploitation scope
When to Use:
- Advanced exploitation scenarios
- Learning sophisticated bypass techniques
- Understanding why certain controls aren’t sufficient
- CTF-style challenges
- Testing against more realistic defenses
Example (Brute Force):
- Implements anti-CSRF tokens
- Random delays between 2-4 seconds on failed logins
- Attempts to confuse timing predictions
Example (SQL Injection):
Input transferred via session variables instead of direct GET/POST requests.
Impossible Level
Purpose: Secure implementation that should be immune to the vulnerability
Characteristics:
- Proper input validation and sanitization
- Parameterized queries for SQL
- Output encoding for XSS
- Strong authentication controls
- Rate limiting and account lockouts
- Comprehensive security controls
When to Use:
- Learning secure coding practices
- Comparing vulnerable code to secure code
- Understanding proper defensive techniques
- Code review and training
- Establishing security baselines
Example (SQL Injection):
Uses parameterized queries that separate code from data:
$stmt = $pdo->prepare('SELECT * FROM users WHERE user_id = :id');
$stmt->execute(['id' => $id]);
```bash
**Example (Brute Force):**
- Account lockout after 5 failed attempts within 15 minutes
- Locked users cannot log in even with correct passwords
- Prevents user enumeration
- May cause denial of service (intentional limitation)
## Security Level Comparison Table
| Aspect | Low | Medium | High | Impossible |
|--------|-----|--------|------|------------|
| **Difficulty** | Trivial | Easy-Moderate | Moderate-Hard | Secure |
| **Input Validation** | None | Weak/Bypassable | Incomplete | Comprehensive |
| **Output Encoding** | None | Partial | Partial | Complete |
| **CSRF Protection** | None | None/Weak | Token-based | Strong tokens + validation |
| **Rate Limiting** | None | Simple delays | Random delays | Lockouts |
| **Realism** | Poor practices | Bad practices | Flawed practices | Best practices |
| **Learning Focus** | Attack basics | Bypass techniques | Advanced exploits | Defensive coding |
## Progression Strategy
For optimal learning, follow this progression:
### 1. Start with Low
- Understand the vulnerability concept
- Practice basic exploitation
- Get comfortable with tools
- Learn the attack vectors
### 2. Move to Medium
- Identify the added protections
- Learn bypass techniques
- Understand why weak controls fail
- Develop more sophisticated exploits
### 3. Challenge with High
- Analyze complex security controls
- Research advanced techniques
- Think creatively about bypasses
- Chain multiple vulnerabilities if needed
### 4. Study Impossible
- Review the secure source code
- Compare with vulnerable versions
- Understand proper security controls
- Learn defensive programming patterns
- Recognize what makes code secure
<Tip>
Don't rush through the levels. Spend time at each difficulty to truly understand both the attack and the (attempted) defense mechanisms.
</Tip>
## Security Level Variations by Module
While all modules follow the same level structure, the specific protections vary:
### SQL Injection
- **Low:** No sanitization
- **Medium:** Escaping without quotes
- **High:** Session-based input
- **Impossible:** Prepared statements
### XSS (Reflected)
- **Low:** No filtering
- **Medium:** Case-sensitive `<script>` filtering
- **High:** Pattern-based script removal
- **Impossible:** HTML entity encoding
### CSRF
- **Low:** No protection
- **Medium:** Referer header checking
- **High:** Anti-CSRF tokens
- **Impossible:** Token + current password required
### Brute Force
- **Low:** Unlimited attempts
- **Medium:** 2-second delays
- **High:** Anti-CSRF + random delays (2-4s)
- **Impossible:** Account lockout system
## Configuration
The default security level is set in `config/config.inc.php`:
```php
$_DVWA['default_security_level'] = 'impossible';
You can change this to start at a different level by default, or use environment variables:
DEFAULT_SECURITY_LEVEL=low
```bash
## Tips for Each Level
### Working with Low
- Focus on understanding the vulnerability
- Don't overthink - exploits are straightforward
- Use basic payloads from help pages
- Learn what makes code vulnerable
### Working with Medium
- View source to identify protections
- Research common bypass techniques
- Test edge cases and encoding variations
- Think about client vs. server validation
### Working with High
- Expect to chain vulnerabilities
- Use advanced tools and techniques
- Read the source code carefully
- Consider timing attacks and race conditions
### Working with Impossible
- Study the code, not for exploits but for defenses
- Compare side-by-side with vulnerable levels
- Identify the key security controls
- Learn the patterns for your own code
<Warning>
Even at Impossible level, DVWA may have undocumented vulnerabilities. The app is designed to teach, not to be production-ready. Never use DVWA patterns in real applications without additional research and validation.
</Warning>
## Next Steps
- Review [User Accounts](/usage/user-accounts) to understand available test accounts
- Start with [Getting Started](/usage/getting-started) if you haven't set up DVWA yet
- Choose a vulnerability module and work through all four levels
- Document your findings and compare exploitation techniques across levels