So you're storing database passwords and cryptographic secrets in a file within the web root, possibly because low-end web hosting has no other storage for these secrets. Entering this file's name as the path in an HTTP
GET request will retrieve its contents. Even if you provide "no web based file explorer", a malicious user may still end up correctly guessing the name of this secret key file unless its name is cryptographically random. Or someone who knows the file's name may leak the name to a malicious party.
.htaccess file in Apache HTTP Server, or analogous files in other web servers, is designed to prevent direct access to a file through the web even if a client knows its name. This is helpful in two situations:
- Say you store secrets in a JSON file that your PHP script loads with
file_get_contents() when it starts. The
.htaccess would block a user who keys in the URL of this JSON file.
- Say you store secrets in a PHP script containing assignments to global variables, which your PHP script includes with
require_once when it starts. For example, MediaWiki's
LocalSettings.php uses this approach. Normally, a variable-setting script would fail to produce any output. But I've seen occasional situations where mod_php or the CGI handler accidentally fails to load, which causes Apache to instead serve PHP files as plain text, including your secrets. The
.htaccess would block a user who keys in the URL of this PHP file.
But be careful:
.htaccess does not prevent access through a script, such as if a script takes a filename as an argument and returns the contents of that file. So make sure all scripts that read files with variable names, such as image-serving scripts, sanitize their paths by canonicalizing them (
realpath() and friends) and then limiting them to a specific directory.