Web-hosted file authorization - authentication

Im using a PHP based login authentication mechanism to allow/restrict access to some parts of my website (folder module1, module2, etc), but i have a problem with restricting access to files.
I used the documents folder (check below) to host some downloadable files. The links to those files appear in index.php (hosted in the root directory). However if for some reason a non-authorized user get the URL of the files hosed in documents he will be able to download it.
/
/documents/
/module1/
/module2/
PS: as this is an intranet website I restricted the access to documents by IPs, but there is still a small chances that someone use a PC with allowed IP address and he have the URL of the document.

Use some sort of a proxy PHP script that will serve the file for the user without giving the real source location.
The user would then see http://yourdomain.com/download.php?file=mydoc.docx
The real path is still /documents/userid/2342/mydoc.docx or what ever your structure looks like.
Then let your download.php file serve the file by:
<?php
// Validate the user here
// Set document root
$root = 'documents/userid/'.$userID.'/';
// Requested file
$file = $_GET['file'];
// Validate
if (file_exists($root . $file))
{
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false);
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"".basename($file)."\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($root . $file));
ob_clean();
flush();
readfile($root . $file);
}
else { echo "File not found"; }
?>
See more here

Related

Get the original filename of symlinks in nginx

From another script i got some generated symlinks.
2QGPCKVNG1R -> /anotherdir/movie1.mp4
HJS7J9ND2L5 -> /anotherdir/movie2.mp4
LKA6A9LA7SK -> /anotherdir/movie3.mp4
Displaying these files in NGINX works fine, but I'd like to rename the files at download via content disposition.
Question is how do i get the original filename in nginx variable?
I'm not sure it is possible at all. Is that another script yours or under your control? You can generate an additional nginx config file with a map block with the same script where you can describe a ruleset for mapping an URI value to the Content-Disposition header value (or you can write an additional script to do it with readlink -f <symlink> command:
map $uri $content_disposition {
~/2QGPCKVNG1R$ movie1.mp4;
~/HJS7J9ND2L5$ movie2.mp4;
~/LKA6A9LA7SK$ movie3.mp4;
}
And then include that file to the main nginx config:
include /path/to/content-disposition-map.conf;
server {
...
add_header Content-Disposition $content_disposition;
Another way I see is to use lua-nginx-module and a LUA script like
map $symlink_target $content_disposition {
~/([^/]*)$ $1;
}
server {
...
set_by_lua_block $symlink_target {
local result = io.popen("/bin/readlink -n -f " .. ngx.var.request_filename)
return result:read()
}
add_header Content-Disposition $content_disposition;

Can't access uploaded files via Podio API

We actually want to upload a file and attach it to an item but we're having problems just uploading it.
We are having a problem uploading an image into an item. We cant seem to access the image we uploaded to Podio via the API. We get a - "Sorry, you don't have access to this file. You might want to ask your admin to provide you the access to this file."
Which is so weird because everyone in our team cant access it, and we're admins on our workspaces. I also setup the api/secret keys and i'm and admin on that workspace. Whats wrong with this?
This is the code:
Podio::setup($client_id, $client_secret);
try {
Podio::authenticate_with_app($app_id, $app_token);
$upload = PodioFile::upload('PATH_TO_FILE', 'test_image.jpg');
if( $upload != ""){
echo "<br><br>Image uploaded to podio!<br><br>";
echo "<pre>".$upload."</pre>";
echo "<br><br>".$upload->file_id."<br>";
echo $upload->link."<br>";
}
if( PodioFile::attach( $upload->file_id, array('ref_type' => 'item', 'ref_id' => 43 )) != ""){
echo "<br><br>Image attached to item!<br>";
}
}catch (PodioError $e) {
echo $e->body['error_description'];
}
Podio::set_debug(true);
You can't access file itself until it's linked to something because files don't have own access-control system. Once file is attached to item or task or workspace or whatever else, then you might be able to access it if you have enough rights :).
There is at least one error item_id=43 is for sure not your item, so you can't attach file to it.

serious error with php move_uploaded_file not working

i have a serious problem with php file upload.
the problem is that the file is not moving from the tmp to the destination directory
this is my html page
<form name="f1" method="post" action="handleUpload.php" enctype="multipart/form-data">
<input type="file" name="htmlfile">
<input type="submit">
</form>
and here is my PHP page handleUpload.php,
if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST")
{
$arrayKeys=array_keys($_FILES['htmlfile']);
foreach($arrayKeys as $s)
echo $s ." : ".$_FILES['htmlfile'][$s]." <br>";
$name = $_FILES['htmlfile']['name'];
$size = $_FILES['htmlfile']['size'];
$tempName= $_FILES['htmlfile']['tmp_name'];
list($filePureName, $ext) = explode(".", $name);
$valid_formats = array("jpg","png", "gif", "bmp","rar","zip");
$fileObject=fopen($tempName,"r") ;
echo "test Text" . fgets($fileObject) ."</br>";
fclose($dstFile) ;
if($_FILES["htmlfile"]["error"] != 0 ) {
echo "file error with code " .$_FILES["htmlfile"]["error"];
}
if( is_uploaded_file($tempName)){
echo "<br> upladed to the tmp directory ";
move_uploaded_file($_FILES["htmlfile"]["tmp_name"],"./".$_FILES["htmlfile"]["name"]) ;
//move_uploaded_file($_FILES["htmlfile"]["tmp_name"],"upload/".$_FILES["htmlfile"]["name"])
}
}
else{
echo "you must visit the HTML upload page first";
}
the output i get is
name : numerical_hw1.rar
type : application/octet-stream
tmp_name : /tmp/phpK7Gmmf
error : 0
size : 34642
test TextRar!Ïs WÅt K„Á &–Gá#3& numerical_hw1\hw1_q1\numerical_hw1.cpp°¸ EÌÌý•½¦~g†¡¹[•Í…Àk#€Qu{Q|0a®'#ÆàM¹%_ûánšF“Q‘Á®ÞÛÅ€ÁEq'‰\—ç9yq%Páðà;áy¹‰ùLx_,Xrh»qüÙ‰ÐO‰ †3JI²†Žc÷“4ˆ ‰‡oɲE³*[⦆sÓè¤Í~·Ö”?ø‘ŒK6"Á¦æF,¼JÇ1rê¼´…BžT5$_sôJäļ†Å$ý˦A:`ë5kέ'3_„}ªœRijÅ3ÎÜøsÛV:÷5ËΰãÚÓžõÌÚK¦œñÕ÷ÚßýT­vÙäÓ
upladed to the tmp directory
the problem is that the file is not moved to the current directory nor to the "upload" directory -of course when it was alone and not commented- !!
as you can see the file is uploaded successfully to the tmp directory and i have open it, and read a line from it. and also i have checked it with the is_uploaded_file function and it pass that check.
i have carefully read php file upload topics from many sites, and found nothing is missing in both php and html !!
the folder permission is 755.
i should mention here that file uploading was working before recently, and i am sure that no body has changed or modified the php.ini file.
Any Help Please?? what should i do?
after exploring the server carefully i found that my website has been hacked, and the hacker upload a hack file !
but really i don't know what to do now and also i cant estimate the damage size caused by that hacker so Any Suggestion ?!!!!
Try that:
$pathDestino=$_SERVER['DOCUMENT_ROOT'] . "\\xxx\\upload\\" . $_FILES["htmlfile"]["tmp_name"];
$tmp_name=$_FILES["htmlfile"]["tmp_name"];
move_uploaded_file($tmp_name, $pathDestino);

cross domain ajax file upload

I am using Valums Ajax Uploader (valums.com/ajax-upload) to upload files to a server. It works very well when the requesting URL and serving URL (ajax URL) are on same server but is not working when they are on different server.
Can someone please guide me about the same ?
This is a late post but hope it helps.
In your server-side (e.g php), add header defined like this:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Content-type: application/json');
if(array_key_exists('HTTP_ACCESS_CONTROL_REQUEST_HEADERS', $_SERVER)) {
header('Access-Control-Allow-Headers: ' . $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']);
} else {
header('Access-Control-Allow-Headers: *');
}
if("OPTIONS" == $_SERVER['REQUEST_METHOD']) {
exit(0);
}

Amazon AWS S3 to Force Download Mp3 File instead of Stream It

I'm using Amazon S3 to put the mp3 file then allow our site visitor to download the mp3 from Amazon AWS. I use S3Fox to manage the file, everything seems working fine until recently we got many complaints from visitor that the mp3 was streamed via the browser instead of displaying browser save dialog.
I try for some mp3 and notice that for some mp3, the save dialog box is appear, and for some others they're streamed via browser. What can I do to force that the mp3 file will be downloaded instead of streamed via web browser....
Any help would be much appreciated.
Thanks
In order to do so you need to set the Content-Disposition header:
Content-disposition: attachment; filename=song.mp3
I don't think this is possible with S3Fox. You could use Bucket Explorer (not free) or write a script to upload the files.
Ok, it's been a long time since you ask this, but I had the same problem and I'd like to share my solution with the community, just in case someone else need to solve this thing. Of course, you can change Content-Type and Content-Disposition from the Amazon S3 Console, but the interesting thing is to do it programmatically.
The following code works fine for me:
require_once '../sdk-1.4.2.1/sdk.class.php';
// Instantiate the class
$s3 = new AmazonS3();
// Copy object over itself and modify headers
$response = $s3->copy_object(
array( // Source
'bucket' => 'your_bucket',
'filename' => 'Key/To/YourFile'
),
array( // Destination
'bucket' => 'your_bucket',
'filename' => 'Key/To/YourFile'
),
array( // Optional parameters
'headers' => array(
'Content-Type' => 'application/octet-stream',
'Content-Disposition' => 'attachment'
)
)
);
// Success?
var_dump($response->isOK());
Hope it can helps other struggling with the same trouble.
This ended up being my solution for force downloading files from AWS S3.
In safari the files were downloading as .html files until I stopped returning the readfile and just ran the function alone.
public function get_download($upload_id)
{
try {
$upload = Upload::find($upload_id);
if ($upload->deleted)
throw new Exception("This resource has been deleted.");
if ($upload->filename == '')
throw new Exception("No downloadable file found. Please email info#clouddueling.com for support.");
header("Content-Description: File Transfer");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename={$upload->uploaded_filename};");
readfile("https://s3.amazonaws.com/stackoverflow/uploads/" . $upload->filename);
exit;
} catch(Exception $e) {
return $e->getMessage();
}
}
In s3 management console window, right click and chose properties.
Click on metadata.
Click on add more metadata
Key: content-disposition
Value: attachment
Save. That's all.