# How to Prevent Direct Access to Files and Directories in WordPress WordPress powers a huge share of the web, which also makes it a frequent target. One often-overlooked vulnerability is **direct file access** — when someone types a URL directly into a browser to reach a PHP file, configuration file, or directory that was never meant to be publicly visible. Preventing this is a foundational part of WordPress hardening, and understanding how it works helps you make smarter decisions about your own setup. ## What "Direct Access" Actually Means When WordPress loads a page, requests are routed through `index.php` and processed by WordPress's core. **Direct access** bypasses that routing entirely. Instead of WordPress handling the request, the web server responds directly — potentially exposing logic, error messages, or sensitive data. For example, if a plugin file like `/wp-content/plugins/some-plugin/installer.php` is publicly accessible, a visitor (or attacker) can load it in a browser and trigger whatever code it contains — outside of WordPress's authentication and permission checks. The same risk applies to: - **Configuration files** like `wp-config.php` - **Log files** or backup files left in the web root - **Plugin and theme PHP files** not designed to be called directly - **Directory listings**, which can expose folder contents when no index file exists ## The Core Defense: `define('ABSPATH')` Checks Many well-coded plugins and themes already include a line near the top of each PHP file: ```php if ( ! defined( 'ABSPATH' ) ) { exit; } ``` This works because `ABSPATH` is a constant WordPress defines at bootstrap. If a file is accessed directly (bypassing WordPress), `ABSPATH` won't be defined, and the script exits immediately. This is a **developer-level protection** baked into the file itself — but it only works if the developer included it, and not all do. ## Using `.htaccess` to Block Direct Access 🔒 For Apache-based servers, the `.htaccess` file gives you server-level control. This is more reliable than code-level checks because the web server enforces the rule before PHP even runs. **Block direct access to `wp-config.php`:** ```apache order allow,deny deny from all ``` **Block access to all PHP files inside a specific directory** (e.g., a plugin folder): ```apache deny from all ``` Placed inside `/wp-content/uploads/`, this prevents anyone from executing PHP files that may have been uploaded through a vulnerability — a common attack vector. **Disable directory browsing** (prevents listing folder contents when no index file exists): ```apache Options -Indexes ``` This single line, added to your main `.htaccess`, closes off directory listing site-wide. ## Nginx Configurations for Direct Access Prevention If your server runs **Nginx** rather than Apache, `.htaccess` has no effect. Equivalent protections go inside your server block configuration: ```nginx location ~* /wp-config.php { deny all; } location ~* /(wp-content|wp-includes)/.*.php$ { deny all; } ``` The second rule blocks PHP execution inside `wp-content` and `wp-includes`, which are directories that should deliver assets — not run scripts directly. Nginx changes require server-level access, which means shared hosting users may need to work through their host's control panel or support team. ## Variables That Determine Your Approach No single method works the same way for every WordPress site. Several factors shape which combination of protections makes sense: | Factor | How It Affects Your Approach | |---|---| | **Server type** | Apache vs. Nginx changes which configuration files you edit | | **Hosting environment** | Shared hosting limits server-level access; VPS/dedicated gives full control | | **Technical skill level** | Manual config edits vs. security plugins | | **Plugin/theme quality** | Determines whether `ABSPATH` checks are already present | | **Site complexity** | More plugins = more potential entry points to audit | ## Security Plugins as an Accessible Layer For site owners who aren't comfortable editing server configuration files manually, **security plugins** offer a GUI-based approach to many of these protections. Most established security plugins can: - Enforce file permission rules - Block direct PHP access in key directories - Disable directory browsing - Protect `wp-config.php` and `.htaccess` from modification The tradeoff is that plugin-based protections add a layer of abstraction — and a plugin itself is another piece of software that needs to be maintained and updated. ## What File Permissions Have to Do With It 🛡️ Beyond access rules, **file permissions** at the operating system level determine who can read, write, or execute files on the server. WordPress has general recommended permissions: - Files: `644` - Directories: `755` - `wp-config.php`: `600` or `640` Incorrect permissions — especially anything world-writable like `777` — can negate other protections entirely. Permissions are set at the server level and are separate from `.htaccess` or Nginx rules. ## The Spectrum of Risk Exposure A simple brochure site with few plugins, on a managed WordPress host that handles server hardening for you, faces meaningfully different risks than a complex WooCommerce store on a self-managed VPS with dozens of third-party plugins installed over several years. For the managed site, many of these protections may already be applied at the infrastructure level. For the self-managed environment, each layer — server configuration, file permissions, code-level checks, and security plugins — typically needs to be addressed deliberately. The specific combination that makes sense depends heavily on what you're running, where it's hosted, who manages the server, and how much of the configuration is already handled for you versus left to you to define.