Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking File Path When Deleting A File

Tags:

c#

.net

asp.net

If I have a web method that deletes a file when called and it accepts three parameters (cNum, year, and fileName). Do I need to be worried about exploits of this method. The only thing I could think of would be using ..\..\..\ to drive the delete further up the folder structure. that should be pretty easy to remove that. But is there anything else that I should be worried about?

[WebMethod(EnableSession = true, 
           Description = "Method for deleting files uploaded by customers")]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public Boolean deleteCustFiles(string cNum, string year, string fileName)
{
    try
    {
        if (String.IsNullOrEmpty(cNum) 
            || String.IsNullOrEmpty(year) 
            || String.IsNullOrEmpty(fileName))
                throw new Exception();

        string path = Server.MapPath(@"~\docs\custFiles\" 
                                        + year + @"\" 
                                        + cNum + @"\" + fileName);
        File.Delete(path);
    }
    catch
    {
        throw new Exception("Unable to delete file");
    }
    return true;
}
like image 643
atrljoe Avatar asked Jan 03 '13 18:01

atrljoe


People also ask

How do I verify before deleting a file?

On the desktop, navigate to the "Recycle Bin" folder. Right-click on the Recycle Bin folder and click on the "Properties" option. "Recycle Bin Properties" window will appear on the screen. Click (select) on the "Display delete confirmation dialog" option and click on the "Apply" button to proceed.

Where do files go when you hit delete?

When you delete a file or folder, it goes into the Recycle bin, where you have a chance to restore it.

How do I track file deletions?

Reviewing events. Open the Event Viewer and search the security log for event ID 4656 with a task category of "File System" or "Removable Storage" and the string "Accesses: DELETE". Review the report. The "Subject: Security ID" field will show who deleted each file.


2 Answers

I would recommend using the GetFileName method on the Path class to cleanse the filename parameter, like so:

public Boolean deleteCustFiles(string cNum, string year, string fileName)
{
    // Cleanse fileName.
    fileName = Path.GetFileName(fileName);

The GetFileName method strips all directory information from a path, which is exactly what you want to do here.

With input like:

..\..\..\filename.ext

You would get:

filename.ext

In return, you don't have to worry about someone injecting a path which would escape the directory that you are targeting (assuming that this filename is user-input or from an open endpoint where someone could enter any input they want).

This then allows you to then append your custom path to fileName.

This only works of course if all of your files are in a pre-defined directory, which it seems it is.

This does not however, do anything to handle deleting files that a user doesn't have access to. If the files belong to another user in that directory, then there's no check here to see if that's the case (but if all users have rights to delete these files, then it's ok).

Also, you might want to use the Combine method on the Path class to combine your paths, like so:

string path = Server.MapPath(@"~\docs\custFiles\")
path = Path.Combine(path, year);
path = Path.Combine(path, cNum);
path = Path.Combine(path, fileName);

If you're using .NET 4.0 or above, you can use the overload of the Combine method that takes the parts of the path as a parameter array:

string path = Path.Combine(
    Server.MapPath(@"~\docs\custFiles\"),
    year, cNum, fileName);

Finally, as Shai points out, if possible (for a complete solution), to make this even more secure you should be enabling permissions on the file-system level.

If you are impersonating the user or using a constrained user account to handle all of the requests, then you should grant that user access to just the ~\docs\custFiles\ directory (and any sub directories).

Anything above that directory the user account should have no access to.

like image 131
casperOne Avatar answered Oct 18 '22 07:10

casperOne


It is a good idea to check the file names and directory names if they are valid file names or not, check them against this char array:

Path.GetInvalidFileNameChars

EDIT:

And you should probably also validate the year and number like this:

bool valid = int.TryParse(num, out temp);

like image 1
sharp12345 Avatar answered Oct 18 '22 08:10

sharp12345