Mobile app version of vmapp.org
Login or Join
Turnbaugh106

: Permissions for serving up temporary files I have a system (web based application) which pulls file attachments from a 3rd party system via SOAP. These are in turn on our system created as

@Turnbaugh106

Posted in: #Apache #Authentication #FileManager

I have a system (web based application) which pulls file attachments from a 3rd party system via SOAP. These are in turn on our system created as files in a directory.

When a user of the system (authenticated through ldap) makes a request to my application to retrieve one of these attachments:

1. I request it via soap
2. Process the response to build the file on our system
3. Redirect user to the location so they can download the file.


First off, is this a good approach?

Is there a better way to serve up files which will not reside on the server much after the attachment download (cron job will clean up the directory every so often)?

Secondly, is there a way I can serve files through apache without storing them in the web root?

Thirdly, how do I enforce permissions on these files so not just any user can download just any attachment?

Our Setup:

linux
apache
php - soap libraries for communication
seperate LDAP for authentication
3rd party soap server (where attachments come from)


EDIT: The code to serve the attachment in case anyone is curious.

<?php

ini_set('display_errors',1);
error_reporting(E_ALL|E_STRICT);

//require global definitions
require_once("includes/globals.php");
//validate the user before continuing
isValidUser();
$subTitle = "Attachment";
$attachmentPath = "/var/www/html/DEVELOPMENT/serviceNow/selfService/uploads/";
if(isset($_GET['id']) and !empty($_GET['id'])){
//first lookup attachment meta information
$a = new Attachment();
$attachment = $a->get($_GET['id']);
//filename will be original file name with user name.n prepended
$fileName = $attachmentPath.$_SESSION['nameN'].'-'.$attachment->file_name;
//instantiate new attachmentDownload and query for attachment chunks
$a = new AttachmentDownload();
$chunks= $a->getRecords(array('sys_attachment'=>$_GET['id'], '__order_by'=>'position'));


$fh = fopen($fileName.'.gz','w');
// read and base64 encode file contents
foreach($chunks as $chunk){
fwrite($fh, base64_decode($chunk->data));
}
fclose($fh);

//open up filename for writing
$fh = fopen($fileName,'w');
//open up filename.gz for extraction
$zd = gzopen($fileName.'.gz', "r");
//iterate over file and write contents
while (!feof($zd)) {
fwrite($fh, gzread($zd, 60*57));
}
fclose($fh);
gzclose($zd);
unlink($fileName.'.gz');
$info = pathinfo($fileName);

header('Content-Description: File Transfer');
header('Content-Type: '.Mimetypes::get($info['extension']));
header('Content-Disposition: attachment; filename=' . basename($fileName));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($fileName));
ob_clean();
flush();
readfile($fileName);
exit();
}else{
header("location: ".$links['status']."?".urlencode("item=incident&action=view&status=-1&place=".$links['home']));
}


?>

10.01% popularity Vote Up Vote Down


Login to follow query

More posts by @Turnbaugh106

1 Comments

Sorted by latest first Latest Oldest Best

 

@Kevin317

First off, is this a good approach?


Sound fine to me. Just make sure you authenticate the user before going through all of that.


Is there a better way to serve up
files which will not reside on the
server much after the attachment
download (cron job will clean up the
directory every so often)?

Secondly, is there a way I can serve
files through apache without storing
them in the web root?


Put the files outside of the webroot. Then using PHP pass the file though a script. That way no one can link to the file directly and bypass your controls. (Naturally make sure the script that does this only after verifying the user has permission to retrieve that file).

Sample PHP:

<?php
if (!isset($_SESSION['authenticated']))
{
exit;
}
$file = '/path/to/file/outside/www/secret.pdf';

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
?>



Thirdly, how do I enforce permissions
on these files so not just any user
can download just any attachment?


Make the users log in to retrieve their files. Then you can set a session variable identifying them as being allowed to download. Make sure your scripts authenticate them on every page of this process.

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme