The whole index.php?=<filename>.exe - php

I've never really understood on how to do it. I want to where where I can type my address, followed by /index.php?=<a file that is on the FTP>.exe. From there, I would be direct to a page that has a download now button and maybe something like a ad.
Anyone have any tutorials or guides that I may look at?

Im gonna bite ...
The PHP script ensures the file is not accessible from the outside, and only on a per-request basis with possible authentication. When you see:
download.php?file=sdjasdk.exe
The download script looks a bit like:
<?php
if( $_SESSION['auth'] == TRUE){
$file = fileopen($whatever);
echo "mimetype crap"
//spit out file
}else{
echo "not authorized bozo"
}
?>
DOne.

I think he is on about simple $_GET requests >.<
<?php
$file = $_GET['file'];
if (file_exists($file)) {
header('Content-Type: application/octet-stream');
echo file_get_contents($file);
}
?>
Ofcourse this is a very basic example with no security at all. Its not reccomended for you to use this in production without upping security on it.

Related

How do I use HTML5 to download from a non web folder?

I have a webpage for that is for internal use only. It is going to be hosted on a server that is primarily running other processes that generate log files in the /opt/appname/logs/ dir. I have been tasked with making a web interface that will allow these log files to be downloaded to any computer on our network. I am using Apache on Debian. This is what I have so far:
<details>
<summary><b>Download Log Files</b></summary>
<?php
foreach (glob("/opt/appname/logs/*.log") as $filename) {
$file_info = explode("/logs/", $filename);
?>
<a href="<?php echo $filename ?>" download><?php echo $file_info[1] ?></a>
<br>
<?php } ?>
</details>
When I try and download a log file the download looks like it starts but then gives me the message "Failed No file". I have found many posts on line that say you can or can't do this but none of them provide adequate examples. I realize that there are issues with accessing anything outside of the web folders but there has to be some way to do this. I am really at a loss here so any suggestions would be great. Lastly I am self taught so if you see any errors or things that I am not doing best practice please let me know. I am always trying to improve.
It's a security related thing, that only files which are in certain paths on the server can be accessed by a browser, so there should not be a 'simple' solution to this.
What you can do:
Define an alias to the path or file in your web server configuration
or
Write a small program which is called instead and which reads the file from the desired location and send it as output.
In the latter case, you should remember that giving the path via parameters is like an open door for all those who like to read all files on your server!
You could create a file download.php. This file can look something like:
Download.php
$fn = $_GET["filename"];
if (is_readable($fn)) {
header('Content-Description: File Transfer');
header('Content-Type: text/plain');
header('Content-Disposition: attachment; filename="'.$fn.'"');
readfile($fn);
} else {
//return a 404 error perhaps.
}
You could then modify your original listing code to:
<details>
<summary><b>Download Log Files</b></summary>
<?php
foreach (glob("/opt/appname/logs/*.log") as $filename) {
$file_info = explode("/logs/", $filename);
?>
<a href="download.php?filename=<?php echo $filename ?>" download><?php echo $file_info[1] ?></a>
<br>
<?php } ?>
</details>
I personally like this method because you can also add extra checks and exceptions in the "download manager".

readfile() not working with remote resources

So I came at a little problem with a project of mine. We have a bulky server with lots of space as well as a light static storage server that can only be used to store things. We need to make sure only the people who are authenticated can access the resources on the static server, so I thought about making a psuedo-proxy out of readfile(), as we can use allow_url_fopen.
So I tried the following code as a test:
<?php
$type = "video/webm";
$loc = "http://a.pomf.se/fzggfj.webm";
header('Content-Type: '.$type);
header('Content-Length: '.filesize($loc));
readfile($loc);
exit;
This always fails, the browser reads this as corrupted. Interestingly, when you do this:
<?php
$type = "video/webm";
$loc = "../test.webm";
header('Content-Type: '.$type);
header('Content-Length: '.filesize($loc));
readfile($loc);
exit;
It does work, even though the file is the exact same. Does anyone know why readfile will not do this correctly, and explain this to me?
EDIT:
I got the error message from it, it was stuck in the file.
Warning: filesize(): stat failed for http://a.pomf.se/fzggfj.webm in C:\uniform\UniServerZ\www\director.php on line 5
Is filesize() my problem here?
Ok I fixed it. deceze was correct, and filesize was the issue. Let the record show that filesize doesn't work on remote resources I guess.
You need to activate allow_url_fopen by adding allow_url_fopen=1 in your php.ini.
why You aren't downloading video to temporary directory and redirect user to there? (of course You can clear outdated tmp dir later with cron script)
try this:
<?php
$loc = "http://a.pomf.se/fzggfj.webm";
$pathToVideos = dirname(__FILE__).'/tmp/';
$ext = explode('.', $loc);
$ext = end($ext);
$hash = md5($loc);
$filename = $hash.'.'.$ext;
$tmpFile = $pathToVideos.$filename;
if(!is_file($tmpFile)) {
exec('wget -O '.escapeshellarg($tmpFile).' '.escapeshellarg($loc));
}
header('Location: /tmp/'.$filename);
exit(0);

Protect PDF docs from being directly accessed in URL

I want to protect a pdf file from being directly linked but instead have my logged in users be able to access it. I have a link which currently goes to a javascript function which posts a form:
$('nameofdoc').setProperty('value',doc);
document.getElementById('sendme').submit();
where sendme is the name of the form and nameof doc the index of the document I want to display.
This then goes to a php file:
$docpath = $holdingArray[0].$holdingArray[1];
$file = $holdingArray[0]; //file name
$filename = $holdingArray[1]; //path to the file]
header( 'Location:'.$docpath ) ;
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="'.$filename . '"');
readfile($filename)
This all works fine it loads up the file and outputs the pdf. What I can't do is protect the directory from direct linking - ie www.mydomain.com/pathToPdf/pdfname.pdf
I've thought of using .htaccess to protect the directory but it's on a shared host so I'm not sure about the security and anyway when I've tried I can't get it to work.
Any help would be great since this is my fourth day of trying to fix this.
thanks
Update
I've had a lot of help thank you but I'm not quite there yet.
I've got an .htaccess file that now launches another php file when a pdf is requested from the directory:
RewriteEngine on
RewriteRule ^(.*).(pdf)$ fileopen.php
When the fileopen.php file lauches it fails to open the pdf
$path = $_SERVER['REQUEST_URI'];
$paths = explode('/', $path);
$lastIndex = count($paths) - 1;
$fileName = $paths[$lastIndex];
$file = basename($path);
$filepath = $path;
if (file_exists($file)) {
header( 'Location: http://www.mydomain.com'.$path ) ;
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=".$file);
readfile($filepath);
}else{
echo "file not found using path ".$path." and file is ".$file;
}
The output is
file not found using path /documents/6/Doc1.pdf and file is Doc1.pdf
but the file does exist and is in that direcotry - any ideas??
OKAY I'm happy to report that Jaroslav really helped me sort out the issue. His method works well but it is tricky to get all the directory stuff lined up. In the end I spent a few hours playing about with combinations to get it working but the principle he gave works well. Thanks
The best way would be to protect that folder with htaccess, as you have mentioned. So you put all PDFs in pdf/ folder, and in the same pdf folder you out .htaccess file:
RewriteEngine on
RewriteRule .* your-php-script.php
Now no files can be accessed by url in this folder. Every request to every file in this folder will return what your-php-script.php script returns. In your-php-script.php you do something like this:
//Check if user has right to access the file. If no, show access denied and exit the script.
$path = $_SERVER['REQUEST_URI'];
$paths = explode('/', path);
$lastIndex = count($paths) - 1;
$fileName = $paths[$lastIndex]; // Maybe add some code to detect subfolder if you have them
// Check if that file exists, if no show some error message
// Output headers here
readfile($filename);
Now if user opens domain.com/pdf/nsa-secrets.pdf Apache will run your-php-script.php. Script will have variable $_SERVER['REQUEST_URI'] set to "domain.com/pdf/nsa-secrets.pdf". You take the last part (filename) and output it to a user (or not).
This will stop anyone from accessing files directly from the internet by knowing URL. If someone has direct access to files on your server, that will not stop them. On the other hand, I think any shared hosting stops users from getting files of other clients. Only way to do it is to hack the server in some way. But then we are getting very paranoid and if that may be a case for you, you shouldn't use shared hosting in the first place.
If you cannot make htaccess work, you can try to obfuscate files, so it would be difficult to spot them for someone outside. For example change file from mySecretData.pdf to djjsdmdkjeksm.pdf. This may help a little bit.
I want to protect a pdf file from being directly linked but instead have my logged in users be able to access it.
Check to ensure there is an authenticated user before streaming the PDF's content.
This is kinda sloppy but it could work assuming you can setup a MYSQL DB. It lets you pass the "password" in the URL as an MD5 string or as a clear text if you want to. Trying to setup some kind of security without using htaccess or an existing frame work is kinda clunky. This however won't even attach the file to the stream until it knows you've been "Authenticated" I think you could maybe make this a little better if you setup a login page that saved a cookie locally then you wouldn't need to pass the "passphrase" in the URL.
$file = $_GET['file'];
$pass = $_GET['pass'];
$download_folder = '../Protected';
$file = basename($file);
$filepath = "$download_folder/$file";
if (file_exists($filepath)) {
if(CheckUser($pass)){
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=$file");
session_write_close();
readfile($filepath);
} else {
echo 'Not Authenticated!';
}
} else {
echo 'No File!';
}
function CheckUser($value){
$con = mysqli_connect("test.com","test","123456","my_db");
// Check connection
if (mysqli_connect_errno()){
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT user FROM pass_table WHERE password =".md5($value).";");
while($row = mysqli_fetch_array($result)){
mysqli_close($con);
//return $row['user'];
if($row['user']){
return true;
}
}
mysqli_close($con);
return false;
}

"ifelse" command in the "include"

where in error?
<?
if($_GET['data'])
{
print 'atmam';
include ('http://downloads.website.com/download/3725f5eea93437e9de52f9b15854f5c1');
}
else {
print 'fail to download'; }
?>
Written on the screen error:
Warning: Unexpected character in input: '' (ASCII=1) state=1 in http://downloads.website.com/download/3725f5eea93437e9de52f9b15854f5c1 on line 515
Parse error: syntax error, unexpected T_STRING in http://downloads.website.com/download/3725f5eea93437e9de52f9b15854f5c1 on line 515
PS: http://downloads.website.com/download/3725f5eea93437e9de52f9b15854f5c1 = direct file download link
Can you help?
Best regards
See if this does something like what you want:
<?php
if ($_GET['data']) {
// Some headers that indicate a generic download
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment');
// Try and read the file directly to the client
if (!#readfile('http://downloads.website.com/download/3725f5eea93437e9de52f9b15854f5c1')) {
// Try and clear the header and print a message. This may not work depending on the result of the readfile() attempt.
#header('Content-Disposition:');
print 'fail to download';
}
exit;
}
?>
An alternative (and many would argue better) approach is this:
<?php
if ($_GET['data']) {
// Redirect the client to the actual location
header('HTTP/1.1 302 Found');
header('Location: http://downloads.website.com/download/3725f5eea93437e9de52f9b15854f5c1');
exit;
}
?>
PHP provides a function called file_exists for this purpose. $_GET['data'] is for getting information out of the html element with name="data" attached to it. If you do not have this in your document the script will NEVER run as its looking for something that doesn't exist. Even if the element does exist, this is not a necessary nor recommended use of $_GET.
To find out more about what you're trying to do check this link, and look at my examples.
http://php.net/manual/en/function.file-exists.php
To use it you simply do this:
$filename = 'http://downloads.website.com/download/3725f5eea93437e9de52f9b15854f5c1';
if (file_exists($filename)) {
echo 'atmam';
include ('$filename');
}
else
echo 'Failed to download file';
I'm assuming you are going to use this for any files your site has to access, to save you time you can use it in a function.
function testfile(filename) {
if (file_exists(filename)) {
echo 'atmam';
include ('filename');
}
else
echo 'Failed to download file';
}
Call the function like this:
$filename1 = 'http://downloads.website.com/download/3725f5eea93437e9de52f9b15854f5c1';
$filename2 = 'something.txt';
function testfile($filename1);
Using the function you can check as many file names as you want using variables for each file name.
Edit: To solve the syntax error that is coming up, you must make sure the file being included has no errors. Please post it here for us to look at. Removing echos and prints will change nothing, in fact you want those in there in order to debug. First try using the small bit of code I've put here, this is the correct method to check if a file exists, and if it does, do something. Once you are using the correct code to check the file and include it, then you will be sure that once you fix any issues in the include file you are going to have the functionality you want.
Hope this helps you out!
-Sean

Include whole content of a file and echo it

I need to echo entire content of included file. I have tried the below:
echo "<?php include ('http://www.example.com/script.php'); ?>";
echo "include (\"http://www.example.com/script.php\");";
But neither works? Does PHP support this?
Just do:
include("http://www.mysite.com/script.php");
Or:
echo file_get_contents("http://www.mysite.com/script.php");
Notes:
This may slow down your page due to network latency or if the other server is slow.
This requires allow_url_fopen to be on for your PHP installation. Some hosts turn it off.
This will not give you the PHP code, it'll give you the HTML/text output.
Shortest way is:
readfile('http://www.mysite.com/script.php');
That will directly output the file.
Echo prints something to the output buffer - it's not parsed by PHP. If you want to include something, just do it
include ('http://www.mysite.com/script.php');
You don't need to print out PHP source code, when you're writing PHP source code.
Not really sure what you're asking, but you can't really include something via http and expect to see code, since the server will parse the file.
If "script.php" is a local file, you could try something like:
$file = file_get_contents('script.php');
echo $file;
This may not be the exact answer to your question, but why don't you just close the echo statement, insert your include statement, and then add a new echo statement?
<?php
echo 'The brown cow';
include './script.php';
echo 'jumped over the fence.';
?>
Matt is correct with readfile() but it also may be helpful for someone to look into the PHP file handling functions
manual entry for fpassthru
<?php
$f = fopen($filepath, 'r');
fpassthru($f);
fclose($f);
?>

Categories