I'm developing an application where I have a configuration page that has some data that must be hidden from anyone who tries to access them directly, I'm currently doing a verification, but I don't know if it really is safe, I'm using this:
if ($_SERVER['REQUEST_METHOD'] == 'GET' && realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME'])) {
die();
}
In other words, any user who tries to access the page remotely dies, is this safe or is there a better way to do this?
It looks like you're using an include file for PHP. There are three ways you can make it inaccessible via GET request.
Use .inc extension and make the server not serve .inc files and throw Error 404.
Put the file in a non-accessible location, out of www and use the include path, which can include file from any path.
Use .htaccess to limit the file access, i.e., see the below one:
Contents of .htaccess to limit config files.
RewriteRule ^config/.*\.(php|rb|py)$ - [F,L,NC]
Related
All of the php files in the application are directly accessible through URL.
Adding this code at the start of my php files works for few of them which are being requested with POST method:
if ( $_SERVER['REQUEST_METHOD']=='GET' && realpath(__FILE__) == realpath( $_SERVER['SCRIPT_FILENAME'] ) ) {
die(header( 'location:/webapp/postings' ));
}
But, I do have some php files which are being requested through GET method and the above code doesn't work for them, because of which I came with the following code:
if(!isset($_SERVER['HTTP_REFERER'])){
die(header('location:/webapp/postings'));
}
I know that the HTTP_REFERER coudn't be trusted. Any other options?
can someone please tell me a generic way of preventing direct URL access without altering the code across all the php files.
Note: My Application is running on IIS 7.5 Web server.
Don't do this:
public_html/
includes/
dont_access_me_bro.php
...
index.php
...
Do this instead:
includes/
dont_access_me_bro.php
...
public_html/
index.php
...
Explanation
Keeping your source files outside of the document root guarantees that users will be unable to access them directly by changing the URI on their HTTP request. This will not protect against LFI exploits.
To find out where your document root is, this handy PHP script can help:
var_dump($_SERVER['DOCUMENT_ROOT']);
If this prints out string (25) "C:\htdocs\www\example.com", you don't want to store your files in C:\htdocs\www\example.com or any subdirectory of C:\htdocs\www\example.com.
If you place user-provided files inside your document root, you're creating the risk that someone will access them directly from their browser, and if Apache/nginx/etc. screws something up, their uploaded file may be executed as code.
So you would not want your files to be inside C:\htdocs\www\example.com\uploaded, you would want something like C:\uploads\example.com\.
This is covered in-depth in this article on secure file uploads in PHP.
For a file transfer system, I store data on my server. The data can be accessed using a URL, for example:
http://filestorage.example.com/files/clientfiles/clientid/test.pdf
All files inside the folder clientid/ are linked on a generated download page for the client, For example:
http://example.com/download.php?clientid=28692692846
Above URL contains a webpage with multiple links to all files inside the clientid folder:
<a href="http://filestorage.example.com/files/clientfiles/clientid/test.pdf" download>
test.pdf
</a>
Now I want to restrict the access to the files. It should be impossible to access the files from outside, they should only be accessible from the download.php.
Is it even possible to achieve something like this?
Files and the script are on the same server.
The simplest way I can think of to accomplish this would be to use a unique session variable generated on the files inside the /clientid folder - regardless of what the file extension is for these, they'd be simple PHP pages which loaded the files via download.php.
session_start();
$_SESSION['file_id'] = $secret_file_id;
header("Location: http://example.com/download.php?clientid=28692692846");
Then in the download.php file, check for this variable.
session_start();
if((isset($_SESSION['file_id'])) && ($_SESSION['file_id'] == $secret_file_id)) {
// Offer file for download
} else {
//Not referred from correct URL, reject.
}
You can put a .htaccess file in that folder that contains just:
deny from all
In this way you cannot open any file from that folder, but you can include them in php without any problems.
Yes, you can achieve this through .htaccess using:
order deny,allow
deny from all
allow from example.com/download.php
This will deny everyone access unless they visit via example.com/download.php.
If you're using Apache 2.4, then you would need to use:
Require all denied
Require host example.com/download.php
Obviously you would need to place the .htaccess file into the folder that you wish to restrict access too. So if I'm understanding your file structure correctly that would be /clientid/
So I work on a website and to make things easier I made specific files for every task (like: for the top menu I made menu.php) and then require(); them in the main files. All is good but I tried accessing in the browser /include/menu.php and it shows up. I don't want people to access them whenever they want, I just want to require them and to be available only through the main file.
The easiest way to prevent other php files from being accessed, is to define a variable in the main script:
define('IN_APPLICATION', true);
In all of your other files, simply add:
if ( !defined('IN_APPLICATION') )
die('You cannot access this file directly.');
An alternative way is to use an .htaccess file. If your server is running apache, this is all you will need. Simply put this file in your /includes directory.
This is what the map of my website looks like:
root:
-index.php
-\actions\ (various php files inside and a .htaccess)
- \includes\ (various php files inside and a .htaccess)
- .htaccess
I know that if I use "deny from all" in actions and includes directories, the files in them will be secured from direct access.
Now, my actions folder has many php files that are called by index.php (forms).
I have "deny from all" in .htaccess inside \actions, but then I have the forbiden access to that files.
So, how can I protect the files from direct url access but have the exception that can be called from index.php?
The easiest way is to place a constant in the index.php and check in the other php files if this constant exists. If not, let the script die.
index.php
define('APP', true);
various.php
if(!defined('APP')) die();
If you want to block using .htaccess then most likely the best way of adding the exception is to add it to the same .htaccess file. If you want to prevent PHP script from working (but not from being "visible"), then simply look for certain condition (like session variable, constant) at the begining of your scripts. Unless these scripts are invoked "the right way", these requirement will not be ment, so it'd be safe to just die() then
I have a php class that connects to a database which has the password to the database hard coded into it. I do NOT have have access to folders outside the webroot. Reading this forum and others it seemed that creating a htaccess file with
order allow,deny
deny from all
in the directory with my php classes would do the trick. however after doing some quick testing it seems this also blocks the public files which need access to the database to generate the site. to be clear this is the structure i want:
index.php (public file which calls on php classes that access the database)
php_classes/DatabaseConnect.php (contains the password to the database. i want to hide this from everything that is not uploaded onto mysite --- or better yet only to specific files i name)
...
thanks,
brook
Do not place your PHP code in the webroot. Frameworks will typically use this technique where they only put a bootstrap file in the webroot...you can do that same and place your PHP file with sensitve information above your web root so it cannot be browsed.
Your bootstrap file would #require_once '../safe_dir_above_webroot'.
If you're worried about others seeing the login details to your database, rest assure that it cannot be seen if inserted between PHP tags.
.htaccess is a little tricky with some servers. It seems quite a few setups hate overruling which I can understand.
Since you have suggested that you cannot access folders outside of the root directory, you may just want to do something like this.
define("include_allowed", true);
Call that in the leading file, for instance index.php. When a file is included it should check to see if include_allowed has been set true.
if (include_allowed != true) header('HTTP/1.1 404 Not Found');
This checks to see if it has been included by index.php or which ever file that has defined include_allowed true.
If it fails to return true, a 404 error is sent saying not found to trick users! :)
Since your file is PHP , it will processed by the PHP exe, before being rendered to the client. So the password should not be visible. Having said that to use htaccess to stop view a particular file you can do this
<Files php_classes/DatabaseConnect.php>
Deny From All
</Files>