Skip to main content
DVWA provides four distinct security levels that control how vulnerable each module is to exploitation. These levels allow you to practice attacks with increasing difficulty.

The Four Security Levels

DVWA implements a progressive difficulty system:

Low

Completely vulnerable with minimal or no protections

Medium

Basic security measures that can still be bypassed

High

Strong protections requiring advanced exploitation

Impossible

Properly secured code following best practices

Low Security

The Low security level is intentionally vulnerable with little to no security measures. Characteristics:
  • No input validation or sanitization
  • Direct pass-through of user input
  • No protection mechanisms
  • Easiest to exploit
Purpose:
  • Learn basic exploitation techniques
  • Understand fundamental vulnerabilities
  • Practice using security tools
  • Build foundational skills
Example - XSS Vulnerability:
// Low level - No filtering at all
$name = $_GET['name'];
echo "<p>Hello {$name}</p>";
```bash

### Medium Security

The **Medium** security level implements basic protections that can be circumvented.

**Characteristics:**
- Simple input filtering (blacklists)
- Basic sanitization functions
- Easily bypassed protections
- Client-side validation only

**Purpose:**
- Learn bypass techniques
- Understand weak security implementations
- Practice filter evasion
- Identify flawed protection logic

**Example - XSS Vulnerability:**
```php
// Medium level - Simple filtering
$name = str_replace('<script>', '', $_GET['name']);
echo "<p>Hello {$name}</p>";

High Security

The High security level implements stronger protections requiring advanced skills. Characteristics:
  • More sophisticated filtering
  • Server-side validation
  • Whitelist-based approaches
  • Multiple layers of defense
Purpose:
  • Advanced exploitation techniques
  • Real-world security challenges
  • Complex bypass scenarios
  • Understanding defense in depth
Example - XSS Vulnerability:
// High level - Whitelist approach
$allowed = ['en', 'es', 'fr'];
if (in_array($_GET['lang'], $allowed)) {
    $lang = $_GET['lang'];
} else {
    $lang = 'en';
}
echo "<p>Language: {$lang}</p>";
```sql

### Impossible Security

The **Impossible** security level demonstrates properly secured code.

**Characteristics:**
- Properly implemented security controls
- Parameterized queries (for SQL)
- Output encoding
- CSRF tokens
- Secure session handling
- Following security best practices

**Purpose:**
- Learn secure coding practices
- Understand proper implementations
- Compare vulnerable vs. secure code
- Study defense mechanisms

**Example - SQL Injection:**
```php
// Impossible level - Prepared statements
$stmt = $db->prepare('SELECT * FROM users WHERE id = ?');
$stmt->bind_param('i', $_GET['id']);
$stmt->execute();
The Impossible level is not actually impossible to attack - it’s called “impossible” because it implements security correctly, making traditional attacks ineffective.

How Security Levels Work

Each vulnerability module loads different source code based on the current security level.

Code Structure

From the source code (dvwa/includes/dvwaPage.inc.php:20-21):
// Valid security levels
$security_levels = array('low', 'medium', 'high', 'impossible');
```text

Each module has separate implementation files:

vulnerabilities/sqli/ ├── source/ │ ├── low.php # Low security implementation │ ├── medium.php # Medium security implementation │ ├── high.php # High security implementation │ └── impossible.php # Secure implementation └── index.php # Loads appropriate file

### Level Selection Logic

Example from SQL Injection module:

```php
switch( dvwaSecurityLevelGet() ) {
    case 'low':
        $vulnerabilityFile = 'low.php';
        break;
    case 'medium':
        $vulnerabilityFile = 'medium.php';
        break;
    case 'high':
        $vulnerabilityFile = 'high.php';
        break;
    default:
        $vulnerabilityFile = 'impossible.php';
        break;
}

Changing Security Level

You can change the security level at any time while using DVWA.

Via Web Interface

  1. Log in to DVWA
  2. Look for “DVWA Security” in the left menu
  3. Select your desired level from the dropdown
  4. Click “Submit”
The security level is stored in a cookie and persists across sessions.

Security Level Storage

From dvwa/includes/dvwaPage.inc.php:22-28:
if (!isset($_COOKIE['security']) || !in_array($_COOKIE['security'], $security_levels)) {
    // Set security cookie to impossible if no cookie exists
    if (in_array($_DVWA['default_security_level'], $security_levels)) {
        dvwaSecurityLevelSet($_DVWA['default_security_level']);
    } else {
        dvwaSecurityLevelSet('impossible');
    }
}
```bash

The current level is stored in the `security` cookie.

## Default Security Level

You can configure the initial security level in `config/config.inc.php`.

### Configuration Setting

```php
$_DVWA['default_security_level'] = 'impossible';
Valid values:
  • 'low'
  • 'medium'
  • 'high'
  • 'impossible'

Environment Variable

For Docker deployments:
environment:
  - DEFAULT_SECURITY_LEVEL=low
```bash

### Default Behavior

From `config/config.inc.php.dist:30-33`:

```php
# Default security level
#   Default value for the security level with each session.
#   The default is 'impossible'. You may wish to set this to either 'low', 'medium', 'high' or impossible'.
$_DVWA['default_security_level'] = getenv('DEFAULT_SECURITY_LEVEL') ?: 'impossible';
Default is impossible - This encourages reviewing secure code first, then working backward through vulnerable implementations.

Security Level Features

Different security levels also affect session security and cookie settings.

Session Protection

From dvwa/includes/dvwaPage.inc.php:45-57:
function dvwa_start_session() {
    $security_level = dvwaSecurityLevelGet();
    if ($security_level == 'impossible') {
        $httponly = true;
        $samesite = "Strict";
    } else {
        $httponly = false;
        $samesite = "";
    }
    // ... session configuration
}
```sql

| Level | HttpOnly Cookie | SameSite Cookie | Session Regeneration |
|-------|----------------|-----------------|----------------------|
| Low | ❌ No | ❌ No | ❌ No |
| Medium | ❌ No | ❌ No | ❌ No |
| High | ❌ No | ❌ No | ❌ No |
| Impossible | ✅ Yes | ✅ Strict | ✅ Yes |

<Info>
  Lower security levels intentionally leave the application vulnerable to session attacks like session fixation and XSS-based cookie theft.
</Info>

## Recommended Learning Path

For the best learning experience, follow this progression:

<Steps>
  <Step title="Start with Low">
    Begin at **Low** security to understand the basic vulnerability and learn fundamental exploitation.
  </Step>
  
  <Step title="Progress to Medium">
    Move to **Medium** security and practice bypass techniques against basic protections.
  </Step>
  
  <Step title="Challenge yourself at High">
    Attempt **High** security to develop advanced skills and creative exploitation methods.
  </Step>
  
  <Step title="Study Impossible">
    Review the **Impossible** level source code to understand proper security implementation.
  </Step>
</Steps>

## Viewing Source Code

You can view the source code for each security level.

### Via Web Interface

1. Navigate to any vulnerability module
2. Click **"View Source"** in the bottom right
3. Select the security level to view its implementation
4. Compare different levels side-by-side

### Via File System

All source files are located in:

vulnerabilities/[module_name]/source/ ├── low.php ├── medium.php ├── high.php └── impossible.php

Example modules:
- `sqli` - SQL Injection
- `xss_r` - Reflected XSS
- `xss_s` - Stored XSS
- `csrf` - Cross-Site Request Forgery
- `upload` - File Upload

<Tip>
  Comparing the source code across security levels is one of the best ways to learn both exploitation and defense techniques.
</Tip>

## Disabling Authentication for Testing

For automated tool testing, you can set a fixed security level and disable authentication.

### Configuration

Edit `config/config.inc.php`:

```php
$_DVWA['disable_authentication'] = true;
$_DVWA['default_security_level'] = 'low';
This allows:
  • No login required
  • Direct access to all modules
  • Fixed security level
  • Better tool compatibility
Only use this in completely isolated environments. Never expose DVWA with disabled authentication to any network.

Next Steps

Start Testing

Begin exploring DVWA vulnerabilities

Docker Setup

Run DVWA in Docker containers

Build docs developers (and LLMs) love