I was taught that an important step to securing a website (primarily with PHP) was to store all sensitive information such as database connection info, salt generation, etc. in a separate file(s)/Folder(s) and use .htaccess with something like deny from all to prevent access to that information, and otherwise unauthorized access to the site/database.

My question is, to what extent is this helpful? In my web environments those files cannot be accessed/downloaded (that I know of). There is no web based file explorer to access that information, and so long as the information isn't printed to the screen, why does access to those files need to be restricted beyond that?


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.

The .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.

  • So it is still good practice to restrict access to them with .htaccess. What would be some suggestions (or a link to more discussion) on ways to store this information for database connections on a web host?
    – sharf
    Nov 18 '14 at 3:31
  • 1
    a malicious user may still end up correctly guessing the name of this secret key file Heh, web logs are full of these guesses against security by obscurity and it must work quite well otherwise they wouldn't be so persistent. If it's blocked by .htaccess deny then it explicitly isn't available for guessing. Nov 18 '14 at 4:56
  • If we're talking about a PHP file that makes a connection with a database (the passwords are there, but in PHP strings, and won't be outputted), and Apache is set up to process all PHP files before sending them to the client, what exactly would be a possible attack against which .htaccess would secure?
    – user21287
    Nov 18 '14 at 16:24
  • @CamilStaps I explained attacks in an edit. Nov 18 '14 at 16:41
  • @CamilStaps - it's pretty simple. Detect a foul hole in some Wordpress addon that allows you to create a .php file in a directory, then call it. The PHP interpreter merrily does your dirty work and your target's compromised. Now if your target had put an .htaccess file in place denying direct access to the file, he wouldn't be spending time doing one of those "Oh, &^#%" site reloads. Also, the PHP interpreter doesn't process .xml or other files where configuration data may be stored so once again... I'll let you peruse some web logs to discover all the attempts... Nov 22 '14 at 21:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.