Forum Moderators: coopster

Message Too Old, No Replies

Password security when using PHP to access MySQL

         

craighaggart

9:40 pm on Jun 21, 2009 (gmt 0)

10+ Year Member



Gotta say up front that I'm very new to web programming; please forgive me if this is a stupid question.

I'm developing a site for a local nonprofit that will allow people to sign up for membership. It's written in XHTML + CSS, but I'm planning to use a PHP script to package up the form data and stuff it into a MySQL database.

I've read everything I can about PHP and MySQL, but nobody seems to address my specific question of how in the world the database username and password are protected. These are hard-coded into the PHP script, and the script is in the public directory of the web host. How are people kept from simply looking at the PHP code and seeing the MySQL username and password? If I put the PHP in a protected directory, the XHTML would still need to call it so anyone looking at the web page code could see how to get into that directory, right? I just don't get it.

Thanks in advance for any help.

Craig
Sunnyvale, CA

FourDegreez

11:57 pm on Jun 21, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



As long as your server is not misconfigured, raw PHP code will not be sent to the browser. It is executed on the server and the output is sent. Only a configuration error could result in the code being exposed.

It is good practice to keep such code out of the public directory, though. In that case, the code will not be exposed under any circumstance short of somebody hacking in.

craighaggart

1:35 am on Jun 22, 2009 (gmt 0)

10+ Year Member



Thanks for the very fast response! I'm still a bit in the dark, however. I understand that raw PHP is not supposed to be sent to the browser, but if someone knew where to look for it couldn't they just copy or download the PHP file?

> "It is good practice to keep such code out of the public directory, though."

That sounds good. But if I put the PHP file in a different (protected) directory, how can the HTML use it without anyone else being able to also see how to get to it?

Sorry if I'm not making sense. It's obvious to me that it must be a normal thing to do, since millions of web pages use PHP to access MySQL databases. It's just that I don't have a mental picture of how this can be secure, and it isn't mentioned in any of the PHP/MySQL books and tutorials I've read. It seemed jarring to me to see username and password info hard-coded into the PHP script.

Craig
Sunnyvale, CA

willybfriendly

3:00 am on Jun 22, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The fact that PHP code appears to be embedded in HTML is confusing at first.

PHP is actually putting together the HTML on the fly, and then serving it. So rather than coding:

echo "<li>".$someData."</li>";

It becomes possible to code:

<li><? echo $someData; ?></li>

Conceptually, it is probably more accurate to think of the HTML being embedded in the PHP code, even though it doesn't look that way at first glance.

As was previously stated, a properly configured server will never present raw PHP code.

Also, as previously stated, best practice would have you include() or require() sensitive portions of you code to a directory outside of the webspace on your server.

craighaggart

3:23 am on Jun 22, 2009 (gmt 0)

10+ Year Member



You folks are great! Thanks for helping so quickly; it's beginning to make more sense to me now.

My site is hosted on a commercial server (DreamHost), which I'm assuming is configured properly so that should be OK.

It's clear now that I should put the PHP in a different directory from where the site pages reside. Are there any downsides to creating a subdirectory called "includes" or "scripts" or "nonpublic" or whatever?

Sure do appreciate this help.

Craig
Sunnyvale, CA

StoutFiles

5:52 am on Jun 22, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



but if someone knew where to look for it couldn't they just copy or download the PHP file

No, it doesn't work that way. You can't download a .php file from someone's server, otherwise almost every website out there would be hacked. Think about it, even if you include() files I would know the directory where you included them from by downloading a .php file...

The only way someone can see your .php code is by ftp'ing into your website, and if they did that then you're screwed anyway.

[edited by: StoutFiles at 5:52 am (utc) on June 22, 2009]

craighaggart

6:17 am on Jun 22, 2009 (gmt 0)

10+ Year Member



> "The only way someone can see your .php code is by ftp'ing into your website, and if they did that then you're screwed anyway."

Thank you for that clear explanation. I believe I finally understand.

This forum is a wonderful resource! Thanks a million for being so patient with rank beginners like me.

Craig
Sunnyvale, CA

StoutFiles

6:53 am on Jun 22, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well, let me clarify that a little more. You CAN download a .php file from someone's server, it's just that the .php code will process on their server before being sent to you. Therefore, you won't see any of the .php code because it has been already run.

If you make a file with <?php echo "Hello World"; ?>, when they view or take the file all they will see is Hello World in the code...no php. If you make a file with <?php $password = "12345"; ?> they won't see anything, unless you decided to echo the password.

Think of php as your secret language that only you can see and no one else, unless you choose to echo variables. A good way to test this is to make some .php files with a mixture of php and html, then put it on your server. View that file from a browser and "view source", you won't be able to see the php code and neither will anyone else.

[edited by: StoutFiles at 6:55 am (utc) on June 22, 2009]

coopster

12:49 pm on Jun 22, 2009 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



This forum is a wonderful resource! Thanks a million for being so patient with rank beginners like me.

Welcome to WebmasterWorld, craighaggart :)

FourDegreez

3:34 pm on Jun 22, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here is what I do. I have a directory called "php" right under the home directory, at the same level as "public_html". It is in the php directory that I keep many php scripts, including those used for db access.

In my public_html directory I have a script called setIncludePath.php which does the following:

set_include_path(get_include_path() .':/home/[my_acct]/php/');

I include this script on every page, so that I can easily include any file in the php directory. Actually, I use require_once():

require_once('foo/bar.php');

where "foo/bar.php" is found in the php directory. Nobody hitting the server with a browser can request foo/bar.php because it is completely outside the public folder.

[edited by: FourDegreez at 3:36 pm (utc) on June 22, 2009]

craighaggart

11:41 pm on Jun 22, 2009 (gmt 0)

10+ Year Member



Thanks again, everyone. I feel reasonably confident that I can now proceed. I had already written some of the PHP and did indeed use the require_once() function, so it appears that I'm on the right track. I'll create a directory for my PHP code at the same level as my public HTML directory rather than as a subdirectory under it.

I'm sure I'll be back soon with more questions! One of the things I'd like to do in the future is find out if I can get the forms "submit" button to do more than one task. But that's for later and it should be a separate discussion thread... :)

Craig
Sunnyvale, CA

AlexK

12:47 am on Jun 23, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



a properly configured server will never present raw PHP code

To be 100% accurate, the phrase above needs words like the following in front of it:
    "Most of the time"
    "In Laboratory conditions"
    "In theory"
    ...etc etc

Assume always that, due to one kind of a glitch or another, that web-facing raw-PHP will be seen, and code accordingly.

craighaggart

1:42 am on Jun 23, 2009 (gmt 0)

10+ Year Member



> "Assume always that ... web-facing raw-PHP will be seen, and code accordingly."

Oh man, now I'm back to where I started! That was my original mindset, which is why I had to ask how to code a PHP script to access a MySQL database. The username and password must be embedded right there in the PHP; if it's possible for someone to see the PHP, how in the world is this done securely?

I am now back to being confused about it. Is there some other way? How is this normally done? I know that millions of web sites use HTML forms to call PHP to access a MySQL database. How do THEY do it? Is there some trick or advanced technique?

Craig
Sunnyvale, CA

StoutFiles

2:27 am on Jun 23, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



"Assume always that ... web-facing raw-PHP will be seen, and code accordingly."

Don't freak out from this statement. That's like me saying you should go buy meteor insurance because a meteor could fall on your house. It's not supposed to happen and there is a 0.001% chance of it happening.

I know that millions of web sites use HTML forms to call PHP to access a MySQL database. How do THEY do it? Is there some trick or advanced technique?

Look up POSt variables. Basically a HTML form will send variables to a secon page that grabs the sent variables with a $_POST['variable_name'] command. It's not hard to learn, lots of good tutorials out there about html forms and POST.

craighaggart

3:15 am on Jun 23, 2009 (gmt 0)

10+ Year Member



> "...HTML form will send variables to a secon page that grabs the sent variables with a $_POST['variable_name'] command."

I've got that part down pat. It's the database access that I'm specifically wondering about -- as in how do people deal with making a MySQL database connection via PHP since the username and password have to be put into the script? My current code is basically the following variety:

$dbconnect = mysqli_connect('mysqlhost', 'myusername', 'mypassword', 'mydatabase') or die('Database connect error.');

It just seemed jarring to me that username and password are right there in the code for anyone to see if they could somehow view or download the PHP. But if this is the normal way that everyone does it, then I guess it must be OK. I just don't have any experience with PHP so I had to wonder about it.

As I said at the outset, I'm a rank beginner! :)

Craig
Sunnyvale, CA

AlexK

7:33 pm on Jun 23, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The statement was not intended to freak you out, but to underline & confirm your suspicions (and yes, I've seen it myself on coding that was never supposed to be seen by the public, and should not have become visible; busy, complicated, public webservers are not working in laboratory conditions).

You have already started to take the correct steps:
craighaggart:

I'll create a directory for my PHP code at the same level as my public HTML directory rather than as a subdirectory under it.

(Even better if you can create a directory above the public-html directory) (if you cannot, research the use of '.htaccess' files in preventing public access) (such a file will NOT prevent local access by your scripts)

Place all your DB-connect coding within a script placed within a private directory ('

$dbconnect
' as previous); such a script is a perfect candidate for a function or (better) a Class, thus encapsulating such coding all in one place. The function should at minimum return
$dbconnect
. Then,
include()
or
require()
the Class at the top of your public script. If seen, all that folks will see is the
require()
coding.

If you wish to take it one step further--since it is a good idea to keep server directory paths private if you can--and if you have server access, add the non-public directory to your php.ini include path:

; UNIX: "/path1:/path2"  
;include_path = ".:/php/includes"
;
; Windows: "\path1;\path2"
;include_path = ".;c:\php\includes"
include_path = ".:/usr/share/pear:/path/to/private/dir"

The step above will allow you to include the file without any directory components; naturally, the file needs to have a unique name.

g1smd

11:31 pm on Jun 23, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



PHP is a programming language. You use it along with normal HTML to make a dynamic web page.

If your server is *not* set up to "run" PHP scripts then the text file full of PHP instructions will be sent as plain text to the browser, exposing exactly how your code is written.

If your server *is* set up for PHP, then whenever anyone calls the PHP file from the web, the server will 'run' that program. Only the stuff generated by the PHP 'print' and 'echo' statements will be sent out to the browser.

If there is an accident with the server settings, it is possible that the PHP file will revert to being sent out as a plain text file. However, users can only directly access files that are in publicly accessible folders of your site.

If you put critical files into folders which are located outside of those that are visible from the web, then they will always be safe. You make those files work by calling them as 'includes' from one file that *is* visible from the web. The server accesses those private folders by an internal route, not by calling them via the web.

The alternative to putting the 'secret' files 'above' the web root is to put them into a folder which *is* visible from the web, but to then add a configuration file to that folder that disallows all access to that folder using HTTP methods. The server will still be able to internally access the folder and its files (as per when that are 'included'), but they will not be directly accessible from the web with their own address.

craighaggart

1:03 am on Jun 24, 2009 (gmt 0)

10+ Year Member



I could be wrong, but I don't believe I have control over the php configuration on the web server (dreamhost.com). I also don't believe I have access above my domain's root directory. But it absolutely is set up to run PHP; I've tried it with a couple of very basic scripts while going through a PHP tutorial.

I definitely DO have the option to password-protect directories and subdirectories, too, but what I don't get is how code in the public directory can access a script in a password-protected directory. If it takes a password to get access, won't that password have to be in the potentially visible code? I hope I'm making sense.

Craig
Sunnyvale, CA

g1smd

1:33 am on Jun 24, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The password of which you speak, is located in the .htpasswd file and it controls how people on the outside world access that folder via HTTP from the web.

The server itself has no problems reading the folders of it's own hard drive. It doesn't need to go out on the web and back in through HTTP to do that. It just reads them locally and internally. Doing that, it has no need to supply any sort of password to gain access.

You need *one* script to be web accessible. All the rest that are 'included' by it, can be hidden elsewhere and protected from 'direct' web access while still being accessible to the file that calls them. Remember, the PHP code is being run *on* the server, not in your browser.

craighaggart

1:46 am on Jun 24, 2009 (gmt 0)

10+ Year Member



So do I understand correctly that I use .htaccess to create a protected directory, put PHP to access the database in there, and when the script is invoked from the HTML in my public directory (via the PHP commands embedded in the HTML) it will run without having to supply any password?

Craig
Sunnyvale, CA

g1smd

1:59 am on Jun 24, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If a running script needs to call another file, it doesn't need a password, because it will not be accessing it from the web via HTTP but simply by reading a different folder on it's own hard drive internally within the same server.

.

It's like the staff offices in a bank haven't got a door that leads right on to the street, they have thick walls to prevent access; they can't be accessed from the street. Only the customer areas of the bank are accessible from the street, but those areas do then have access to the staff offices if you're *inside* the building.

As a browser you are never inside the building. You only get to look in through the customer door.

As a bank manager you have access to all areas inside the building, so you could fetch something from the offices and take it to the door and hand it to someone outside.

The bank manager didn't have to go outside and try to penetrate the office walls from the outside of the building. He used an internal corridor to get from area to area.

craighaggart

2:40 am on Jun 24, 2009 (gmt 0)

10+ Year Member



I like the office door analogy, but the source of my confusion has been the concept of a LOCKED door. If it takes a key to get through the door, who has access to the key and how do they get it? I don't want to just leave it under the mat. :)

Anyway, thanks yet again for the help. I will put the database connection PHP in its own protected directory and move forward with reasonable confidence.

Craig
Sunnyvale, CA

FourDegreez

3:29 am on Jun 24, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hey craig, it seems there is advice overload in this thread! Your best bet, once again, is to have a directory for your private scripts that is not under public_html at all. You don't need to worry about password protecting it then. It is already safe without jumping through hoops.

Consider, if we are going off the fear of the server "doing something wrong" and sending out your code, theoretically the same thing could happen and give access to your password protected directory. By placing your scripts in a directory not under public_html, it is not possible for an internet user to view them, PERIOD.* You don't need to mess around with .htpasswd and whatnot.

*Logically speaking, of course. All bets are off when it comes to hackers discovering new exploits, but that problem exists under any proposed solution.

craighaggart

3:54 am on Jun 24, 2009 (gmt 0)

10+ Year Member



> "Your best bet, once again, is to have a directory for your private scripts that is not under public_html at all. You don't need to worry about password protecting it then."

It looks as though it won't be too difficult to try it both ways to see what works, but thanks to everyone's very detailed advice I at least think that I now know the following:

1. The PHP database access script should be in a different directory from the HTML that calls it.

2. Using a protected directory should work and may be better, but it apparently isn't strictly necessary.

3. It's normal (and apparently OK) for the database access PHP to have the MySQL username and password in it.

4. The PHP "action call" in my HTML doesn't pose a security issue just because it references the PHP database script that contains the username and password.

I suppose I should stop fretting over this now and just finish writing the damn code! :)

Craig
Sunnyvale, CA