Delete file using unlink

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
samdufeu
Forum Newbie
Posts: 1
Joined: Fri Aug 12, 2011 5:42 am

Delete file using unlink

Post 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
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: Delete file using unlink

Post 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?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Delete file using unlink

Post 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.
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: Delete file using unlink

Post 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.
Post Reply