Where to put the database sensitive information [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to secure database passwords in PHP?
Recently I was given a website project which was supposed to be done in PHP but I don't have much experience in PHP. Anyway, it is up and running but there is a big room to improve. The one thing that I am not feeling well is the way I am dealing with database: I put the database connection information in a separate db.php file and include it where needed. But I remember seeing PHP source files returned by the server many a time.
So now my question is: what is a better or the best way / place to put database sensitive data?
By the way, how NOT to let PHP show error messages on web pages when things are gone wrong? A custom error page or settings somewhere in php.ini? Thanks!
Note: I am using PHP in it's old flavor not object-oriented way. But I am open to object-oriented or MVC way if there are better approaches that way to prepare for future projects

I don't know if this is what you are looking for:
You can put your sensitive data in your db.php, but outside the web root directory (public_html or www).
For example, you could have a directory called config which is a sibling of your web root directory, and store your db.php file there.
You can include your db.php file like this:
require_once('../config/db.php');
I hope this helps.

Its fine to put it in a db.php file, just use require_once() just after the opening <?php tag of each document.
If basedir restriction is not in effect, move db.php file outside of your web/ftp root that way its definitely not accessible via http/ftp. Make sure permissions are set properly on this file though.
Since you aren't using OOP or an MVC structure for your code this is the best route to go.

I would personally create a file called db.php and place this above the public_html folder on your server
for example
<?php
error_reporting(0);
$link = FALSE;
$link = mysql_connect('hostname', 'username', 'password');
if ( ! $link)
{
die("Couldn't connect to mysql server!");
} else {
mysql_select_db('databasename');
}
?>
This turns off error reporting at the same time as connecting to your database, from your index.php you would include the file like so:
<?php require('../db.php'); ?>

Related

Is this a good enough way to "hide" the db credentials?

Just looking for some tips if this is good enough or if i should do anything different to "hide" my database credentials. Been searching for a long time. I have found alot of ways to do this and feel everyone does it a different way. So wondering if this is good enough. Thank you.
Right now I'm storing a config.ini file with my database credentials outside of the public directory.
Then inside the public directory I got a folder name db_includes. This is where i have my db connection php file. This is the code for the database connection.
$config = parse_ini_file('../../private/config.ini');
$db = new \PDO('mysql:dbname='.$config['DB_NAME'].';host='.$config['DB_SERVER'].';charset=utf8mb4', ''.$config['DB_USERNAME'].'', ''.$config['DB_PWD'].'');
Also inside the db_includes folder i got a .htaccess file that has "deny from all" so its not possible to get to that db_includes folder or the database connection file.
Is this good or should i also move the database connection file outside of the public directory and just call it when i need it?
There's a few ways of doing it. First, I recommend using a PHP file to store the credentials, this way if your htaccess fails, the php file will be parsed anyway and your credentials won't appear:
config.php:
<?php
return [
"DB_NAME" => "database",
"DB_USER" => "user"
// ...
];
Wherever you need:
$config = require "path/to/config.php";
$db = new \PDO('mysql:dbname='.$config['DB_NAME'].';host='.$config['DB_SERVER'].';charset=utf8mb4', ''.$config['DB_USERNAME'].'', ''.$config['DB_PWD'].'');
If possible, keep it outside your public folder as it is a good way to make it safe.
Remember that if your database and server is well configured and safe enough you don't need to worry about database credentials.

How to properly store global variables for php server code

I am writing php scripts for a server code. These include sign up, log in, and similiar functions. These functions often reference the same database and URLs. I have been reading on stackoverflow and google that the user of a global PHP file and using a simple include is a bad idea. Seen below:
global.php
<?php
$databaseHost = "someurl.com";
$databaseUser = "adminUser";
$databasePassword = "adminUsersPassword";
$databaseName = "dbName";
?>
serverFile.php
<?php
include 'global.php';
//mysql functions that use the variables below
$databaseHost;
$databaseUser;
$databasePassword;
$databaseName;
?>
Can someone explain to me the safest way to do such includes or is it better that I just write all the information directly into every server php file? This seems like it will be hard to keep updated if we change / update our database or change our server host.
If you could also explain why you recommend what you recommend that would be greatly appreciated. I have a very good understanding of other programming languages and hardware (I'm a computer engineer), so in depth explanations are welcome.
Sorry for not having an exact problem, but I am very lost on how to best approach this. Thanks in advance for the stackoverflow knowledge.
This is fine. The only thing you should do is put the file outside of your web root (public_html). That way it can't be accessed directly, but instead can only be accessed from code.

How to pass database connection instance between PHP files without redeclaring it

I have created a database connection instance in PHP like:
$mysqli = mysqli_connect("localhost", "root", "blabla", "blabla");
I need to pass this database connection to other PHP files, since I have an HTML form that first inserts data into a database and then it goes to a PHP page that retrieves data.
I know that I must not instantiate the database connection each time but I do not know how to do it, because I am not so familiar with OO PHP.
You can just name a file connection.php and store your line for connection to database.
Then you can include your file like this :
require_once('connection.php');
This will be the content of connection.php :
$mysqli = mysqli_connect("localhost", "root", "blabla", "blabla");
And then this way, your file will never load twice.
If I understand you correctly, I think you misunderstand what you've read.
In PHP how most systems (phpBB, WordPress, etc) do it is there is a base include file that is included at the start of each PHP page. In phpBB it is called "Common.php" if I remember correctly.
Common.php goes through and does a few things:
It reads the database configuration files and connects via the most acceptable database connection type (mysql_connect, or mysqli_connect, depending, or another connection if you aren't using MySQL).
It then unsets the database password variable (so that someone, on an off chance, couldn't figure it out via SQL Injection)
includes other files necessary for the system to function - certain user-made functions or class definitions.
This is done via one of 4 functions:
include('common.php') will include the contents of the file at the point it is written in the file. E.G.
<?php
do_function();
include('common.php');
do_other_function();
?>
Will run do_function(), then run any script in the common.php file, which could theoretically hold the definition for do_other_function(), and then run do_other_function();
include_once('common.php') makes sure that a file is run through the process only once. This is good for things like class definitions as it ensures a class is not accidentally re-defined. E.G.
<?php
include_once('database_class.php');
//Code here code here
...
//Oh crap, did I include that database class? I can't remember. I think so...maybe not
include_once('database_class.php');
?>
Will only include the database class def one time. Where as the same example above with include('database_class.php'); instead of include_once would throw an error akin to the class 'database' is already defined
Note, include and include_once will only throw warnings if a file does not exist, and if you have error reporting set to only show fatal errors, you won't notice when something isn't included except for perhaps a "constant/function/class 'something' not defined" and you'll scratch your head for perhaps a long time. So if you try to include the file 'cmmon.php' when you meant 'common.php', you may or may not see an error.
then there is the require and require_once functions, they do effectively the same thing as include and include_once, but unlike the latter two the script will stop running if it cannot include the file and throw an error, like "could not include file 'something.php' on line # [line] in file [file path]"
Use require for scripts that are absolutely necessary - function/class/constants that your scripts will need in order run properly.
Use include for things that are voluntary, the first thought that came to mind would be plugins - things that don't necessarily have to be there in order for your system to work as intended.
If $mysqli is global, then all php files can see it by peeking the $GLOBALS array, assuming the php is included.
For example:
$mysqli = mysqli_connect(..); // in global space
another php file:
$GLOBALS["mysqli"]; // use that
inside a php function you could also do:
global $mysqli; // use that

How to know if php script is called via require_once()? [duplicate]

This question already has answers here:
Check if a file was included or loaded
(12 answers)
Closed 2 years ago.
My webapp has a buch of modules. Each module has a 'main' php script which loads submodules based on a query sent to the main module:
//file: clientes.php
//check for valid user...
//import CSS and JS...
switch( $_GET["action"] )
{
case "lista" : require_once("clientes.lista.php"); break;
case "listaDeudores" : require_once("clientes.listaDeudores.php"); break;
case "nuevo" : require_once("clientes.nuevo.php"); break;
case "detalles" : require_once("clientes.detalles.php"); break;
case "editar" : require_once("clientes.editar.php"); break;
default : echo "<h1>Error</h1><p>El sitio ha encontrado un error.</p>";
}
This main module deals with security and imports many resources all submodules need. The big problem shows up when a user asks for any of the submodules, bypassing all the security measures on the main module! My idea was to add a line on every submodule to test if it was being called directly and deny access or if its been called via another script, and continue. The least thing I would like to do is redo the security checking on every single file, since it does a bunch of query's to the database.
Does a php script know if its been called via a require_once() or a direct call ? I've been trying to implement some sort of $_SERVER['REQUEST_URI'] and $_SERVER['PHP_SELF'] pitfall but I was wondering if there was some sort of an elegant way of doing this.
I was looking for a way to determine if a file have been included or called directly, all from within the file. At some point in my quest I passed through this thread. Checking various other threads on this and other sites and pages from the PHP manual I got enlightened and came up with this piece of code:
if ( basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"]) ) {
echo "called directly";
}
else {
echo "included/required"
}
In essence it compares if the name of the current file (the one that could be included) is the same as the file that is beeing executed.
EXPLANATION:
__FILE__ is a PHP magic constant that stores the full path and filename of the file, the beauty of it is that if the file has been included or required it still returns the full path and filename of such file (the included file).
(Magic Constants Manual: http://php.net/manual/en/language.constants.predefined.php)
$_SERVER["SCRIPT_FILENAME"] returns the absolute pathname of the currently executing script. As when a file is included/required it's not executed (just included) it returns the path name of the (let's say) "parent" file (the one that includs the other file and the one that gets executed).
basename(string $path) is a function that returns the trailing name component of path, that in this case is the file name. You could also just compare the full path and filename, that would be indeed better, it isn't really neceseary to use this function but it feels cleaner this way, jajaj.
(basename(): http://php.net/manual/en/function.basename.php)
I know it's a "bit" late to be answering the main question but I guessed that it could be useful to anyone who's on the same situation that I was and that also passes by.
One elegant way is putting all your files which should only be accessed via include outside the web directory.
Say your web directory is /foo/www/, make an include directory /foo/includes and set this in your include_path:
$root = '/foo';
$webroot = $root.'/www'; // in case you need it on day
$lib = $root.'/includes';
// this add your library at the end of the current include_path
set_include_path(get_include_path() . PATH_SEPARATOR . $lib);
Then nobody will be able to access your libraries directly.
There's a lot of other things you could do (test a global variable is set, use only classes in libraries, etc) but this one is the most secure one. Every file which is not in your DocumentRoot cannot be accessed via an url,. But that does not mean PHP cannot get access to this file (check as well your open_basedir configuration if you have it not empty, to allow your include dir in it).
The only file you really need in your web directory is what we call the bootstrap (index.php), with a nice rewrite rule or a nice url managment you can limit all your requests on the application to this file, this will be a good starting point for security.
One popular method to make sure modules are not called directly is defining a constant in the main script, and checking for that constant in the module.
// index.php
define("LEGIT_REQUEST", true);
// in each module
if (!defined("LEGIT_REQUEST"))
die ("This module cannot be called directly.");
For the sake of completeness, the other possibility is to move such files to a directory that's not publicly available. However, some control panels used by hosting providers make this impossible. In such case, if you are using Apache you can place an .htaccess file inside the directory:
#
# Private directory
#
Order allow,deny
Deny from all
A common technique is to add this to the main module (before the includes)
define('TEST', true);
and to add something like that at the first line of every submodule
if (!defined('TEST')) {
die('Do not cheat.');
}
An alternative to defining a constant and checking it is to simply put the files that index.php includes outside of the document root area. That way the user can't directly access them via your web server at all. This is also obviously the most secure way, in case your web server has a configuration error in future that eg. displays PHP files as plain text.
You can define('SOMETHING', null) in clientes.php and then check if (!defined('SOMETHING')) die; in the modules.
global.php
if(!defined("in_myscript"))
{
die("Direct access forbidden.");
}
module.php
define("in_myscript", 1);
include("global.php");
A generic way that works without having to define a constant or use htaccess or use a specific directory structure or depend on the $_SERVER array that could theoretically be modified is to start each include-only (no direct access) file with this code:
<?php $inc = get_included_files(); if(basename(__FILE__) == basename($inc[0])) exit();
As practice of habit I have a console class built to send messages, errors, etc. to console with FirePHP. Inside the Console class write() method I have a check to see if a $_REQUEST[debug] == 1, that way I'm not exposing errors to users if something pops up on production and they would have to know what the request variable is to access the debug information.
At the top of every file I add:
Console::debug('fileName.php is loaded.');
here is a snippit from it to give you the right idea:
class Console{
public static function write($msg,$msg_type='info',$msg_label=''){
if(isset($_REQUEST['debug']) && $_REQUEST['debug'] == 'PANCAKE!'){
ob_start();
switch($msg_type){
case 'info':
FB::info($msg, $msg_label);
break;
case 'debug':
FB::info($msg, 'DEBUG')
break;
...
}
}
}
public static function debug($msg){
Console::write($msg, '');
}
}
Short and simple (for CLI):
if (__FILE__ == realpath($argv[0]))
main();

PHP variables maintaining an URL string

I'm not a PHP developer, but I'm currently hacking on an internal tool so my team can take advantage of its goodness. There's an index file that looks like so:
require( ($loader_path = "../../loaderapi/") . "loader.php" );
Used like this, $loader_path will retain its value within the loader.php file.
However, we want to access this API from our team's server like so:
require( ($loader_path = "http://remoteservername/loaderapi/") . "loader.php" );
In this case the $loader_path variable doesn't retain its value. I'm guessing it has something to do with it being a full blown URL, but I might be wrong. Any idea on how I can make this work, or why I can't do it this way?
If your accessing a PHP script over HTTP, only the output of that script is returned. So your script will try to interpret the output of that remote PHP script and not its source.
If there is a connection over the file system, you may want to try file://remoteservername/loaderapi/loader.php instead.
NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO!
Remote file inclusion is a BAD idea, probably one of the biggest security flaws you can open up. Even for an internal tool this is not acceptable even if only purely for contributing bad habits.
PHP by default disables this behavior, and there is a broad push to have the ability to perform an include on a URL completely stripped from PHP (as there is no compelling reason to have this ability).
If you want to load shared resources, go through a shared file system drive (as in, don't use http, ftp, anything but file://) or better yet distribute copies of loader.php through a version control system. Loading from a single file resource opens you up to problems in the future of say a new dev overwriting loader.php and breaking everyone else's code.
There shouldn't be any real difference between the two; what you're doing is defining $loader_path, concatenating the loader.php, and passing that to require.
HOWEVER: you're defining the variable within the scope of a require, which will halt processing of the script of require fails.
Try replacing 'require' with 'include' and see if it retains the variable.
Also, note that if you are running your PHP server on a windows machine, and the php version is less than 4.3.0, neither 'require' nor 'include' can handle remote files : http://us.php.net/manual/en/function.include.php
Also, as noted before, if the .php lives on a remote server that parses php, you will not get code, but the result of the remote server processing the code. You'll either have to serve it up as a .txt file, or write php that, when processed, outputs valid php.
Have you tried splitting it into two lines:
$loader_path = "http://remoteservername/loaderapi/";
require( $loader_path . "loader.php" );
It's easier to read this way as well.
Simplify the code reading by simply putting everything on 3 lines:
$loader_path = "http://remoteservername/loaderapi/";
$page = "loader.php";
require($loader_path . $page );
Much clearer and it works.
why not just put it above the require statement? would make it easier to read too.
<?php
$loader_path = "../../folderName/"
require($loader_path . "filename")
?>

Categories