Jump to content

Empty .txt is downloaded


afterfx

Recommended Posts

Hello guys, i do not have very good PHP knowledge so go easy on me :)

 

So I am building this site, where users can create files (for now only text files)

 

Creating file is done and works, now I want to add function to download the file, my code so far

<?php
error_reporting(E_ALL);
$file = $_GET['file'];
if(file_exists('users/'.$_COOKIE['username'].'/files'. '/' .$file)) {
	header('Content-Type: text/plain');
	$content = file_get_contents('users/' . $_COOKIE['username'] . '/files' . '/' .$file);
	//var_dump($content);
	//die();
	header('Content-Disposition: attachment; filename="'.$file.'"');
	readfile($file);
} else {
	echo "File does not exists!";
}

?> 

I have 5 files 1.txt 2.txt 3.txt ... 5.txt.
Download part works alright, but the file downloaded is blank
If i var_dump the file i get the following : string(4) "Five" for the 5.txt and string(3) "Two" for the 2.txt

 

I know that the code is awful to look but I am not that experienced in coding.
Am I missing some headers?

Link to comment
Share on other sites

I see you're doing users/$username/files/$file in that one if condition, then again when you get $content. That's the full path to the file, right? You aren't doing that with the readfile...

 

There's a much, much more significant problem with your code: I can use it to download any file I want from your server, and all I have to do is change the ?file= in the URL. Consider what would happen if I did

?file=../../../script.php
That means your code would look for

users/$username/files/../../../script.php -> script.php
?file isn't the only part that's risky, either. Cookies can be edited by the user, so when you put the username in one I can change it to whatever value I want. Besides using that to mess around with the file path, I bet I could use it to any username I wanted.

 

Here's what you need to do:

 

1. Fix the username problem. Store your data in sessions instead of in cookies, because session data cannot be edited by the user. You'll need to fix this on the rest of your site too.

2. Make sure that the ?file is a safe value. For example, you can make sure that it's just a filename by using basename. This is also something that you'll probably have to change in other places.

3. You also need to make sure that the ?file is even present in the first place. If not your code will do some odd things. Use isset for that.

 

Unrelated,

4. You should not need to change error_reporting in your scripts. Set it globally with your PHP configuration (however that works) and you'll never have to think about it again.

 

After all those changes, your script should look more like

<?php

session_start(); // required to use session data

if (isset($_GET['file'])) { // make sure ?file is present
	$file = basename($_GET['file']); // strip everything except the final filename portion
	$path = 'users/' . $_SESSION['username'] . '/files/' . $file; // create a variable for this instead of repeating it everywhere
	if (is_file($path)) { // file_exists checks if the $path exists *even if it's not a file*. use is_file instead
		header('Content-Type: text/plain');
		header('Content-Disposition: attachment; filename="' . $file '"');
		readfile($path);
		exit; // stop executing code. header + readfile + exit often come as a trio with download scripts
	} else {
		echo 'File does not exist!';
	}
} else {
	echo 'File name missing!';
}
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.