SQL connect.php security risk? - php

I'm just writing a PHP file to connect to my SQL server for a website login system and I'm terrified I'm just going to leave massive security holes.
I have my connect.php file in a directory of the websites root directory with this in it:
$db = new mysqli('localhost', 'publicguest', '**********', 'website');
where the password is open to see. I know when someone is looking at the website they cannot see the PHP code through the source but is this insecure and what is the common way to avoid this?

If your server has configuration issues, specifically php scripts aren't executed then someone may be able to get that info.
To avoid that you can put the file above the document root directory.

Unless they have direct access to the files you're working with, it should be fine.
Most commonly, people will store passwords and settings in a configuration file above root level which they then parse and use in those statements. It will then be up to the attacker to reach that file.
If you really want to be obscure about it, you could encrypt those settings as well.

Unless an attacker has FTP/direct access to the files, this is not a security risk as the PHP file is processed before outputting it to the client.
If the attacker has FTP/direct access, the mysql auth info is the least of the problems!
Wordpress stores the mysql login info in clear text in the wp-config.php, joomla does the same, there is no other way to do it i think.

For a good practice you shouldn't use your password in the source code of your application, but rather store it in a db_config.php file outside your web root, making sure your config file is not publicly accessible.
This should get you deeper into the argument:
http://www.mediawiki.org/wiki/Manual:Securing_database_passwords

For the most part its safe, unless:
For some reason your web server spits out your code in plaintext, this can happen in rare cases with server misconfiguration.
You can store your connection data outside of the web root to stop general access, but in the event a hacker has been allowed to execute PHP on your server for any reason, its game over anyways.

The only thing I would change about that line of code is getting the username and password out of that particular line, eg:
$host = 'localhost';
$user = 'publicguest';
$pass = 'hunter2';
$database = 'website';
$db = new mysqli($host, $user, $pass, $database);
The reason for this is if, at some point, your code encounters and error and spits out a stack trace it will not accidentally spit out your connection information as well.
If you really wants to be paranoid you can call:
unset($user);
unset($pass);
After the connection goes through, but that really only protects you from code injection, and so long as you never ever use eval() you should be fine. [seriously, never. >:I]
Anything further that people in this thread are suggesting is just paranoid faffing about because once someone has file-level access to your code they have the keys to your kingdom anyways and it's game over. But take heart! 99 times of 100 no one cares about your code or your database, they just want to inject their own code to send spam and/or DOS other people. :P

Related

mysqli connection db user and password settings

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

Is it secure to use include() to connect to server and database?

Is it secure to use a PHP file with connection parameters, and include that file to the page?
example:
include("connect.php");
connect.php:
$con=mysqli_connect('localhost','root','','database')
or
die(mysqli_connect_error($con)."- In line: ".__LINE__);
mysqli_set_charset($con,'utf8');
Yes, because the include is happening server-side. You should look up some information about server-side programming and client-side programming!
Also MySQL functions are officially deprecated and MySQLi or PDO should be used instead!!!
Yes, this is fine though it might be better if you used require() so that if for whatever reason including the connect info fails, the code execution stops. include() will continue to execute the script even if the command did not succeed, which can cause error information and/or information only required if a connection is successful to be exposed (not generally recommended).
For even more security, you can move the connection info file out of the public web root (e.g. if web root is /home/data/files then moving it to /home/data then including /home/data/connect.php or ../connect.php - if your web host allows this). This will mean it cannot be accessed via HTTP.

Hacking by sending PHP variable from another host

Is it possible to hack website by sending PHP variable from another host? For instance:
I have a file secure_content.php:
<?php
if($fgmembersite->Login()) //placed at the top to avoid the warning: headers already sent
{
$login = TRUE;
}
//intentionally removed {else $login === FALSE}
// echo some contents
if ($login === TRUE)
{
//echo secure data
}
else
{
echo "You are not authorised to view this content";
}
?>
And an attacker have a file in his webserver named: hack.php
<?php
$login = TRUE;
require_once "http://mywebsite.com/secure_content.php";
?>
Is it possible the hacker to view the secure content?
How to avoid processing our scripts using include/require from other webserver?
No, it isn't possible to process your scripts from another webserver.
Your server will not give the entire PHP source code to the remote server, rather it will give the output of running your script.
No worries here.
You cannot avoid processing your scripts using include from other webserver, because that is not possible in the first place. So there is nothing to prevent.
As Denis said, though I want to add few interesting caveouts from personal experience administrating sites.
People often rename their php scripts into something like secure_content.php.back while editting the file - fear it. As then, the attacker can download your PHP script accessing (secure_content.php.back). Having source-code is not enough to hijack variables, but is already a vulnerability. It will get amplified, if your secure_content.php.back has some configuration variables like $database_password
Also, if you are to uninstall PHP from your web-server, Apache (or whatever) will serve your secure_content.php as a text file - is also a risk. Just keep in mind when you are to tinker with your PHP engine.
No. Your server will run the script and then send the results to the evil server.
A similar thing to what you mention can occur in older versions of PHP if register_globals is on. This would allow someone to call http://mywebsite.com/secure_content.php?login=true.
This would cause $login to be set to true at the start of the script. Thankfully register_globals is now off by default and is deprecated in 5.3 and removed in 5.4. See here.

find public html folder using php's ftp functions

I have a php script that logs into my servers via the ftp function, and backs up the entire thing easily and quickly, but I can't seem to find a way to let the script determine the folder where the main index file is located.
For example, I have 6 servers with a slew of ftp accounts all set up differently. Some log into the FTP root that has httpdocs/httpsdocs/public_html/error_docs/sub_domains and folders like that, and some log in directly to the httpdocs where the index file is. I only want to backup the main working web files and not all the other stuff that may be in there
I've set up a way to define the working directory, but that means I have to have different scripts for each server or backup I want to do.
Is it possible to have the php script find or work out the main web directory?
One option would be to set up a database that has either the directory to use or nothing if the ftp logs in directly to that directory, but I'm going for automation here.
If it's not possible I'll go with the database option though.
You cannot figure out through FTP alone what the root directory configured in apache is - unless you fetch httpd.conf and parse it, which I'm fairly sure you don't want to do. Presumably you are looping to do this backup from multiple servers with the same script?
If so, just define everything in an array, and loop it with a foreach and all the relevant data will be available in each iteration.
So I would do something like this:
// This will hold all our configuration
$serverData = array();
// First server
$serverData['server1']['ftp_address'] = 'ftp://11.22.33.44/';
$serverData['server1']['ftp_username'] = 'admin';
$serverData['server1']['ftp_password'] = 'password';
$serverData['server1']['root_dir'] = 'myuser/public_html';
// Second server
$serverData['server2']['ftp_address'] = 'ftp://11.22.22.11/';
$serverData['server2']['ftp_username'] = 'root';
$serverData['server2']['ftp_password'] = 'hackmeplease';
$serverData['server2']['root_dir'] = 'myuser/public_html';
// ...and so on
// Of course, you could also query a database to populate the $serverData array
foreach ($serverData as $server) {
// Process each server - all the data is available in $server['ftp_address'], $server['root_dir'] etc etc
}
No, you can't do it reliably without knowledge of how Apache is setup for each of those domains. You'd be better off with the database/config file route. One-time setup cost for that plus a teensy bit of maintenance as sites are added/modded/removed.
You'll probably spend days getting a detector script going, and it'll fail the next time some unknown configuration comes up. Attemping to create an AI is hard... you have to get it to the Artificial Stupidity level first (e.g. the MS Paperclip).

Connect to MySQL with hashed password?

I was wondering (and used Google with no clear result) if there is any way to connect to a MySQL database with PHP using a hashed password. Say I have the following:
Password (plain): 'foobar'
Password (sha1): '8843d7f92416211de9ebb963ff4ce28125932878'
Now I would like to connect to MySQL like this (using the mysql_* function as example, I'm using PDO though):
$db_link = mysql_connect ( 'localhost', 'user', '8843d7f92416211de9ebb963ff4ce28125932878' );
I this possible? Have anyone done this before?
Then the "hash" would be the password. What would be the benefit?
The short answer is no.
But, just wondering... what is your real concern? Someone hacking into your server and discovering your password?
the usage case would be having multiple developers editing the .php file that contains the sql connect password that you might not want them to know.
I think one solution would be to move the connect statement out to a file like so, make sure you don't have a $password variable though cause someone could just call it and print it out later in their .php file
mysql.php
<?php
mysql_connect('db.cs.dal.ca','user','password');
#mysql_select_db($database) or die( "Database Error ".mysql_error());
?>
and only give your self rw------- permissions to the mysql.php file, then in all of your group accessible .php files you can just include that file to evoke a connection.
index.php
<?php include("mysql.php") ?>
<!-- some web content -->
<?php mysql_close(); ?>
and give your developers group rw-rw---- permissions on all the other .php files, as long as the owner of the mysql.php file can read it should executed on the php server..... i think.
you can also exclude mysql.php from git for example, and have developers run their own local copy of a DB with their own mysql.php file and just provide a stripped down copy of your production database for local development and testing
Simple answer is "You can't."
I know what you are trying to accomplish: You are probably on some shared hosting plan and cannot put your config file above the html folder.
Stefan is thinking that a hacker would just be hunting for the config file and wants to make him have to work for the info. Once the hacker realizes he needs more info, he has to crack the site a second time.
This has nothing to do with a table of usernames & passwords. This is for the MySQL config file.

Categories