Solved

How can I serve files from the filesystem but enforce user authentication?

Posted on 2012-03-15
5
245 Views
Last Modified: 2016-12-08
So I want to upload files to domain.com/secure/attachment/<attachment_id>/<attachment_filename>.<extension>. So if a user_a uploads "screenshot.jpg" it would live at domain.com/secure/attachment/5154234/screenshot_5154234.jpg. If the user_a wanted to view this file they could navigate to this url in their browser. My question is, how can I serve these files from the filesystem while enforcing user authentication/authorization so that user_a can view the file because they're authorized and logged in to the system but user_b can't because either 1) he isn't logged in or 2) he's not authorized?

As a real life example, JIRA implements this method.

As a side note, this seems interesting because, how could your run this kind of logic when the uri is to a jpeg and not a php script.

Please include code examples.
0
Comment
Question by:aristanoble
  • 2
  • 2
5 Comments
 
LVL 109

Accepted Solution

by:
Ray Paseur earned 300 total points
ID: 37728648
...uri is to a jpeg and not a php script

A URI represents an HTTP request.  The request (usually GET or POST method) is sent to the server.  The server responds in any way that it sees fit.  The server may have rewrite rules that (for example) see requests for .jpg files and send the requests to an intermediate client authentication script.  This is one way that a server could respond.  But most servers are configured to simply serve up the image files.

If you want to keep image files away from people, the only secure answer is, "Do not put those files on the internet."  Once you have sent an image file to a client browser you have released it into the wild.  You have no more control over the file.  The client can copy it, store it, modify it, re-transmit it, republish it, etc.  Your only protections against these actions are the legal system.  And as we have seen many times in the last two decades the legal system is not a nimble match for technologists who would choose to ignore it.

My advice would be to have a data base that handled client authentication and held two other tables.  One is the table that gives the file paths to all the uploaded files.  The other table is the junction table that relates authorized clients and uploaded files.  When a client requests a directory listing, he is shown the files that are permitted to his client identity.  When the client requests a file, he is given access via an authentication script that checks the junction table for the appropriate relationship before it serves the file.

If you keep the files outside of the web root directory tree and serve the files via the authentication script, you will be fairly secure.

HTH, ~Ray
0
 
LVL 1

Author Comment

by:aristanoble
ID: 37729389
serve the files via the authentication script


So, is that to say the files will be served as /files.php?file_id=khj4344gkj2, for example, and I would perform the authentication in that script before I serve the file?

If so, how would I serve up various filetypes (images, pdfs, zips, etc...) through that script?
0
 
LVL 34

Assisted Solution

by:Slick812
Slick812 earned 200 total points
ID: 37730568
greetings aristanoble, , , This may not be a straight forward code setup for you, since you will need to have error control for -
1. No Sign In, Not a Logged In User asks for a restricted file.
2  User that wants to get something (file) that he does Not have rights to.
3. Asks for a file that does not exist, or is in the wrong location (directory).

Since you ask for - "how would I serve up various filetypes"  in your post here is some code that may help you, although it DOES NOT do any User access verification, this just does some verification for the GET input and if the file exists -

// User verification would go FIRST, maybe using a Session variable

$dir = (empty($_GET['loca'])) ? '?' : $_GET['loca'];
$fl = (empty($_GET['fl'])) ? '?' : $_GET['fl'];
$ext = (empty($_GET['ext'])) ? '?' : $_GET['ext'];

// ERROR out with a 404 status and error page as =
$error = '<html><head><title>404 ERROR - File Does NOT Exist</title></head><body><h2>ERROR 404 - File Does NOT Exist on this Server</h2></body></html>';


if (($dir == '?') || ($fl == '?') || ($ext == '?')) {
	header('Status: 404  Not Found');
	echo $error;
	exit;
	}

switch($ct){
	case 'jpg': $type = 'Content-Type: image/jpeg'; break;
	
	case 'png': $type = 'Content-Type: image/png'; break;
	
	case 'pdf': $type = 'Content-Type: document/pdf'; break;
	
// ERROR out if it is NOT an approved extention
	default: header('Status: 404  Not Found');
	echo $error;
	exit;
	}

// ERROR out if NOT a valid file path
if (!file_exists ('/home/domain/userF/'.$dir.'/'.$fl.$ext)) {
	header('Status: 404  Not Found');
	echo $error;
	exit;
	}

$fl = file_get_contents('/home/domain/userF/'.$dir.'/'.$fl.$ext);
// Error out if problems getting file
if (($fl === false) || (strlen($fl) < 2)) {
	header('Status: 404  Not Found');
	echo $error;
	exit;
	}

// For any file you absolutly MUST set the file TYPE in header
header($type);
echo $fl;

Open in new window



Ask questions if you need more info or explanation
0
 
LVL 34

Expert Comment

by:Slick812
ID: 37730579
sorry the line -

switch($ct){

should be

switch($ext){
0
 
LVL 1

Author Closing Comment

by:aristanoble
ID: 37730776
Thank you both.
0

Featured Post

Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
This article discusses how to create an extensible mechanism for linked drop downs.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

831 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question