Page 1 of 1

Delete file using unlink

Posted: Fri Aug 12, 2011 5:47 am
by samdufeu
Hi,

I've set up a little upload script and was adding into it a delete function as well...
Basically im trying to parse the following:

Code: Select all

<a href="removefile.php?file=files/<?php echo $filename;?>" title="Delete file '<?php echo $filename;?>' from the server">Delete</a>
I know 'filename' works as I call the filename in a table before this for each individual filename and my output works when i post it to removefile.php i would get a url such as http://www.baseurl.com/removefile.php?f ... 20card.zip - also my alt tag is working.

Inside removefile.php i have:

Code: Select all

<?
if(isset($_POST['$filename'])){ 
unlink($_POST['$filename']); 
}
?>
I am pretty sure this shuldn't be complex? The files are in the same directory as the remove script for the time being as well..

Any help would be appreciated.

Thanks
sam

Re: Delete file using unlink

Posted: Fri Aug 12, 2011 11:09 am
by Jonah Bron
Your removefile.php has some issues. First, you need to use $_GET, not $_POST. GET data is in the URL in the query string (everything after "?"). Next, change the index from '$filename' to 'file'. That's the name of the value you want.

Code: Select all

<?php
if(isset($_GET['file'])){
    unlink($_GET['file']);
}
?>
You also have a major security issue here. What if someone called this?

http://example.com/removefile.php?file=removefile.php

Or even worse, this?

http://example.com/removefile.php?file=.

You have to make sure that only files in the directory you specify can be deleted. Here's how to do that:

Code: Select all

<?php
if(isset($_GET['file'])){
    $filename = 'files' . ltrim($_GET['file'], '/\\');
    // make sure only deleting a file in files/ directory
    if (dirname(realpath($filename)) == realpath('files')) {
        unlink($filename);
    }
}
?>
To accommodate these changes, you need to change the first page a bit.

Code: Select all

<a href="removefile.php?file=<?php echo $filename;?>" title="Delete file '<?php echo $filename;?>' from the server">Delete</a>
I removed the files/ part from the URL. This means that removefile.php will decide where to delete the file from, not the URL.

That will make sure that no-one can delete a file outside of the specified directory. realpath() calculates the absolute path of a file/directory name. dirname() get the parent directory of that, and basename() just gets the folder name. Basically, we're just making sure the parent of the file is the one we're expecting.

Other measures need to be taken to make sure that you can't just delete files without permission. Will this be on a live site?

Re: Delete file using unlink

Posted: Fri Aug 12, 2011 11:28 pm
by Weirdan
Jonah Bron wrote:Your removefile.php has some issues. First, you need to use $_GET, not $_POST.
Uhm, no. GET requests should cause no destructive side effects (ideally, no side effects whatsoever). You don't want google bot, or just any smart browser that prefetch links to delete your files without you clicking anything, do you?

Of course your points on input validation still hold true.

Re: Delete file using unlink

Posted: Sat Aug 13, 2011 10:17 am
by Jonah Bron
That was an accommodation to the link he had. We obviously wouldn't want random visitors deleting files, now would we? :) I figured that we shouldn't go too complicated until we find out whether or not it's actually on a public server, or just a personal project.