Most PHP sites keep their shared code - database access, configuration, helper
functions - in a library folder such as lib. Your own pages need to read
these files with include or require, but a visitor should never
be able to list the folder or open a file in it directly.
Opening a .php file directly runs it out of context, which can produce
errors that reveal paths or other details. Files with any other extension, such as
.inc, .ini or .txt, are worse: Apache sends them
as plain text, source and passwords included.
The good news is that include and require read straight
from the file system, not through the web server. Anything that blocks web access to
the folder leaves your own scripts working.
If a folder has no index.php or index.html, Apache may show
a list of every file in it. Stop this by creating a .htaccess file inside the
library folder containing:
Options -Indexes
Browsing to the folder now returns 403 Forbidden instead of a file list. This hides the file names, but a visitor who knows or guesses a name can still open that file, so on its own it is not enough.
Add one more line to the same .htaccess file:
Options -Indexes
Require all denied
Apache now refuses every web request for anything in the folder, whatever the file name or extension, with 403 Forbidden. Your pages can still include the files, because that never goes through Apache. This works the same on Linux and on XAMPP for Windows.
Note: Require all denied is Apache 2.4 syntax. Apache only honours
these lines in .htaccess if the server's AllowOverride setting
permits them - Options needs AllowOverride Options and
Require needs AllowOverride AuthConfig
(AllowOverride All covers both). If a line is not permitted, Apache returns
500 Internal Server Error for the folder, so test after adding it.
On a Linux server you can also restrict the folder itself, for example to
drwxr-x--- (chmod 750), so that only the owner and group can
read it.
This only helps when PHP runs as a different user from the one Apache serves files as
- for example PHP-FPM or suPHP running as the site owner. With mod_php, PHP
runs inside Apache as the same user, so if Apache cannot read the files, neither can your
scripts. Unix permissions do not apply on Windows, so this step does not apply to XAMPP
for Windows. Steps 1 and 2 work in every case.
If your host lets you place files above the web root, put the library there. A file that is not under the web root has no URL at all, so there is nothing to block:
your-site/
lib/ (not reachable from the web)
public_html/ (web root)
index.php
Include the files with a path relative to the current script:
require_once __DIR__.'/../lib/database.php';
Where that is not possible - many shared hosts only give you the web root - Step 2 is the reliable alternative.
https://yoursite.com/lib/ - you should get
403 Forbidden, not a file list.https://yoursite.com/lib/database.php - you
should also get 403 Forbidden.
Please donate if helpful