My script:
$secret = check_input($_GET['secret']);
if(isset($_POST['register'])) {
if (isset($secret) || !empty($secret)) {
if (file_exists(ROOT . '/intl/codes/' . $secret)) {
unlink(ROOT . '/intl/codes/' . $secret);
$trusted = 'yes';
} else {
$trusted = 'no';
}
}
//$_POST['register'] register details...
}
$secret
doesn't exist in the /codes/
folder, it produces Warning: unlink Is a directory
How to get rid of that?$trusted
always gives yes
even if the file doesn't exist ?To delete a directory, you should be using rmdir()
instead of unlink()
.
$secret = check_input($_GET['secret']);
if(isset($_POST['register'])) {
if (!empty($secret)) {
if(file_exists(ROOT . '/intl/codes/' . $secret)) {
rmdir(ROOT . '/intl/codes/' . $secret);
$trusted = 'yes';
} else {
$trusted = 'no';
}
}
//$_POST['register'] register details...
}
Although, there is a serious security risk here! If your check_input()
does not properly sanitize $secret
, you could rmdir('/intl/codes/../')
which is the same as deleting /intl/.
Try something like this:
$allowed = ROOT. '/intl/codes/';
$path = realpath($allowed . check_input($_GET['secret']));
if(strpos($path, $allowed) === 0) { //Check that $path is within allowed directory
if(is_dir($path)) {
rmdir($path);
} else if(file_exists($path)) {
unlink($path);
} else {
echo "File/folder not found";
}
} else {
echo "Untrusted user tried to delete outside of allowed directory";
}
You can use just if (!empty($secret))
- empty()
returns TRUE
for NULL
value as well.
Use if (file_exists(ROOT . '/intl/codes/' . $secret) && !is_dir(ROOT . '/intl/codes/' . $secret))
to check if your file is not a directory and get rid of that warning. If you still wanna remove the directory, use rmdir()
function.
file_exists()
returns TRUE
for directories as well. So, you should also check if the argument is a directory with is_dir()
, as i said before.
if (file_exists(ROOT . '/intl/codes/' . $secret)) {
unlink(ROOT . '/intl/codes/' . $secret);
$trusted = 'yes';
} else {
$trusted = 'no';
}
Is there another way to do it (more simplier, etc.)?
No, Only way is to use file_exists
If $secret doesn't exist in /codes/ folder, it produce Warning: unlink Is a directory How get rid of of that?
It seems $secret
points to a directory. The execution path reaches to unlink
because if
part returns true. So it exists. To delete a directory use rmdir()
Why $trusted always give's yes even if file doesn't exist ?
Because unlink
deletes it and sets $trusted
to yes
. When you search after deletion you see it doesn't exist but $trusted
contains yes
Obviously your $secret
is an empty string, but it's passing your isset()
test.
So the directory ROOT . '/intl/codes/'
does exist (thus passing file_exists()
check), but you can't unlink()
the directory (neither is it your intention here).
Make sure that you have something non-empty in $_GET['secret']
and verify your check_input()
function.
P.S. You probably should remove isset($secret)
part of the condition. !empty($secret)
is enough here and it will fix your script.
as stated by php documentation about file_exists()
:
Checks whether a file or directory exists
My only guess for your question #3 is: You check if file exists and it does. Only, it's not file, it's directory.
as for #2, also as stated by the error message, you can do something like this:
$file_to_check = ROOT . '/intl/codes/' . $secret;
if (file_exists($file_to_check)) {
if( !is_dir( $file_to_check ) )
unlink($file_to_check);
else
rmdir( $file_to_check );
$trusted = 'yes';
}
and for your #1 question, you might one to do something like this:
$secret = input_get($_GET['secret']);
if(isset($_POST['register']) && !empty($secret)) {
$file_to_check = ROOT . '/intl/codes/' . $secret;
if (file_exists($file_to_check)) {
if( !is_dir( $file_to_check ) )
unlink($file_to_check);
else
rmdir( $file_to_check );
$trusted = 'yes';
} else {
$trusted = 'no';
}
}
function input_get($key, $default = ""){
if(!isset($_GET[$key])){
return $default;
} else {
//do input cleanup first, if you want
return $_GET[$key];
}
}
A little bit of explanation:
check_input()
does, so I created wrapper function for $_GET[]
called input_get()
. It removes the need to do isset()
and also fill in the default value.ROOT . '/intl/codes/' . $secret;
into variable $file_to_check
so that you don't have to type it again and again.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With