How can protect from an attack based on PHP’s rename() method?

In the last post we showed how you can do an attack exploring the rename() PHP method.

You can look more details about rename() in PHP documentation.

Read the last post ( Hacking using “rename()” of PHP ) to better understand this post.

In essence rename() accepts two parameters, one with the old name and another with a new name.

With this parameters rename() can then change the name of files.

After understanding how we can execute an attack, we will then learn how to defend ourselves from this vulnerability .

The first thing, and one you will read all the time in my posts, there is no silver bullet or one and only solution.

There are many way to save your code when managing files.

In this post I will show you how you can protect yourself using lists without walking into other folders.

In theory you will create a list with extensions for accept or no accept type extensions.

Example code exposed:

Obs: I’m using GET method because is more simple to explain but this problem can happen in all http methods.

http://www.target.com/?oldImage=imageX.jpg

$_GET['oldImage'] = 'imageX.jpg';
<?php 
$newName = 'imageNewName.jpg';
rename( $_GET['oldImage'], $newName );
?>

Example of protect using a white list ( list of extensions that have authorization to execute, in this case rename name file );

$oldImage = basename( $_GET['oldImage'] );
$newName = 'imageNewName.jpg';
$pathFolder = '/uploads/';

$validExtensions = [
'jpg',
'jpeg',
'png'
];
$ext = pathinfo($oldImage, PATHINFO_EXTENSION);
if(in_array($ext,$validExtensions)){
rename( $pathFolder.$oldImage, $pathFolder.$newName );
}

We just need to set the folder where the system can rename files and force the return of just the name file without folders. I used basename() to get the name file without folders. And set the folder ( uploads ) to worker and force work just in folder.

In this example I set possibles extension to rename. The code said, if the file has one of the authorised extensions, you can rename the file.

Example of protecting using a black list ( list of extension that haven’t authorization, in this case can’t rename name files );

$oldImage = basename( $_GET['oldImage'] );
$newName = 'imageNewName.jpg';
$pathFolder = '/uploads/';

$invalidExtensions = [
    'php',
    'js',
    'env'
];

$ext = pathinfo($oldImage, PATHINFO_EXTENSION);
if( ! in_array($ext,$invalidExtensions) ){
    rename( $pathFolder.$oldImage, $pathFolder.$newName );
}

We set the path folder and only return the name file with basename again.

In this example I set the extension that can’t rename and change validation with “!” in the if. The code said “if the file doesn’t have one the other authorised extensions, you can rename”.

Which is more secure?

The white list, because you can have many extensions that you don’t remember that can be important to system. The white list forces you to work with only specify extensions.

Tips:

Use methods that solve your problem by you ( it is not necessary to re-invent the wheel ) like pathinfo with parameter PATHINFO_EXTENSION to return extension of name or filters like filters_var or filter_input.

I know that you can create your method to do this, but there are options to bypass some wrong defenses ( Subject of the next posts ) and the default method will think in all possibilities for you.

Obs: Many people mentioned filter_var and filter_input, filters in generally that can help protecting folder navigation.

In first time I said this will not solve everything, but I was wrong =) , yeah you can solve it with this. With filter using parameter FILTER_SANITIZE_ENCODED you will change “/” to “%2F” and you can’t walk by folders.

$oldImage = filter_var( $_GET['oldImage'] , FILTER_SANITIZE_ENCODED));

In next post I will show some wrong ways of protection and some code bypass’s.

What do you think? Do you have a bypass?

Another way to defense?

Do you would like receive briefing of next subjects? Register here.

See you in next posts folks…

Leave a Reply

Your email address will not be published. Required fields are marked *