Restrictions on PHP include() - php

I am separating some XHTML from PHP by putting the XHTML into a separate file and then using PHP's include() function within the PHP script.
This works perfectly fine, however, users are still able to access the .html file directly if they know the address. They can't really do much with it, but I would rather it not show.
I've seen some scripts in the past use some form of referrer check, is this what I would do to add some basic (Notice I said 'basic') restrictions to prevent it from being viewed by accessing it directly?
Thanks!
Clarification: I forgot to mention that I want to do this within PHP, so no web-server configuration (Moving files out of document-root, configuring web-server to disallow access, etc.). I think the most logical choice here is to use the define() constant check, that's actually indeed what I've seen in other scripts that I had forgotten, as I outlined in my post. I realize this is probably not the best solution, but given that the html file that can be access is of no particular value, the define() constant should suffice.

If you currently place all your files (like index.php) in /something/public_html/ you will want to move the files to /something/. That way users cannot access the files.
The /public_html/ is called your document root. That folder is mapped to example.com, and and basically the website starts there. If you move the files to above where the website starts, no one can access those files via a browser.
As Ignacio said, this will not work with include if safe mode is turned on.
Other methods are to place something at the top of the file thats says
if(!defined("RUNNING_SCRIPT"))
die("No Direct Access Allowed");
and then in your PHP files put
define("RUNNING_SCRIPT", true);
If RUNNING_SCRIPT is not defined, that means they are directly accessing it, and it stops the page from loading. This only works though if PHP runs on the .html files.
You could also use a .htaccess file to disallowed access to that folders.

Just move it outside of the document root. This will not work if PHP is in Safe Mode though.

Change your webserver configuration to disallow access to that file?

No, do something like this:
index.php:
<?php
define('ALLOW_INCLUDE', true);
include('other.php');
?>
other.php:
<?php
if (defined('ALLOW_INCLUDE') === false) die('no direct access!');
// your code
?>

It's a good idea to place this as the first line.
You can also use .htaccess or drop a index.html page too as fallbacks.
<?php defined('SOME_CONSTANT_GLOBAL_TO_YOUR_APP') or die('Access denied.'); ?>

may be apache access control?
http://httpd.apache.org/docs/2.2/howto/access.html

Related

kohana, what does stop accessing files directly from URL mean?

You should recognize the first tag as an opening php tag (if you don't you should probably learn php). What follows is a small check that makes sure that this file is being included by Kohana. It stops people from accessing files directly from the url.
http://kohanaframework.org/3.2/guide/kohana/tutorials/hello-world
Let's assume that your webservers DocumentRoot is /srv/www and you put your example code under /srv/www/application/classes/controller/hello.php.
"stop accessing files directly from URL" means that if a user now navigates to www.example.com/application/classes/controller/hello.php it will not run the script, instead it will display 'No Direct Script Access', since SYSPATH is not defined.
http://kohanaframework.org/3.2/guide/kohana/flow

PHP security - Website Directory Structure

So I have a fairly noobish question, I have been reading up a lot around the subject, but can't quite find the answer I want, so bear with me...
I have a fairly simple website that I have been designing, consisting of the following:
1) HTML and PHP files that I want the user to be able to access directly by typing in the url in the browser.
2) HTML files that are only to be viewed inside an iframe in 1) (don't ask me why I used iframes)
3)PHP files that are called on by 1), e.g. when form data is submitted. I want 2) and 3) to be accessible to 1), but not directly accessible to the user by typing in the url.
4) images and includes, etc.
5) maybe this is a different issue altogether, but I also have a MySQL database.
I understand that I can control access to files by putting them in private/public folders in the website directory? My question is how should my directory structure be and where should I put 1), 2), 3), etc.?
Thanks a lot for your help.
Your directory structure does not matter. Any URL that is accessible to some users is accessible to all users. You only have control over the content of that URL.
If you really need to limit access to the content loaded by 1) you have to use PHP to serve the content. That PHP script can check some parameters or login credentials or something that makes sure the URL has been loaded by 1).
However, it's hard to give you a clear answer since you don't describe the concrete problem you're having. For example, it makes much difference how secure the method needs to be. For example, it's rather simple to check if a URL is loaded inside a frame using JavaScript but that check is not hard to circumvent.
Your httpdocs directory is your Apache DocumentRoot (found in /etc/httpd/conf/httpd.conf) or your vhost DocumentRoot (if you've got vhosts defined), so assuming Linux:
1,2,4 should go into /var/www/vhosts/sitename.com/httpdocs/ - these are directly accessible through the browser.
3 should go into /var/www/vhosts/sitename.com/library/. When the user submits data it should hit a handler page (the user must be able to "see" this page) and that page includes the necessary files from this library directory. As long as your server is configured to run PHP for all *.php scripts this is probably unnecessary, as there is little advantage to be gained from hiding PHP scripts. If you don't want them invoked directly and you'd like to leave them in a publicly accessible area, try:
public script:
define('INVOKED_BY_SCRIPT', true);
...
include "../library/hiddenScript.php";
"hidden" script:
if (!defined('INVOKED_BY_SCRIPT') || true !== INVOKED_BY_SCRIPT) {
echo "Cannot invoke directly";
exit;
}
Your MySQL database should be in /var/lib/mysql, or wherever it's been installed by default. Be sure to run the MySQL security script mysql_secure_installation to remove default passwords and test databases.
Everything except the includes should be in your public_html directory.
For 3, it is not possible to have a PHP script that can be referenced by a form, but it not accessible by the user typing in the address into the address bar. The best you could do is to check the post variables to see whether anything has been posted. You could check the HTTP_REFERER variable, but I would not recommend this since it cannot be relied on.
You can't make HTML only to be viewed inside an iframe
There are NO files called by 1). It's users browser that calls your files.
So, just leave your directory structure as is, it's okay.
What you're probably looking for is a way to "hide" your executable files outside of the document root, which you can do with a directory structure something like this:
public_html <-- (document root)
index.php <-- (publicly accessed index file)
images
htmlstuff
private_index.php <-- (application's "real" index file)
application
tmp
Then, for public_html/index.php, you'd just have:
<?php
require_once('../private_index.php');

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.

prevent direct access to a php include

I have a php script PayPal eStores/dl_paycart but it has PayPal eStores "settings.php" Security Bypass Vulnerability
I would like to know if I can prevent direct access to a php include file.
Would this help?
defined( '_paycart' ) or die( 'Access to this directory is not permitted' );
Thank you
I would STRONGLY recommend finding some new script. Any sort of blocking is just sticking a finger in the dam; it isn't a permanent solution and eventually it's going to break.
If you really want to use it, check out htaccess files, particularly "Order Allow,Deny" and "Deny from All"
The problem is that if someone is able to use "include" and read the code contents, variables, and the like, that means that they are already operating on the same server and, to be a bit crude, you're boned if they try to screw with you.
On the other hand, if you're looking to prevent outside access to the file from a remote server, then the include call can only retrieve the values which would be displayed to any external site (and if the question is, "Can I prevent external sites from even loading this file remotely", the answer is "through server configurations in http.conf and .htaccess files" ).
The long and the short, however, is that this is not something which can really be fixed with PHP, this is a server security issue.
The fact that the script has a .php extension offers some protection - any http or https call for that file will go through the web server which is going to execute the php before serving the request.
I would recommend moving the script to a directory under your public web directory and putting .htaccess file in that directory that either blocks all requests, or requires a password to access it. Then include the script when needed by scripts in your public directory. See Apache's .htaccess Tutorial
Probably the most secure way is something like this
$allowed_files = array("/paths/", "/that/", "/are/", "/allowed/");
if(!in_array($_SERVER['PHP_SELF'], $allowed_files))
{
die("Not Allowed");
}
Fill the array with Files that you would like to have access. (You might have to access PHP self in each page you want and copy and paste it in). This will check to make sure that the file being executed is one of the allowed pages. If it isn't the script will die.
I believe $_SERVER might be able to be changed, but probably won't be. This file will still be able to be gotten using fopen or file_get_contents, and if someone reads it, they will know what to change.
But I would forewarn, it is not 'completely secure', because there isn't really a way to make something 'completely' secure.

Can a client view server-side PHP source code?

I'm developing a PHP application that has to respond to request from several clients, and I thinks "Can any of the clients see the PHP code that I'm writing?".
No, unless
There is a server misconfiguration
There is a bad echo/include somewhere
No. Unless you're echoing it to them under where you're actually using it.
Use includes from below or outside the www served directory. (can't +1 yet.. for Frankie)
Don't use symlinks for your http directories. I've intentionally used this to both show source and execute depending on user request path before, but that required httpd.conf changes (or misconfiguration) and can explicitly be disabled in httpd.conf.
If allowing downloads of files using fopen, don't pass anything the user creates to it or they could figure out how to get it to grab any file they can find.
Consider:
fopen('reports/' . $_GET['blah']);
where the user passes in '../index.php'
No, but you should take all measures to prevent it.
You should always set your sensitive code (heck, why not all?) in a directory bellow your server working dir (say /www), that way if the server gets messed up, it wont be able to show your code to the world because that code will be included by php that is not working in the first place.
If you have your webserver set to serve instead of parse your php yes. But then the clients wouldn't work. So the barring any security holes, answer is no.
No. Assuming you've installed a L/UAMP server properly, or aren't printing out (echo, print_r, etc.) and of the guts of your code, the PHP will be processed and the logic or HTML it's meant to output will be used on the page, not visible.
N.B. If there isn't an 'index' in a directory or a proper .htacess file, an Apache server will show a list of files in the directory, which can be downloaded and reviewed.
One mistake for it to happen is to paste a php tag inside a php string, example:
$string = "This is the answer: <s><?php echo $answer; ?></s>";
echo $string;
The person did a Ctrl+C and Ctrl+V of something that should be printed along the string, but the coder forgot to remove the php tags by distraction.

Categories