Block Direct Access to a File Over Http But Allow PHP Script Access

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



Leave a reply



Submit