The WP Debug Toolkit (WPDT) standalone viewer is protected by multiple security layers. Password authentication is mandatory, and additional protections — rate limiting, session controls, CSRF tokens, and path traversal blocking — operate automatically.
Password protection has been mandatory since WPDT 1.1.0. There is no way to run the viewer without a password.
auth.php in the viewer directory, not stored in the WordPress database. This keeps authentication functional when the database is unreachable.Update the viewer password from Debug Toolkit > Settings > Viewer Settings. Enter a new password and save. The new hash replaces the existing one in auth.php. Active sessions are invalidated — you need to log in again with the new password.
wp dbtk viewer setup --password=new-secure-password
This reinstalls the viewer with the new password while preserving existing configuration and settings.
The viewer uses progressive lockout to defend against brute-force login attempts. Rate limiting is enforced per IP address.
| Failed attempts | Lockout duration |
|---|---|
| 1 | 0 seconds |
| 2 | 5 seconds |
| 3 | 30 seconds |
| 4 | 5 minutes |
| 5 | 30 minutes |
| 6 | 1 hour |
| 10+ | 24 hours |
Each consecutive failed attempt increases the lockout duration. After a successful login, the counter resets for that IP.
Rate limiting uses SQLite by default. The database file is stored outside the viewer web root when possible (in wp-content/debug-toolkit-cache/). When the PDO SQLite extension is unavailable on the server, WPDT falls back to a file-based rate limiter that uses JSON files.
After successful authentication, the viewer creates a session with the following properties:
Session timeout — Sessions expire after 30 minutes of inactivity. After expiration, you are redirected to the login screen.
IP binding — By default, sessions are tied to the client’s IP address. If a request comes from a different IP than the one that authenticated, the session is invalidated. This prevents session hijacking by blocking the use of stolen session tokens from other networks.
Disabling IP binding — In some environments, the client IP changes legitimately during a session (certain proxy configurations, mobile networks, VPN failovers). Disable IP binding from the viewer’s Settings panel if you experience unexpected logouts. Navigate to Settings in the viewer (K key) and toggle Disable IP binding.
Warning: Disabling IP binding reduces session security. Only disable it if you experience repeated session invalidation from IP changes.
All state-changing API actions (modifying settings, toggling debug constants, disabling plugins) require a valid CSRF token. The token is generated when the session starts and included in every mutating request from the React app. Requests without a valid token are rejected with a 403 response.
The viewer API validates all file path parameters to prevent directory traversal attacks. Requests that attempt to access files outside the allowed directories are blocked.
The API maintains a blocklist of sensitive files that are never served regardless of the request path:
wp-config.php.htaccess.htpasswd.envid_rsaid_dsa.sshconfig.php (viewer configuration)auth.php (viewer password hash)rate-limiter.db.git directories.sqlite filessecure-debug.php (GridPane debug configuration)Requests for blocked files return a 403 error with no file content.
The viewer API sets security headers on every response:
X-Content-Type-Options: nosniff — prevents MIME type sniffingX-Frame-Options: DENY — blocks embedding in iframesX-XSS-Protection: 1; mode=block — enables browser XSS filteringReferrer-Policy: strict-origin-when-cross-origin — limits referrer informationContent-Security-Policy — restricts script and resource loading to same-originCache-Control: no-cache, no-store, must-revalidate — prevents caching of API responsesThe API accepts only a defined set of actions. Any request with an unrecognized action is rejected with a 400 response. Action names are sanitized to allow only lowercase alphanumeric characters, hyphens, and underscores.
httponly, secure (on HTTPS), and samesite=Strict flagsLog content displayed in the viewer is filtered to redact sensitive values (database credentials, authentication salts, API keys) before rendering.