VT : File copying security puzzler?
So here's a security potential puzzler - some of you will get it right away and others will not. Really depends on whether you have run into it in the past and it is branded into your brain, or maybe security is just first nature to you. Don't read the end and tell me at what point you figured it out. I have numbered various activities througout the blog, so tell me by number where you figured out there would be a problem (note some may be bogus!).
Scenario : At VentureTogether we want you to be able to associate an image with your profile - but of course if you choose not to, you can ignore this step. So a long time ago I created an "Images" directory under Inetpub a long time ago and it currently allows you to upload an image and saves it it the directory. This works fine for ALL users and always has done. To the present... In the case where a user did not upload a photo, a temporary "photo not uploaded" image is to be shown. Next I got a basic photo saying "person unknown" from a freebie site on the web and downloaded it and saved it on my desktop so i could quickly edit it ever so slightly [1]. Once this was done i "Cut and Pasted" the file (called "nophoto.jpg") into the "Images" folder under the Inetpub folder [2].
Next to the coding. A method called SetNoPhoto() was created in my code behind and was designed as follows:
private void SetNoPhoto(int accountID)
{
string filename = "nophoto.jpg";
//get a reference to the "no photo" image
string root = "/Glasgow/UserData/Images/Users/";
string webroot = Server.MapPath(root + filename);
try
{
//first we need to provide access to write to the folder
FileIOPermission perm
= new FileIOPermission(FileIOPermissionAccess.AllAccess,
Server.MapPath(root));
//make sure we have permission
perm.Demand();
File.Copy(webroot, Server.MapPath(root) + accountID.ToString() + ".jpg"); [xxx]
}
catch (Exception ex)
{
throw ex;
}
}
I ran the ASPX page and go an access denied for the file being created during the copy in the line maked [xxx] above [3]. So back I went and checked the parent folder permissions and even made EVERYONE have full acess, ensured the "write" checkbox was checked in IIS and clicked OK. I re-ran the page and still I got the same access denied exception [4].
Next I tried to create a text file in this method - if nothing else than to just validate i could even write to it within this method (paranoia setting in you see!). So I added the code below:
System.IO.StreamWriter sw = System.IO.File.CreateText(Server.MapPath(root) + accountID.ToString() + ".txt");
sw.WriteLine("I am a new file");
sw.Close();
Again I ran my ASPX file and guess what. The ".txt" file was successfully created and was sitting there in the folder (and i'm sure it had a wicked smile). [5] Got it yet? Bug in File.Copy?? Don't feel too stupid if you haven't got it yet - I felt pretty stupid as I should have known better having read every page of Writing Secure Code, and yep, something was certainly securing its ass off. Now the simple answer...
It was way back when you cut and pasted the file into the inetpub subfolder [6]. Had I copied the thing it would have worked fine. But i cut it. When you copy the file it will inherit the permissions of its containing folder, which would have made everything work fine. But, when you cut, it holds its permissions and hence only my computer account and one or two others could access the file. So when the ASPNET account (or anyone else for that matter) tried to access it, the were denied, So the actual error in the File.Copy() wasn't in fact access denied on the out file, it was access denied on the input file.
So should I feel stupid, or my brain just missed something? I'll guage that by the response I get, but just remember - it happens to us all at least once!
vtgo.net