Block direct access to a file over http but allow php script access
The safest way is to put the files you want kept to yourself outside of the web root directory, like Damien suggested. This works because the web server follows local file system privileges, not its own privileges.
However, there are a lot of hosting companies that only give you access to the web root. To still prevent HTTP requests to the files, put them into a directory by themselves with a .htaccess file that blocks all communication. For example,
Order deny,allow
Deny from all
Your web server, and therefore your server side language, will still be able to read them because the directory's local permissions allow the web server to read and execute the files.
How can I deny direct access to a directory, but allowing it from a php script?
I would use a handler for either of these file types.
Place the files outside of the web accessible file system. i.e. If your web root is /var/www/html then create /var/www/files/ directory and store all your files in there.
$file_id = intval($_REQUEST['file_id']);
$sql = sprintf("SELECT * FROM files WHERE file_id=%d",$file_id);
$query = $mysqli->query($sql);
$file = $result->fetch_assoc()
// add business logic for
// if $user_id is allowed to view $file_id
if (preg_match("/\.pdf$/i",$file['filename'])){
header('content-type: application/pdf');
} else if (preg_match("/\.(jpg|gif|png)$/i",$file['filename'])){
header('content-type: application/pdf');
} else {
die("Unknown file type");
}
$full_path = sprintf("/var/www/files/%s",$file['filename']);
readfile($full_path);
This would allow you to use your application logic to determine which files should be accessed by a user, record the access and keep them out of the web accessible directory.
So instead of using something like this
<img style=max-width:100% src=../files/'.$image.'>'
I would suggest using a syntax similar to this for handling images
<img style=max-width:100% src=/handler.php?file_id='.$file_id.'>'
and a link like this for downloading PDFs
<img style=max-width:100% src=/handler.php?file_id='.$file_id.'>'
It should be pretty straight forward assuming your have a database of PDFs and images. Something simple like this.
CREATE TABLE `files` (
`file_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`file_name` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`file_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
PHP: How can I block direct URL access to a file, but still allow it to be downloaded by logged in users?
Into folder members create new folder files, move here all your songs, create new .htaccess file and add the following lines:
Order Deny,Allow
Deny from all
Into folder members create file get_song.php and add the following code:
if( !empty( $_GET['name'] ) )
{
// check if user is logged
if( is_logged() )
{
$song_name = preg_replace( '#[^-\w]#', '', $_GET['name'] );
$song_file = "{$_SERVER['DOCUMENT_ROOT']}/members/files/{$song_name}.mp3";
if( file_exists( $song_file ) )
{
header( 'Cache-Control: public' );
header( 'Content-Description: File Transfer' );
header( "Content-Disposition: attachment; filename={$song_file}" );
header( 'Content-Type: application/mp3' );
header( 'Content-Transfer-Encoding: binary' );
readfile( $song_file );
exit;
}
}
}
die( "ERROR: invalid song or you don't have permissions to download it." );
And now, you can use this URL to get the song file:
http://mysite.com/members/get_song.php?name=my-song-name
prevent direct url access to php file
You can do it with PHP
<?php
/* at the top of 'check.php' */
if ( $_SERVER['REQUEST_METHOD']=='GET' && realpath(__FILE__) == realpath( $_SERVER['SCRIPT_FILENAME'] ) ) {
/*
Up to you which header to send, some prefer 404 even if
the files does exist for security
*/
header( 'HTTP/1.0 403 Forbidden', TRUE, 403 );
/* choose the appropriate page to redirect users */
die( header( 'location: /error.php' ) );
}
?>
Related Topics
How to Remove the Extra Square Bracket from Json Having Multiple Arrays
Converting Soap Xml Response to a PHP Object or Array
Php Warning: Mysqli_Connect(): (Hy000/2002): Connection Refused
Curl (7): Failed to Connect to Localhost Port 8000: Connection Refused
Check If Class Property Is Not Null Before Calling Any Public Class Method
Symfony: an Exception Occured in Driver: Could Not Find Driver With MySQL
Disable Xampp Redirect Http to Https
How to Use Find in Set for User Rankings Based on Score
Checking If Email Is in MySQL Database in PHP
Generate Preview Image from Video File
(Php, Mysql) Result Could Not Be Converted to String
How to Prevent Multiple Inserts When Submitting a Form in PHP
How to Sort Arrays and Data in PHP
How to Prevent Xss With Html/PHP
How to Get Woocommerce Order Details
Reference - How to Handle Namespaces (Tags and Attributes With a Colon in Their Name) in Simplexml
Laravel - Display a Pdf File in Storage Without Forcing Download