PHP & MySQL connection more secure - php

I have a small page that contains the connection data to my MySQL DB, which I include in other pages that require it. The small code is:
[connect_DB.php]
----------------
<?php
define("HOST", "localhost");
define("USER", "myUser");
define("PASSWORD", "myPasword");
define("DATABASE", "members");
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
?>
A friend of mine proved to me that he can download the .PHP file, and in less than 2 min, he did. That means he got the login info for my MySQL server. And I was wondering if there existed another way of connecting with the database, without putting the password in a file, etc. He recommended me use SSL or TSL, or simply configuring the HTTPD.CONF or .HTACCES to not allow "exterior" access to the file. Is that correct or achievable?
I am actually testing this on Wamp Server (Win7), and I cannot create a .HTACCESS file because It tells me to enter a name for the file (which I am already introducing! :( ) every time I try to name it that way.
I understand that this may be a duplicate question, but believe me I read a lot of t hem but I don't understand what should I do. In advance, thank you.

I am pretty sure that your host Provider is not parsing the PHP files, because it would not be possible to download the sources if they'd pass the interpreter.
Make sure you have PHP installed, configured and activated, contact your provider's support in case of questions. The easiest way to test this is to upload a file:
test.php
<?php phpinfo(); ?>
To protect a file it's enough to put the your database config php outside of public_html, html or htdocs directory (one of these is most likely to be your document root), where you still can include(); it via PHP.
Other solution is to protect the file via .htaccess where you put something like that inside the file and upload it to your document_root:
<Files db_config.php>
deny from all
</Files>
To add a little more security,
you can protect the db_config.php by adding this on top:
if (!defined('IN_MY_PROJECT')) {
die('forbidden');
}
and put this on top of your index.php:
define('IN_MY_PROJECT', true);

Most likely, Your server is not setup correctly, meaning the PHP engine is not running, so its just sending or displaying the file contents back as say text/html and not being parsed by PHP. This is the only way that some tool like you mentioned in comment could possibly access the file, a tool like that would also not see the file if there was not a link to it somewhere, so perhaps you have Directory Indexes enabled to.
To test you have PHP enabled simply make a file and put in it:
<?php phpinfo(); ?> if it displays your php info then im stumped, if not then its proof your server is misconfigured for PHP.
Though once fixed, it is good practice to put sensitive files outside of your web root. And not a good idea to set your values in constants as a function like get_defined_constants() will give access to the sensitive values. Just put them directly in the construct arguments.
if you want to block access to a directory where only PHP can access you make a .htaccess file with deny from all in it, this will cause the server to send a 403 Forbidden.

Related

Database settings security

I've got a file on my site called dbSettings.php with the lines:
<?php
$host = "localhost";
$dbName = "database";
$user = "user";
$pwd = "pass";
$db = new mysqli($host, $user, $pwd, $dbName);
?>
I get this page into my main page with the require_once() function. Is there ANY way for someone who's reaching this page through the server(my domain) to get a hold of the values stored in these variables? Is this a secure way to keep the database settings?
This is a common way to keep database credentials in php applications. Generally a config file would keep those settings some good practices are
Proper file permissions to the file such as
chmod the file 640 instead of 600. Keep file ownership to your user and change group to webserver. This way, the webserver can only read and not modify it
Move file out of webroot so its not accessible directly by others
Only give needed database privileges to that database user
If user just needs to access one database only give privileges for that database and data not give Structure or Administration related privileges if not needed
If possible protect with
.htaccess
<files dbSettings.php>
order allow,deny
deny from all
</files>
If your webserver is configured properly, web clients should not be able to view the settings. When a .php file is accessed through the webserver, it executes the script, and returns what it prints to the client. The source code of the script is not sent to the client.
You can make things more secure by putting files like this outside your webroot. Then clients can't even address them, they can only be accessed by being required from another script.
From what I know of PHP security, there are a couple ways for this information to leak:
If dbSettings.php can be somehow loaded by a client, without the server processing the page. This would obviously give out the details, since they can just look at the file. Generally speaking, if you server is correctly configured, and and you have no backup files created, this shouldn't be an issue.
If dbSettings.php is loaded by the client, you want to make sure no errors could leak the information (so for instance the mysqli creation can't fail and leak the information). Since your app isn't initialized, it is possible for errors you regularly mask to appear.
As for securely storing the information, I don't believe there is a much better solution then to do as Barmar suggests, and put the configuration files somewhere the web server doesn't actually serve files. PHP can still generally access these files, but the web server won't give them out to clients. Depending upon your hosts, this may or may not be possible.
Make sure that your dbSettings.php is not accessible through URL, so php must be able to read this file, but this file should not be accessble by typing it's address in the browser (by guessing, luck, etc). But if you have properly configured www server you should be fine because php will be processed and blank page will be returned to user.
Only if you misconfigure your web server so it will not process php pages but return them to the user - the file will accessible by others to download. So again your settings must not be accessible from outside.
Besides that You should never have echo, dump, etc those values from your php code on production server and you should also catch any errors from mysql driver so they will not be printed out to the user on production server.
The most important security measure, as outlined by previous answers, is proper webserver configuration.
As you are creating a configuration file that should never be directly accessed, you can safely place it outside the server root, or in a directory for which the server is configured to not serve files. As long as the file has proper permissions, you can include() it without the webserver's help.
If for what ever reason you choose to stick with having the configuration file in an accessible location, you can use a define() trick to prevent unauthorised execution. This is done by defining a constant in the file to include the config file, prior to the actual include(), then checking for the existence of the constant in the config file itself.
example.php:
<?php
define ('my_const', 1);
include ('config.php');
echo $super_secret_data;
?>
config.php:
<?php
if (!defined ('my_const'))
die ();
$super_secret_data = 42;
?>
Of course, the only security benefit here is that executable code will not run without the constant if the page is accessed directly, and that its data will not be accessible by files that do not define the const (which is pretty bad security through obscurity, as you can probably still call getfilecontents() on the file).

Where do I hide my login info when using PHP connect to get to a database?

I need to connect to a mysql database using PHP. I am storing my login, user, password, and other info in a separate php file (let's say "mysql_connect.php") and then accessing it via require_once (mysql_connect.php) in a different file.
I have done a bit of googling and I know that I am supposed to keep "mysql_connect.php" out of the web root. I have moved it outside of the html folder and tried calling to it by using "../../mysql_connect.php" This is not working, it gives me an error "function not found" or something like that. Upon googling that, the internet says that its because it can't locate the file i'm referencing. When I move mysql_connect.php into a folder below root, everything works fine. The issue is because it is moved outside of the web root (i think).
I have been googling for two days now and cannot find a detailed explanation on how to get this to work. Something about changing the .htaccess file? I've read a bunch of articles on the theory but I am really looking for a step-by-step tutorial (I am a beginner). The only step-by-step tutorials I can find just tell you to put the config.php file into the same folder which is not secure.
Also in reading, it says that putting mysql_connect.php above root might not be THE most secure way to store the information as it is still basically just a .txt file and it can be retrieved easily(like downloading it). I am looking for a balance between secure and also do-able (for a beginner like myself). The mysql database I am trying to protect will not have any personal information and I plan on using a dedicated server (with no other information on it).
Can any one help me to solve this issue?
it gives me an error "function not found" or something like that.
This.
Is your main problem.
You either didn't bother to read this error message yourself nor didn't bring it here to help us to help you.
While
there is no problem in having this file below document_root,
and there is no problem in having this file above document root either,
the only problem you have is to assign a correct filename.
And the error message you got could help you more than 1000 volunteers from this site.
Despite of that, you can use PHP predefined variable to make this path work from whatever part of your site. Aassuming the file is one level above the document root, the code would be
require($_SERVER['DOCUMENT_ROOT']."/../mysql_connect.php");
however, this one may produce an error too, as nobody knows a real file locations. Thus, you may read the error message and corect the paths. Or post it here and get an interpretation
You can store the database information inside your web server configuration.
If you run Apache you can use SetEnv inside the VirtualHost. Since you're still on a shared host, your server admin probably need to help you with this. You can read more about this approach here.
... tried calling to it by using "../../mysql_connect.php" This is not working, it gives me an error "function not found" or something like that.
Include the connection details with:
require_once("../../mysql_connect.php");
This assumes that the file mysql_connect.php is two levels up from the currently executing script.
The database connection details will always be able to be read by whomever has administrative access to the server. It is not feasible to encrypt the file, because you would still need to store whatever key or password needed to decrypt it on the server as well, which would still not hide it from the server administrators.
Besides moving out of the web-root (which is a good step forward) an approach I've seen used is:
// at the top of your index or bootstrap file
define('SECURED', true);
And:
// at the top of any file subsequently included, such as mysql_connect.php
if(!defined('SECURED'))
{
exit();
}
This will at least prevent the file(s) from being accessed (executed) directly. This is helpful is the to-be-included files would otherwise issue a warning or error, that could potentially dump sensitive data as output.
If you're in a shared hosting environment you won't be allowed access outside of document root (most likely). You will need the password therefore it won't be completely secure. Instead, you can look into creating seperate mysql users with priviledges and limiting connections to to local accesses only.
i know i'm new, but something as simple as form for your login should be checked in order for it to work.
<form action="insertphpfilepath.php" method="POST">
and then in "insertphpfilepath.php", would have the mysql_query to check the login and password, not forgetting the mysql_query for connecting to the database and table using the right username and password .
a newbie recommendation to you for use mysql_real_escape_string for any $_POST['login'] so that it would become $login=mysql_real_escape_string($_POST['login']); for evading mysql injection.

Is there any way to view PHP code (the actual code not the compiled result) from a client machine?

This may be a really stupid question...I started worrying last night that there might be someway to view PHP files on a server via a browser or someother means on a client machine.
My worry is, I have an include file that contains the database username and password. If there were a way to put the address of this file in to a browser or some other system and see the code itself then it would be an issue for obvious reasons.
Is this a legitimate concern?
If so how do people go about preventing this?
Not if your server is configured right. I think discussion on how that is done belongs on serverfault.
To add on to the other answers:
If you use a file extension like .inc there's indeed a higher risk. Can you open the file directly in your browser?
The most important advice is missing:
Only the files that should be accessed by a browser, should be in a publicly accessible location. All the other code (and configuration) should be in a completely separate directory.
For example
root
- webroot
- includes
- config
Only 'webroot' is exposed by your webserver (apache). Webroot can for example contain a single index.php, along with all your assets (javascript, css, images).
Any code index.php needs to load comes from 'includes' and all the configuration from 'config'. There's no way a user could ever directly access anything from those 2 directories, provided this is done correctly.
This depends on the file extension you have given the include file.
If the extension is one that is known and executed by the web server, it will be protected. If you browse to the file, the server will try to execute the code rather than just returning it as plain text.
If the extension is not known by the web server it will serve it as plain data, so anyone (who can guess the file name) can browse to the file and see the source code.
A Directory Traversal Vulnerability can used to obtain files off of the remote mahine. Alternatively you can use MySQL based sql injection to read files using load_file(). You can also test your system with w3af's urlfuzzer which will look for "backup files", such as index.php.zip. Also make sure that all files have .php extensions, a .inc can be viewed from the public. I would also disable Apache directory listing.
Normally there should be no way to view the PHP files remotely... it would be absolutely pointless. This completely depends on what web server you are using and how it's setup though.
Having looked around I can see that it is possible to protect a directory via the .htaccess by adding these lines:
Order allow,deny
Deny from all
This apparently protects the directory so that only local non web-access is possible.
This allows me to keep my includes in a subdirectory of the main site directory which is good for organisation and it can be used on the projects where I do not have access to folders outside the web root.
Does anyone else use this method?
Just for good measure I've put the directory permissions to execute only.
And the include extension is PHP as suggested by others.

How to make sure no scripts except those under my own domain, can include the db connection file?

I would like to ensure that any scripts that are trying to "include" my database connection file are located under my own domain. I don't want a hacker to include the database connection file to their malicious script and gain access to my database that way. My connection file's name is pretty easy to guess, it's called "connect.php". So without renaming it and taking the security through obscurity route, how can I protect it by making sure all connection requests are made by scripts residing under my own domain name? How can this be checked using PHP?
Generally speaking if someone tries to include a file on your domain, they will see the results of the execution of that file. What do you see when you load the connect.php script in your web browser? Thats what they'll see as well if they try to include a remote file.
That said, its generally a good idea to keep important files inaccessible from the outside of your public web space. So, if your website is /var/www/yoursite/ then keep your connect.php in /some/dev/dir/yoursite and include the files from your pages using require_once '/some/dev/dir/yoursite/connect.php';
thetaiko's answer addresses the fundamental issues here - but if anyone else has access to run code on the server (i.e. its a shared server) then access to the file will depend on how the server is configured.
There are lots of ways that access might be constrained - e.g. suphp, base_opendir, multiple chrooted servers. The only way to find out what's going on for sure is to casr yourself in the role of the hacker and see if you can access files outside your designated area.
C.
What do you mean by including your connection file? If a script does include "connect.php" then they can see the source code of the file, so whatever security measures you add to that file will be pointless, as it will be like:
if($notFromHostname)
{
echo "DONT LOOK AT THIS";
die();
}
define('DB_PASS',"myPassword");
...
And the "hacker" will clearly be able to see your password. You are probably better off using something like iptables to deny hosts that are not from a specific domain.
Are you on a shared server and don't want other users of the same server instance to be able to get at your files? That'd be up to your server provider, then, to provide some sort of chroot or virtual system to keep your things in. For Apache, mod_suid can accomplish this nicely, and each vhost gets its own userid and permissions set.
If you want external users to not be able to get at your files, then unless you've badly munged your code, or the server's badly misconfigured, then all they'll get when they visit http://yourserver.com/connect.php is a blank page
No other user than yourself should have access to your PHP files in any way, as Felix mentioned. However, this is how you'd check in PHP:
if($_SERVER['SERVER_NAME'] != "example.com")
die("I've been kidnapped!");

Where do you store your PHP script configurations like DB access data?

I have an config.php file where I simply make an huge array that contains all the framework configuration. Also the database source string thing like "mysql:host=localhost;dbname=mydb" (whats that called, btw?) and username + password for DB. I'm afraid this is:
stupid
not good; better solution there
not secure (?)
so how do the PHP experts do that?
If you have a www, httpdocs or public_http folder or something like that, where your php application is situated, then it is good practice to put the config file outside of that folder, and just access it like this:
include "../config.php";
Nobody can gain access to that file without FTP access, and so it's relatively safe compared to having it in the application folder.
If you don't have such a folder, you can create one, and make a .htaccess file in the root, which redirects all requests to that folder. There are many different ways to do that, but that's a different question all together.
I store it in a plain text ini style configuration file, usually above the web root so as not to allow users access to it. In the cases where it is accessible, I usually have a .htaccess file with deny from all so as to prevent all access to it.
Storing it in a PHP file accessible to users should be fine, but it isn't ideal. If the sever handles PHP files correctly, even if people can access the file, they can't access the values as they just get the output (nothing). There are of course issues with this, (see comments).
Using PHP files is the most common method with PHP projects (Both FOSS and commercial) I have used. Most of them didn't both storing them above the web root. With any stable setup, there is on the face of it very little point in storing your configuration file above the web root, although given Murphy's law it is worth doing if you can (That or use .htaccess or the equilivent for your server to deny user access to a directory)
That's how most do it, but you could also try some of these solutions:
Save the configuration file outside the web folder (this requires that the open_basedir configuration in PHP is disabled).
Restrict access to the configuration file by using .htaccess:
<Location /config.php>
Order deny,allow
Deny from all
</Location>
Use .ini files and the parse_ini_file function (this is not really a solution in itself, but could be combined with the others)
Why storing DB username & password in "config.php" is not fine? as long as i know, the data in this file can't be shown publicly.
E.G.
<?php
$DB_User = "amindzx";
$DB_Pass = "Something";
// connect to DB and so on.
?>
unless if the hacker can gain access to your FTP.
Why it's stupid to hold simple config.php file without any securities? Even if programmer finds this file he can do nothing, because, like amindzx said "this file can't be shown publicly." Or I'm wrong?
With sensitive info like database or payment gateway credentials, and when I have control over the server, I like to add lines like the following to my apache virtual host config:
SetEnv DB_USER "myuser"
SetEnv DB_PASS "mypass"
In your PHP, you can access these using $_SERVER['DB_USER']. You can make this config file readable only by root, which you can never do to a file that php accesses at run time. One caveat: Be sure you disable php_info and don't expose these variables with something silly like print_r($_SERVER). (Much of this is paraphrased or stolen from here.)
For non-sensitive configuration, I like to do a class full of constants, which is similar to your setup, but I like the OOP-ness of it.
class Application
{
const CONTACT_EMAIL = "me#mysite.com";
}
usage:
$contactEmail = Application::CONTACT_EMAIL;
I usually store settings in a config.php too, such as database connection settings, file paths etc.

Categories