I'm trying to access Apache's access log and track bandwidth usage in real time.
As we know Apache logs every request made to the server, and the log file could be as big as couple of gigabytes so it would be pretty hard for PHP to phrase the log file.
Lets say I provide users with download links with special URL prefix.
Is there a way to only log those download links? if so I could use multi-log to log those data to another log file. Multi Log
Apache config uses %u to represent the URL, is there a way to filter this?
Have php create the logfile, When people click on the link php could add to the log file and output what file to download.
<?php
/*Logging Proccess*/
$file = "Log.txt";
$to_be_logged = file_get_contents($file);
$to_be_logged .= /*Insert what you want to log like ip address or sumthing*/$_SERVER['REMOTE_ADDR']."\n";
file_put_contents($file, $to_be_logged);
/*Download Script*/
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=filetobedownloaded.rar");
?>
Put this in a file named download.php or something and
Add a file named Log.txt next to the file where this is located
This should work...
Related
When I create a TXT file with fputs(), usually it goes into the "downloads" directory, set in the browser settings. The question is how do I get the directory path of the downloaded file.
$archivo="customers.txt";
$file = fopen($archivo,"wb");
fputs($file,$contenido);
fclose($file);
header('Content-type: text/csv; charset=ansi');
header("Content-disposition: attachment; filename=$archivo");
print $contenido;
Simply put, the server is never allowed to know because the browser will never report it back. Doing so could lead to the browser leaking private information about the user without that user's consent.
Additionally, the server cannot force a user to save a file to a specific location. Again, this is for security reasons. Otherwise a server could force you to save a file to your computer's startup location.
Suppose I have a device that knows the name of a file they want to download from my server.
How can I transfer said file to that device without giving the device access to the file system?
For example, suppose I have a page ping.php which receives a get request for "something.zip"
ping.php knows the location of something.zip (somewhere on the server's file system), but I can't allow the user access to the file system, or allow them to know the location of the file (it even needs to be hidden from somebody using something like wireshark).
How can I solve this problem?
It might be an easy solution, I'm just not extremely well versed in these matters.
If it makes any difference I'll be using an Apache server on a Linux box.
You can create a PHP script to facilitate the file transfer while the file is sitting in a folder that is not accessible via the Web. This is how I commonly handle file downloads on my system.
There are any number of sample scripts that you may use to do the actual file transfer. The key is to put that file outside the web-accessible file system.
For completeness, here's some code I've used in the past to do a file download in PHP:
$filename="filetodownload.xyz";
$cf = realpath("/non-webaccessible-folder/".$filename);
$file=$cf;
header('Content-Disposition: attachment; filename="' . basename($cf) . '"');
header("Content-Length: " . filesize($cf));
header("Content-Type: application/octet-stream");
readfile(realpath($cf));
I made an upload form and stored files in (root) '../upload_file' folder
the problem is how authorized (logged in) user only can download that uploaded files? because browser cant handle root url like: www.web.com/../upload_file/test.pdf
please Im newbie
thanks :D
Ok, I want make this clear. Actualy my question is similar to: How to go about protecting files from unauthorized downloads
where is unsolved
You need to create a php script that will authenticate the user and then output the contents of the uploaded file in the php script. Make sure you do not echo anything out before setting the headers of the output file. There should be code somewhere on how to load the contents of a file into a variable.
$fileContents = file_get_contents("test.pdf");
header("Cache-Control: public, must-revalidate");
header("content-disposition: attachment; filename=test.pdf");
header("content-type: application/pdf");
header("content-length: " . strlen($fileContents));
//output file contents
echo $fileContents;
The users should never have access directly to the upload folder.
Access control depends on your server operating system and server, like Windows Server(IIS) or Linux(Apache, Ngix)...
The best way to protect the files from being visted from URL is to set the upload path outside your webroot.And the file will be only accessiable by your server.
UPDATE: how to access files by user
Create a php file named readpdf.php.
header("Content-type:application/pdf");
//if you just want to show the file on broswer, delete the line below
header("Content-Disposition:attachment;filename='downloaded.pdf'");
readfile("progit.pdf");
Read the file by visiting http://localhost/readpdf.php
I'm making a website that allows users to upload any kind of files. All the files are stored in a 'files/' folder. I want users to be able to see and download any of the files in that folder, but not execute them.
Some files, like JPG files, are easy: browsers have a built in system to display them, as we all know.
Other files, like PDF files, cannot be displayed directly, so what browsers do is prompt the user a download screen. Thats fine too.
However, other files, like PHP files, pose a problem. When I open one such file, if I am not careful, it gets executed. For example, if the file contains
<?php echo 'ok'; ?>
then when I go to 'files/myphpfile.php', what I see is just 'ok', and not the contents of the file. This will happen not only with PHP files, I presume, but also with any other file types that my server can execute (for example ASP files, I suppose).
What I need is to prevent users from executing the files, so that when they go to 'files/myphpfile.php', they either see the file contents, or the browser prompts them the download screen. Ideally it would be a general solution, that would not require me to construct a list of every file type executable by the server.
To me, the most reasonable approach was to set the file permissions to 644, so that users could only read the files. But after doing so, the PHP files keep getting executed.
To download:
header('Content-Type: text/plain');
header('Content-Disposition: attachment; filename=somefile.php');
header('Pragma: no-cache');
readfile('/path/to/somefile.php');
To display:
echo htmlspecialchars(file_get_contents('/path/to/somefile.php'));
UPDATE
When I open one such file, if I am not careful, it gets executed
That's why you don't have a direct link to the file. I.e. the files should not get uploaded to a location somewhere inside the document root. If the files are uploaded to a directory outside the document root people cannot access it directly by URL, e.g.: http://example.com/files/somefile.php.
This will happen not only with PHP files, I presume, but also with any other file types that my server can execute (for example ASP files, I suppose).
You are the only one who can tell what files may be dangerous. We cannot know whether you have some server which also serves (and parses) asp files nor what other potential dangerous files may be on there.
What I need is to prevent users from executing the files, so that when they go to 'files/myphpfile.php', they either see the file contents, or the browser prompts them the download screen.
See my already provided solutions above.
To me, the most reasonable approach was to set the file permissions to 644, so that users could only read the files. But after doing so, the PHP files keep getting executed.
This is because PHP files are not getting executed. They are only being parsed (i.e. being read by the webserver).
So basically you need to find out what are the possible dangerous file types (also think about other files that may get parsed by PHP e.g. .phtml or what not). Users shouldn´t be able to call executables anyway through a HTTP request. Because when I would do http://example.com/run-virus.exe it never gets executed on the server, but it only requests the file.
I solved the problem by displaying the files through a script, and not directly from their real location. The script was taken from an answer to a previous question of mine.
$fileinfo = finfo_open( FILEINFO_MIME_TYPE );
header( 'Content-Type: ' . finfo_file( $fileinfo, 'files/' . $filename ) );
finfo_close( $fileinfo );
readfile( 'files/' . $filename );
So now users that want to see 'files/myfile.php' must go to 'open/myfile.php', and the script above will prompt them the download screen, or display the file in the browser, if the browser is able to do so.
I'm trying figure out how I can protect digital downloads in PHP. Just need some general directions so I can start my research. I don't seem to be able to find anything useful.
I want to make files available for my users to download but don't want them to be able to directly access a download folder. Also, I want the download link to be available only for set period of time or a single download.
Could some one point me in the right direction?
The best way is to delegate the download managment after your check to the mod for apache
x_sendfile
https://tn123.org/mod_xsendfile/
Usage:
<?php
...
if ($user->isLoggedIn())
{
header("X-Sendfile: $path_to_somefile");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$somefile\"");
exit;
}
?>
<h1>Permission denied</h1>
<p>Login first!</p>
Basically when you send the header X-Sendfile the mod intercepts the file and manages the download for you (the file can be located whenever you want outside the virtualhost).
Otherwise you can just implement a simple file download.php that gets the id of the file and prints the contents with readfile after the login check
Just some examples: You can place your files outside of the webserver's document root or in a directory that is protected by a .htaccess file with a "deny from all" rule; then you deliver the files by a custom PHP function that sets the correct headers (mime-type, filesize etc.) and returns the file.
You could create links with unique id's based on MD5 or SHA1 hashes - a mod_rewrite rule points the id to your PHP file, you lookup the id in the database and do your time checks, like
example.com/downloads/73637/a8d157edafc60776d80b6141c877bc6b
is rewritten to
example.com/dl.php?id=a8d157edafc60776d80b6141c877bc6b&file=73637
Here's an example of doing something you want with nginx and PHP:
http://wiki.nginx.org/HttpSecureLinkModule
"Secure Download Links", a PHP Script can be used to hide download url or rename download file, it has option for storing below web root and for files stored above webroot that is with absolute http urls also.