PHP files without an ABSPATH guard can be accessed directly via URL, leaking paths, triggering errors, or executing partial logic without WordPress security context. [CWE-425 · A05:2021]
prevents information disclosure and unguarded code execution from direct file requests
BeforeMerge scans your pull requests against this rule and 4+ others. Get actionable feedback before code ships.
Impact: HIGH (prevents information disclosure and unguarded code execution from direct file requests)
Every PHP file in a WordPress plugin or theme is directly accessible via URL unless protected. When accessed directly (e.g., https://example.com/wp-content/plugins/my-plugin/includes/process.php), the file executes without the WordPress bootstrap — no security checks, no authentication, no API functions loaded. This can:
Incorrect (no access guard):
<?php
// wp-content/plugins/my-plugin/includes/helpers.php
// ❌ No guard — directly accessible via URL
function process_data( $input ) {
global $wpdb;
// Fatal error: $wpdb is null when accessed directly
// Error message leaks server path and WordPress install location
return $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}posts" );
}<?php
// ❌ File with initialization logic that runs on include
// Direct access triggers this without WordPress context
$config = include __DIR__ . '/config.php'; // May expose sensitive values
$db = new PDO( $config['dsn'] ); // Direct DB connection without WP safeguardsCorrect (ABSPATH guard at the top of every file):
<?php
// ✅ First executable line in every plugin/theme PHP file
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
function process_data( $input ) {
global $wpdb;
return $wpdb->get_var(
$wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}posts WHERE post_status = %s", 'publish' )
);
}<?php
// ✅ Alternative: check WPINC (defined in wp-settings.php)
defined( 'WPINC' ) || die;
// ✅ One-liner variant
defined( 'ABSPATH' ) || exit;Where the guard is required:
.php file in your plugin directory.php file in your theme directoryPlugin Name: header) — WordPress loads this directly, so it should define its own constant or check ABSPATH earlyDetection hints:
# Find PHP files missing ABSPATH guard
grep -rL "defined.*ABSPATH\|defined.*WPINC" wp-content/plugins/my-plugin/ --include="*.php" | grep -v "vendor\|node_modules"Reference: WordPress Plugin Security · CWE-425: Direct Request