PHP file security on webserver - php

I'm slowly learning PHP, MySQL, along with some HTML, using localhost as my webserver. However, I'm starting to wonder how my .php files are going to be secured if I put this actually on the Internet.
I have a webpage at localhost/app.php that includes a form, some PHP code, and some MySQL queries. The MySQL credential information is located one directory above where app.php is located, but how do I prevent from strangers accessing the contents of app.php, including MySQL data structure, commands I'm using, etc. When you view the source code in a browser, you only see the HTML part of it, but couldn't someone download app.php and look into the actual file if he wanted to?
What's the proper way of constructing the file structure? Links or comments are greatly appreciated! TIA!

Well, if you're using the .php extension, then Apache will serve up the parsed version -- echo and print will output but your variables won't.
If you're still concerned there's a few ways of making your files more secure.
Apache aliasing is common -- it lets you have one directory act like it's another. In this case, you'd alias your PHP directory to some directory on your domain. If your file structure is /home/user/my_files/, you might alias my_files to be www.my-domain.com/files. The script would not be accessible there to the requests, but it would be accessible to something on the server.
Symbolic links or symlinks can accomplish the same as the above.
simply place the config files somewhere else and directly reference them. Generally not a good idea as it is hard-coding file locations, but it is an option.
the CodeIgniter method: in your index.php have define( 'IN_APPLICATION', 1 ); in your config files have if( !defined( 'IN_APPLICATION' ) ) die( 'No direct script access allowed' );

No. the php is parsed if the page is requested over HTTP. The person would have to know a vulnerability in your app, Apache or PHP or have some other access such as FTP.
You can move the files out of your wwwroot and reference them elsewhere. Also, never name your include files as .inc. always name them `.php.

Try to download the .php file on your localhost. You'll find that all you get is HTML code. This is because of how a server works. Here is an example with a php file
Client (usually a web browser) sends a HTTP request to the server, i.e:
GET /app.php HTTP/1.1
The server takes the request and processes it. In the case of a php file, the server should process the php file into HTML.
The HTML is returned to the client.
If you are using Apache, and want to make sure that the php files are being processed, make sure these rules are in your apache2.conf:
LoadModule php5_module modules/libphp5.so
AddHandler php5-script .php
AddType text/html .php
And, just for fun, if you did ever want to expose your php source, add this line to apache2.conf:
AddType application/x-httpd-php-source .phps
To be secure, make sure that your mySQL configuration files and anything else you don't want public are stored outside the directory you are serving up. The apache docs are a great resource for understanding how all this works.

While there is not a direct problem with doing this, (many applications do this, and since the source cannot be seen without hacking your site), many applications solve this using a 'frontcontroller'. A frontcontroller is used a lot in MVC structured (Model, View Controller) applications.
A typical structure is like this:
app/ (applications, controllers and views)
lib/ (libraries, generic logic)
config/ (your configurations)
web/ (your webproot, only for css, images, javascript etc.)
web/index.php (your frontcontroller)
By only exposing index.php and placing all php and sensitive files outside of your webroot they will not be accessable for anyone from the web.

Related

Definition of Outside Webroot

I have been reading about where to securely save a PHP file that has my mysql database connection password. I understand from the forums that it should be saved in a folder above the webroot. I have a cloud server from a hosting company.I have access to root
The path to the public files is as follows:-
/var/www/vhosts/mydomain.co.uk/httpdocs/afile.php
Say I have a PHP file (containing my password) called sqlpassfile.php
Would the following be okay as a place to securely store it? ie in a new folder called Newfolder after vhosts??
/var/www/vhosts/NEWFOLDER/sqlpassfile.php
Sorry for a simple question but just want to make sure its secure
Thanks
All the nowadays PHP framework you will find do, indeed store their whole code base in a level under the web root.
They do not only store informations like credentials actually, they do store all the business logic of the application outside of the web root. They will then only allow a facade file to be accessed (most of the time a index.php or app.php) that will, then, with the help of controllers, handle every request and route you to the right page/content, and, of course, all the static content the site will use (your design images, your css, your js, ...).
For example :
Zend Framework does use a public folder where you will find an index.php and all the static files
Symfony does use a web folder where you will find two files app.php and app_dev.php and again all of the static files
So in your case you could do
/var/www/vhosts/example.com/httpdocs/ is the web root of your server
/var/www/vhosts/example.com/app/ store all the php code you need
/var/www/vhosts/example.com/app/config store all your configuration file, and then maybe your credentials files which you can call sql_config.php
/var/www/vhosts/example.com/httpdocs/afile.php will require_once '../app/config/sql_config.php
Usually, People just save the database connection information in a regular PHP file, for example, Wordpress saves the connection info in it's wp-config.php. Simply because nobody is able to see your password by visiting that php page, nothing is returned.
To make it more secure, you can disable access to php file while mod_php stopped working. Try this in you .htaccess
<IfModule !mod_php5.c>
<Files *.php>
Order Deny,Allow
Deny from all
</Files>
</IfModule>
Please also have a look at this post:
Password in file .php
Whether your method is safe depends on the configuration of the server, something that providers are not often very good at documenting.
Your first line of defence is keeping what is essentially confutation data inside a file named with a .php extension. So if it is accessible from a browser the webserver will execute the file rather than returning the data. You certainly want at least 2 levels of security on your data (each of which you have tested independently).
Considering the path you have chosen, /var/www/vhosts/NEWFOLDER/sqlpassfile.php what happens if you request http://NEWFOLDER/sqlpassfile.php from the server? (In most cases, nothing but once in while....) Generally its better practice to keep it well clear of the directories your webserver uses.

Creating a php file in PHP

I'm working on an installer for a project of mine and the installer will create a configuration file.
I have it working 99.99% fine, but in that file i want a check to ensure a hacking can't access it directly, and that code uses the $_SERVER super global, which in every run, gets parsed by php so it breaks the logic I'm trying to go for.
does anyone know I can get the superglobal to stay intact as it is without it parsing or should i rethink my logic and add it elsewhere?
for those who may want to see the code, here it is:
#Disable direct access.
if(!strcasecmp(basename($_SERVER['SCRIPT_NAME']),basename(__FILE__)) || !defined('accessed')){
die('<string>No Direct access is allowed for this file.</string>');
}
Assuming you are using Apache (or any .htaccess compatible server), you just have to create a .htaccess file in the folder holding your configuration file, containing the following:
<Files config.php>
deny from all
</Files>
It will prevent any access to this file through an HTTP request.
See using .htaccess files for details.
Don't use in-script or .htaccess protections - just write the file somewhere outside of the document root. If you don't want something to become available, don't make it available.
Putting it in the document root is like your bank hanging sacks of money in the front window with "do not steal" written on them.

PHP source code security on server

I am a PHP newbie and a have a php security question. Is it possible for somebody to get the source code of a php script file running on a server with default configuration? If so, what is the best way to be protected? I am asking this because I happened to download a php file when I requested a page from a site and what triggered my concerns. I think that maybe apache configuration was wrong and served that file to me like a simple file but I am not sure. Also what is the best place to keep "sensitive" data such as database or smtp configuration?
Thank you,
Alex
For the most sensitive information, I'd suggest putting it outside of your web root folder, and including it through "require" or "include". This way, even is some configuration gets botched on the server, the visitor will only get served the line "include('secret_stuff.php');" and not the actual script.
Exactly what David Dorward said but i would advise you take a look at the following patch(s) that would modify apache to not send source code's regards if there is a misconfiguration.
http://mirror.facebook.net/facebook/patches/ap_source_defense.patch
Patch like so:
cd apache-1.3.x
patch -p1 -i ap_source_defense.patch
More Patches from Facebook Development Team: http://mirror.facebook.net/facebook/patches/
The best way to protect your much needed source is to place them outside the public root directory, as if apache is running it will not be able to serve files directly from the folder up public_html
for example:
C:/server/apache/
C:/server/apache/htdocs/
C:/server/apache/htdocs/includes/
People can specifically view the files my going to
http://hostname.tld/includes/
but having the directory structure of:
C:/server/apache/
C:/server/apache/includes/
C:/server/apache/htdocs/
and then within
C:/server/apache/htdocs/index.php
you have
<?php
require_once('../includes/config.php');
?>
this should protect all major files bar the view file (index.php)
If the server is not configured to handle PHP files, then it will treat them like any other unknown file (and serve them as either text/plain or application/octet-stream.
PHP support is, as far as I know, always provided as an extension or external program (for CGI, FastCGI, etc) and never as a built in for an HTTP server.
If the server is properly configured to run PHP code, then people without direct access to the server cannot view the PHP source code. You don't have to do anything else.
It is only because that server was not configured to run PHP, and instead served it as text, that you could see the source.
If you have this line in your apache.httpd.conf file,
AddType application/x-httpd-php .php
Apache should deal with data, rather than showing them...
Also you need to start php services.
What you describe as "default configuration" is a webserver without php installed (or with php disabled). In these cases, it is certainly possible to download the php script.
Make sure php is installed (as it will be on ~100% of production php servers) and/or block access to your configuration file with an .htaccess file like this:
<FilesMatch "^config.php$">
Order allow,deny
Deny from all
</Files>
If you want to be extra-tricky (and work even on servers where .htaccess files are ignored), prefix the configuration file with .ht, like .ht.config.php. Most Apache(and some other webserver) configurations will refuse serving files beginning with .ht. However, in general, the only way you could be sure no webserver serves your file is to move it to a directory outside of the server's document directory. On most hosts you or your php script won't be able to access those though.
Your second problem are misconfigurations. There's not much you can do, albeit there might(?) be options to construct a rewriterule to prevent accidential accessibility.
The best prevention however is to keep all scripts outside of the DOCUMENT_ROOT. Just leave a single index.php there, and include all dependencies from there. This is also the best strategy to avoid leaking of configuration data (also don't use ini files for sensitive data, but always .php scripts).
Another worry are shared hosting servers however. All concurrent users on a server can read out your scripts (if not through PHP then via Perl/bash CGIs). Nothing you can do about that, unless you change to a professional hoster which supports running everthing through suexec and thus allowing individual permissions.
Well, "default configuration" is a vague term, but as long as the web server is configured to parse .php files through PHP, you should be fine from that angle. If your scripts themselves happen to parse other PHP files (for eg. a template system) then you need to make sure there aren't any loopholes in that too, since the PHP scripts have full access to your files on the server.
Assuming these are taken care of, you don't need to keep the "sensitive" data in any special place -- just put them in your .php files, but make sure all your scripts end in .php (for eg. config.inc.php) so that they are always parsed via PHP and not sent as plain text.

Can .htaccess rewrites request files outside of the htdocs/httpsdocs area of a server?

On my server, a website resides within a directory similar to /domains/domain.com/public_html. I wish to keep the domain at this path, as all the main files are there, but is there any way to source some files from another location in my server, eg. /global/script.js?
In short, I hope to write a mod-rewrite than can source specific files from outside the DocumentRoot, or something very similar, but I cannot work out a solution.
I figure I could manage this by directing all files to a PHP script (css, js, php, images, etc), which will then work out what file is requested, load the files contents and return it with the correct header. I feel this will more than likely slow down all requests because I believe this requires more processes, is this correct?
No need for mod_rewrite: If all files are in the same directory, you can use alias.
Alias /MyMapDir /global/resources
a request to example.com/MyMapDir/script.js will be mapped to /global/resources/script.js
Note that this works in httpd.conf only!

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.

Categories