2

i am trying to figure out if there is a way to make a password recovery system that actually hides the "connection.php" with all the mysqli db username and password. is this possible?

most of the tutorials i found have the "connection.php" file shown to make the connection to the database and it can be viewed from source which makes the the database login info visible. can someone help me with this or point me in the right direction to go about this please?

example:

 <?php
 $connection = mysqli_connect('localhost', 'root', 'Rvm@i[9)0?~=');
 if (!$connection){
die("Database Connection Failed" . mysqli_error($connection));
}
 $select_db = mysqli_select_db($connection, 'pixelw3p_demo');
 if (!$select_db){
die("Database Selection Failed" . mysqli_error($connection));
 }
  ?>

this is in the connection.php file which needs to be added as a

  require_once('connection.php');

now this php file can be seen in the source then you know which php file to look for to get the database info. any way all of this can be hidden so my db isn't vulnerable?

  • did you actually try to see the source? – Your Common Sense Nov 24 '17 at 20:58
  • Possible duplicate of [How to secure database passwords in PHP?](https://stackoverflow.com/questions/97984/how-to-secure-database-passwords-in-php) – Tom Udding Nov 24 '17 at 21:02
  • Note: The object-oriented interface to `mysqli` is significantly less verbose, making code easier to read and audit, and is not easily confused with the obsolete `mysql_query` interface. Before you get too invested in the procedural style it’s worth switching over. Example: `$db = new mysqli(…)` and `$db->prepare("…")` The procedural interface is an artifact from the PHP 4 era when `mysqli` API was introduced and should not be used in new code. – tadman Nov 24 '17 at 21:57
  • well i feel like an idiot... you can delete this if you wish. –  Nov 24 '17 at 22:18
  • 1
    There's nothing wrong with asking questions that might seem embarrassing so long as you're learning. Don't worry about it. Better to ask than to muddle along not knowing any better. – tadman Nov 27 '17 at 18:37

3 Answers3

5

To put it straight: there is absolutely nothing wrong in having credentials in a PHP file. What everyone is talking about is "NEVER store passwords, API keys, or other sensitive information" in a file included in the version control (e.g. git).

A PHP file by itself is no worse than ENV, INI, JSON, XML, YAML or whatever. Actually a PHP file is even slightly better, as it doesn't need to be put strictly above the document root. And also, using PHP for the configuration allows a better integration with your application.

Whereas what is really essential, is having all the application settings in a separate file with which is removed from the version control, so it will never make it into a repository or another server.

Given all the above, to make your configuration file separated from the source code:

  • add the config.php line in .gitignore (in case you are using git)

  • create a file called config.sample.php with all variables set to empty values like this

      return [
          'db' => [
              'host' => '127.0.0.1',
              'username' => '',
              'password' => '',
              'dbname' => '',
              'port' => 3306,
          ],
      ];
    
  • add it to the version control

  • in your application bootstrap file have a code like this

      if (!file_exists('config.php'))
      {
          throw new \Exception('Create config.php based on config.sample.php');
      }
      $config = require 'config.php';
    
      mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
      $mysqli = new mysqli(...$config['db']);
      $mysqli->set_charset('utf8mb4');
    
  • then, as suggested, create config.php on the every server your application runs, each with its own set of values

What you have to understand, this routine is obligatory for any file format, config.ini icluded. And it's this routine that makes your passwords secure and portable, not a file format you choose.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
1

To be blunt, most of the tutorials you've found are probably absolute garbage and everything they're telling you is wrong. Few of them actually address serious security concerns, and those that do usually either gloss over it, or fail to address the issues by promoting best practices.

It's not hard, but it can be tricky to do right. You need to keep in mind a bunch of things.

NEVER store passwords, API keys, or other sensitive information in your source code. Use configuration files, especially simple ones in INI, JSON or even XML format. PHP has functions for reading all of these quickly and easily.

NEVER store configuration files in a place that's within your public "web root", that is a place that could be accessed by someone tinkering with the URL to probe for files like these. Even if you have rules in your web server configuration to block these requests those rules might be disabled by accident, a problem that often manifests when you redeploy your application to a new server that isn't configured correctly.

NEVER check your production configuration files into version control. This is how you leak API keys and passwords to would be attackers. For instance, accidentally pushing an Amazon AWS key to a public GitHub repository is often swiftly punished by someone who will use that key to spin up hundreds of expensive instances. It doesn't matter if repositories are private: These can be cloned by people and made public without your knowledge.

ALWAYS do what you can to minimize the number of places where critical passwords, API keys and other credentials are stored. Use a secure storage system like 1Password as a "vault" where the contents are properly and thoroughly encrypted, not something like a Google Doc which could be compromised.

ALWAYS burn all passwords, API keys, and other credentials stored on a server in the event of a compromise. If you don't know how much access had or how long they've had access, re-issue new passwords, generate new API keys, and be absolutely certain the old credentials no longer work. Do not assume you have time to fix this. You might not. Immediately and permanently fix the problem when you realize you've got an issue.

The simplest answer here is to make a config.ini file with this information in it that's saved outside the web root and kept only on the server. Don't download it. Don't copy it. Don't touch it unless you need to. This helps avoid costly, painful mistakes.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • so i was looking into config.ini a bit but still havent found something on how i am going to be linking it or reading it if its outside the public folder and only saved on the server. do i place its location in the php.ini or even place the ini in the php folder say where the php.ini is located? if i remember correctly reading it is a parse_ini_file() in order to read said ini. just unsure about how to link it or where to place it for ease. thanks –  Nov 27 '17 at 18:07
  • You may want to look at how a package like [Laravel](http://laravel.com) organizes the application as these sorts of frameworks generally have a pretty good model to use. They also have documentation on how to properly configure your application's web root. Modifying `php.ini` should not be necessary, this is typically an Apache `httpd` or Nginx type concern with regard to virtual host configuration. – tadman Nov 27 '17 at 18:36
  • 1
    started using ini methods. works like a charm and i can finally take out the username and passwords to stuff around the source. thanks for pointing me in the right direction! –  Dec 13 '17 at 19:10
-1

A .htaccess file is usually impossible to display in browsers, but mind that depends on webserver settings. It's the default in Apache, and also in NGINX (where a .htaccess file has no functionality), but be very aware other webservers could have other defaults, and may display the contents of a .htaccess.

Contrary: a php.ini file is usually not configured to be rejected at HTTP requests! Also if PHP processing fails, you end up with credentials in plaintext.

Anyway, I consider the .htaccess method as reliable as using htpasswd for authentication or limiting access.

In Apache's .htaccess this works:

php_value mysqli.default_host     localhost
php_value mysqli.default_user     obelix
php_value mysqli.default_pw       zKSIOSwjsiyw9263djcaleP982WLdDU3kzn6
php_value mysqli.default_db       broccoli

Then in PHP it's as easy as:

$db = mysqli_connect();
$db->select_db('menhirdb');

It's anyway better than storing credentials in sourcecode.

If you think your webserver performance sucks because a .htaccess is read line by line at each HTTP query, than you better put it in httpd.conf That's anyway the way I would do it, but then like:

php_admin_value mysqli.default_host     localhost
php_admin_value mysqli.default_user     obelix
php_admin_value mysqli.default_pw       zKSIOSwjsiyw9263djcaleP982WLdDU3kzn6
php_admin_value mysqli.default_db       broccoli

The benefit of using 'php_admin_value' is automatically that .htaccess values can't overwrite them. Which is a great security benefit, I think. As I've witnessed more than once that vulnerable CMS systems wrote hostile .htaccess files.

Leo
  • 2,331
  • 2
  • 19
  • 17
  • ["You can’t do this. You shouldn’t. If you need .htaccess, you’re probably doing it wrong. Stop using .htaccess. It’s horrible for performance. NGINX is designed to be efficient. Adding something like this destroys that"](https://www.nginx.com/resources/wiki/start/topics/examples/likeapache-htaccess/) – Your Common Sense Jan 29 '21 at 05:59
  • You can do it - that's why the options exist, and are named like that. If your .htaccess or httpd.conf is readable you have a bigger problem than user-credentials. – Leo Jan 31 '21 at 15:49
  • [The nginx doesn't support .htaccess](https://stackoverflow.com/a/35767433/285587) – Your Common Sense Jan 31 '21 at 15:57
  • nginx.conf by default still limits access to filenames starting with .ht* – Leo Jan 31 '21 at 15:58
  • Maybe you should learn to read: the manual, the config examples and my comments. I never statet .htaccess has functionality in nginx - I stated nginx by default limits access to it. I'm not going to repeat this another 5 comments. – Leo Jan 31 '21 at 16:01
  • The question is not how to hide some useless file but **how to store db credentials**. Although Nginx could hide .htaccess but it **won't get** any "php_admin_value" from it. Which means .htaccess is useless with Nginx. And even in Apache mod_php has been declared deprecated long time ago which means it won't make any sense from "php_admin_value" either. – Your Common Sense Feb 18 '21 at 14:11