Make URL inaccessible for everything but a specific Webpage - 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/

Related

How can I make a php page inaccessible to all users?

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]

PHP directly accessing the required files

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.

How can I access sql login info outside of web root

I'm a newbie.
I have a php script located here /var/www/check_login.php that includes sql login information in plain text. This file is accessed to verify correct user credentials by my login page /var/www/login.php via <form name="" method="post" action="check_login.php">
I'd like to store check_login.php outside of web root directory so it cannot be accessed remotely.
How would I tell login.php to access check_login.php outside of the web root directory?
I'm guessing its not as simple as action="/var/<new folder outside of root>/check_login.php
Thanks!!
Move file with credentials to one level up directory and in file check_login.php
include('../credentials.php');
You're on the right track. Create a different folder for your site in /var/www. I like to do this setup:
/var
---/www
-------/mysite
----------/html
----------/config
----------/lib
etc. In apache, I tell it my document home is
/var/www/mysite/html
and then I store any config files (like MySQL credentials or classes) in /var/www/mysite/config. Then, I can include these files with something like:
require_once("/var/www/mysite/config/mydbcreds.php")
In your example, login.php would need to call your check function in this file, and would be able to if you require it to be included. Check out my answer here on how to use a MySQL connection class that may save you some time and headaches.
Create a new page for your database connection information and move that to /var/
You can then use your HTML action="check_login.php"
and on your check_login.php script, use the solution which Gustek suggested:
include('../credentials.php');
You can simply use include('path of folders/ your_ logging_data .php);
If you're on a shared hosting plan, I would simply create a new folder outside my website root and have all my non-public files in there. Then in the php.ini file for your website, I would edit the include path to include this new folder. In your .php file, simple put require("the-non-public-file.php"); at the top, i.e, without the absolute path.

How can I prevent users from accessing include files?

I am using apache server.
Is there a way to prevent users from accessing my include files directly ?
But only allow the server the access to those ?
Another way is to have the include files outside of the directory the site is served from. For example:
/
includes/somefile.php
http/index.php
So the Web site is served from http/, but includes are outside of that directory, meaning no one can access them directly from a Web browser, but your scripts can include them like this:
<?php
require_once '../includes/somefile.php';
[...]
Put them in a directory outside of the web root.
i.e. if index.php is in /var/www/domain.com/www, put the includes in /var/www/domain.com/includes or something.
Do not put the include files under the document root (i.e. outside the file tree that apache delivers to the user).

using htaccess to hide database passwords

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>

Categories