1

I'm using Zend Framework 1.11 for building website. I want to implement functionality when user upload file and after can download it through API or web-interface. The thing is that I don't understand very well how to provide an acceptable level of security for the file storage.

I have the following structure of the project:

-My Project
    -application
    -data
    -docs
    -library
    -public
    -tests

Only folder "public" is publicly accessible. My idea was to save user files in folder "data". When user wants to download file he makes request to controller action, where I can check access rights. If user has access, php script will read corresponding file and send it to user.

My question is: if before saving user files I encrypt it (for example with AES-128 algorithm) will it somehow improve security of file storage? If yes, what is the best practice for keeping keys?

tshepang
  • 12,111
  • 21
  • 91
  • 136
Tamara
  • 2,910
  • 6
  • 44
  • 73
  • If you don't need to worry about storage then you can store these files in databas. That way they will be more secure. – Jay Bhatt May 13 '14 at 15:56

1 Answers1

1

I would do the following:

Create a folder uploads in My Project/data.

Add this lines to index.php

defined('UPLOADS_PATH')
    || define(realpath(APPLICATION_PATH.'/../data/uploads'));

Now you can use this path as a storage for new files uploaded.

Check the permissions for write access for your webserver user!

Now use this Path to move_uploaded_file() or add it as a Rename Filter to your Zend_File_Transfer_Adapter_Http.

$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->addFilter('Rename',UPLOAD_PATH);

The uploaded files will get stored in UPLOAD_PATH.

If $adapter->receive(); was called.

Now, you have stored the files in your data/uploads folder.

If you need some logic to store a file to a loggedin user or similar, you could just name the file with a leading or ending user_id like 4711-image.jpg, where 4711 is the unique identifier.

If you need to handle multiple files, try creating a folder for the current user and name it with that unique identifier like data/uploads/4711/image-1.jpg.

These files will never be accessible as you already realized, only public is public accessible.

But now, how should a user get these files?

One idea is, generating some kind of token which gets stored in a database in relation to a user id or some other informations.

Or just use the folder and filename as unique identifier like data/4711/image-1.jpg.

Now create a Controller/Action that can read a query param (the token or the url_encoded filepath).

In your Action, get the file contents to a variable.

//get the file you want to present to the user
$userId = $this->_getParam('user_id',NULL); //eg. 4711
$fileId = $this->_getParam('file_id',NULL); //eg. image-1.jpg

//create the filepath
$filePath = $userId.'/'.$fileId;
//get the absolute system path
$fullPath = rtrim('/',UPLOAD_PATH).'/'.$filePath;

//check if file existing
if(@file_exists($fullPath)) {
    $fileContent = file_get_contents(fullPath); //content to var
    //create the file download
    $this->getResponse()
         ->setRawHeader('Content-type: application/octet-stream')
         ->setRawHeader('Content-disposition: attachment; filename="'.basename($fullPath).'"')
         ->sendResponse();
    exit(0);
}
else {
    //nothing found (return 404)
    $this->getResponse()->setHttpResponseCode(404)->sendResponse();
    exit(0);
}

Check these link:

http://framework.zend.com/manual/1.12/de/zend.file.transfer.introduction.html

How to download existing file in PHP

PHP - send file to user

Zend Framework: How to intentionally throw a 404 error?

Hope this helps!

Community
  • 1
  • 1
Scriptlabs
  • 498
  • 3
  • 16