How can I prevent users from accessing include files? - php

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).

Related

Host, PHP, htaccess

I need some help.
I was reading the security recommendations of my hosting service and they say that ideally just put the
index file and files like css, js and img inside my root folder, and that all other files should be placed
off, that is, a level above.
I tried doing this in my tests, and I had some problems. The structure of the hosting folders is:
/
/htdocs
Inside /htdocs I put the index.php file and when accessing it through the url exemple.com/index.php works normally.
But putting other test files out of htdocs is what starts the problem. For example, if I have a file called contact.php
and I try to access it through the url exemple.com/contact.php I get the 404 error message.
So the question I have to ask is:
Is it possible to access url files that are outside of htdocs, or better to put all the files that will be accessed by the url inside
of htdocs and leave only configuration files outside this folder, like class, functions, database connection, etc?
And if it is possible to access the files by url, how would I rewrite these urls in htaccess?
and that all other files should be placed off
Yes, this is good practice. However, you're misunderstanding the implementation.
You can not directly access files outside the document root. But you can indirectly access them. I.e., the web server can't see them, but your programming code can.
Ideally, your site would use the front controller pattern. Here, your index.php file would serve every page of your app by intercepting every request and then routing it to the correct end point. I.e., you would never directly request /contact.php, you'd instead request /contact, which would get funneled to /index.php, which would load the required resources from outside the doc root.

Make URL inaccessible for everything but a specific Webpage

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/

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 to hinder PHP files to Global Access

I have some includes files and I don't want to expose them via HTTP. They are only used for being included into other PHP files.
Should I configure .htaccess file and add some lines to specify that?
Thanks in advance...
You could use .htaccess rules or put them outside of your web directory!
Try this:
<Files filename.php>
order allow,deny
deny from all
</Files>
You should never put files, that you don't want to get accessed from outside, into a directory, that is accessible from outside, or in short: Move the files outside the document root.
Lets say
/path/to/htdocs/index.php
/path/to/privateFiles/include.php
In index.php you can use
require dirname(__FILE__) . '/../privateFiles/include.php';
When you want to make it a little bit more portable, you can separate both directories from each other. Usually files from privateFiles/ don't need to know about the files in htdocs. In index.php you can do something like
define('INCLUDES_PATH', '/path/to/privateFiles');
and then anywhere within your application
require INCLUDES_PATH . '/include.php';
When you want to move the private files around, you just need to change the constant in index.php.
If your included file is PHP, define a constant in your index/main code, check it in the include files
Index.php
<?php
define('INDEX_LOADED',TRUE);
include('include.php');
?>
Include.php
<?php
if(!defined('INDEX_LOADED'))
die('not to be accessed directly');
// rest of code here
?>

PHP cannot find my php files if not under htdocs folder

By someone's advice I've put all my PHP files in a separate folder (inc) on the same level as htdocs. Only index.php is left in htdocs. So, it's like this:
C:\myproject\htdocs
- index.php
C:\myproject\inc
- login.php
- util.php
- register.php
...
Now, when I go to localhost in my browser index.php is processed and shown correctly. But any links to other php files are not found. I tried to prepend links with "inc", but they're still not found. What should I do?
My php.ini file has this line (it's on Windows):
include_path = ".;C:\myproject\inc"
The point of an include directory is to put files you don't want to be accessible by a Webserver. If login.php needs to be accessible via a URL like:
http://yourdomain.com/login.php
then don't put login.php in the include directory. Putting util.php in an include directory makes sense because you never want this:
http://yourdomain.com/util.php
You can't put web-accessible files outside the htdocs folder, you should be using the 'inc' folder for files like 'database_functions.inc' which should not be opened directly in your browser:
http://localhost/index.php // directly accessible - goes in htdocs
http://localhost/login.php // directly accessible - goes in htdocs
http://localhost/register.php // directly accessible - goes in htdocs
http://localhost/util.php // you don't want people loading this file directly - put in 'inc'
http://localhost/database_functions.php // you don't want people loading this file directly - put in 'inc'
I believe you need to escape the backslashes in your php.ini -- so it should be C:\\myproject\\inc. But as others have pointed out, you won't be able to use a browser to access the PHP files in your include directory, because the web server will not allow access to a directory outside the htdocs tree.

Categories