how to support delete of <directoryname> as well as <directoryname>/

M

mike

Hi,

We are using a perl script to delete file/folder in apache ( cgi-bin).

When we do a delete with and url that ends with <directoryname>/ the
delete is performed.
However when we use only <directoryname> without the slash then we get
the response saying,
Directory permanently moved.

This is the perl-script we are using ( see below). Any hints on what
we have been missing out?
----------------------------------
#!/usr/bin/perl

use warnings;

use File::Basename;
use File::path;

#Very simple delete handler implementation.
#Note: This script should be used securely.
# A simple log file, must be writable by the user that this program
runs as.
# Should not be within the document tree.
$deletelog = "/tmp/delete1.log";
my $files_deleted = 0;

# Check we are using PUT method
if ($ENV{'REQUEST_METHOD'} ne "DELETE") { &reply(500, "Request method
is not DELETE"); }

&log("Request is DELETE");

# Note: should also check we are an authentication user by checking
# REMOTE_USER

# Check we got a destination filename
$filenamein = $ENV{'PATH_TRANSLATED'};
if (!$filenamein) {
&reply(500, "No PATH_TRANSLATED");
}

my($filename, $directories) = fileparse($filenamein);

&log("Filename : $filename \n");
&log("Directory : $directories \n");

if(! $filename) {
#we are deleting a directory remove the tree in quiet mode
$files_deleted = rmtree($directories);

&log("Number files deleted in $directories : $files_deleted\n");
} else {
#delete a file
&log("Will remove single file : $filenamein\n");
if(unlink($filenamein) == 0) {
&reply(500, "Cannot delete unknown $filenamein");
}
}

# Everything seemed to work, reply with 204 (or 200). Should reply
with 201
# if content was created, not updated.
&reply(200);

exit(0);
------------------------
 
T

Tad J McClellan

We are using a perl script to delete file/folder in apache ( cgi-bin).

When we do a delete with and url that ends with <directoryname>/ the
delete is performed.
However when we use only <directoryname> without the slash then we get
the response saying,
Directory permanently moved.


Is that the actual message (copied/pasted) or a paraphrasing
of the message?

Did the directory get removed in this case?

This is the perl-script we are using ( see below). Any hints on what
we have been missing out?


fileparse() does not know what are directories and what are files.
That is, it does not look at the actual filesystem, it simply parses
the string that is passed to it. If passed:

/tmp/i_am_a_directory

It does not know that the final component is a directory. It only
knows that it is the final component in the path.



You should also have

use strict;

in all of your Perl programs.

&log("Request is DELETE");


You should not use ampersands on subroutine calls unless you know
what it does, and what it does is what you want to do (it seldom is).

log("Request is DELETE");

# Note: should also check we are an authentication user by checking
# REMOTE_USER


That is not secure you know...

# Check we got a destination filename
$filenamein = $ENV{'PATH_TRANSLATED'};
if (!$filenamein) {
&reply(500, "No PATH_TRANSLATED");
}


That may or may not be a real path you know (google it)...

if(! $filename) {
#we are deleting a directory remove the tree in quiet mode
$files_deleted = rmtree($directories);

&log("Number files deleted in $directories : $files_deleted\n");
} else {
#delete a file
&log("Will remove single file : $filenamein\n");
if(unlink($filenamein) == 0) {
&reply(500, "Cannot delete unknown $filenamein");
}
}


Since you cannot rely on either PATH_TRANSLATED nor $directories
being a real path, your code should check if it is a real path itself:

# untested
my $path = $ENV{'PATH_TRANSLATED'};
if ( -d $path) { # delete a directory
$files_deleted = rmtree( $path );
log("Number files deleted in $path : $files_deleted\n");
}
elsif ( -f $path ) # delete a file
log("Will remove single file : $path\n");
reply(500, "Cannot delete unknown $path" unless unlink $path;
}
else {
reply(500, "'$path' is neither a directory nor a file");
}


What you are trying to do is fraught with danger, and problems
still exists even with my code above.

I predict disaster...


You need real authentication, else crackers will delete your website.

There is a race condition in my code above.
 
P

Peter J. Holzer

We are using a perl script to delete file/folder in apache ( cgi-bin).

When we do a delete with and url that ends with <directoryname>/ the
delete is performed.
However when we use only <directoryname> without the slash then we get
the response saying,
Directory permanently moved.

You mean "301 Directory permanently moved." (the numeric code is an
important - often the most important - part of the HTTP response).

Most likely that reponse comes from the server.

"http://www.example.com/directoryname" and
"http://www.example.com/directoryname/" are two different resources,
which must be treated differently. However, if "http://www.example.com/"
refers to a filesystem, and "directoryname/" refers to a directory in
that filesystem, then "http://www.example.com/directoryname" cannot
exist. Since users often omit the / at the end, most (all?) webservers
check for this case. "Let's see - the client requested "/directoryname",
but that doesn't exist. But I do have "/directoryname/", so it probably
wanted that. So I'll send a 301 response instead a 404 response".

This check probably happens before your script is called.

hp
 
P

Peter J. Holzer

That is not secure you know...

REMOTE_USER is set by the web server. You don't know how the web server
determined the remote user, so you cannot know whether it is secure.
Basic auth over an unencrypted connection is insecure, of course. Basic
auth over https cannot be sniffed on the network (but the user may have
a weak password, or a keylogger on his machine). Https with Public key
crypto where the private key is stored in key hardware token on the
user's side is very secure.

However, checking for REMOTE_USER is often futile: If the user wasn't
authenticated or isn't authorized to run the script, the script isn't
even called.

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top