.NET Framework 2.0 Security Guidelines - File I/O

From Guidance Share

Jump to: navigation, search

- J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Chaitanya Bijwe


Contents

Avoid untrusted input for file names and file paths

Avoid writing code that accepts file or path input from the caller. Instead, use fixed file names and locations when your code reads and writes data. This ensures that your code cannot be coerced into accessing arbitrary files. Also avoid making security decisions based on user-supplied filenames.


If you accept file names, validate them

If you do need to receive input file names from the caller, make sure that the file names are strictly formed so that you can determine whether they are valid. There are two aspects to validating input file paths. You need to:

  • Check for valid file system names.
  • Check for a valid location as defined by your application's context. For example, are the file names within the directory hierarchy of your application?

To validate a path and file name, use the System.IO.Path.GetFullPath method as shown in the following code example. This method also canonicalizes the supplied file name.

using System.IO;
public static string ReadFile(string filename)
{
 // Obtain a canonicalized and valid filename
 string name = Path.GetFullPath(filename);
 // Now read the file and return the file content.
}

As part of the canonicalization process, GetFullPath performs the following checks:

  • It checks that the file name does not contain any invalid characters, as defined by Path.InvalidPathChars.
  • It checks that the file name represents a file and not another device type, such as a physical drive, a named pipe, a mail slot, or a DOS device such as LPT1, COM1, AUX, and other devices.
  • It checks that the combined path and file name is not too long.
  • It removes redundant characters such as trailing dots.
  • It rejects file names that use the //?/ format.


Use absolute file paths where you can

Try to use absolute file paths where you can. Do not trust an environment variable to construct a file path because you cannot guarantee the value of the environment variable.


Consider constraining file I/O within your application's context

After you know that you have a valid file system file name, you might need to check that it is valid in your application's context. For example, you may need to check that it is within the directory hierarchy of your application and that your code cannot access arbitrary files on the file system.

You can use a restricted FileIOPermission to constrain an assembly's ability to perform file I/O; for example, by specifying allowed access rights (read, read/write, and so on) or limiting access to specific directories.

You can use declarative attributes together with SecurityAction.PermitOnly to constrain file I/O, as shown in the following example.

// Allow only this code to read files from c:\YourAppDir
[FileIOPermission(SecurityAction.PermitOnly, Read=@"c:\YourAppDir\")]
[FileIOPermission(SecurityAction.PermitOnly, PathDiscovery=@"c:\YourAppDir\")]
public static string ReadFile(string filename)
{
 // Use Path.GetFullPath() to canonicalize the file name
 // Use FileStream.OpenRead to open the file
 // Use FileStream.Read to access and return the data
}

Note The second attribute that specifies PathDiscovery access is required by the Path.GetFullPath function that is used to canonicalize the input file name.

To avoid hard coding your application's directory hierarchy, you can use imperative security syntax, and then use the HttpContext.Current.Request.MapPath(".")to retrieve your Web application's directory at run time. You must refer to the System.Web assembly and add the corresponding using statement, as shown in the following example.

using System.Web;
using System.Security.Permissions;
...
public static string ReadFile(string filename)
{
 string appDir = HttpContext.Current.Request.MapPath(".");
 FileIOPermission f = new FileIOPermission(PermissionState.None);
 f.SetPathList(FileIOPermissionAccess.Read, appDir);
 f.SetPathList(FileIOPermissionAccess.PathDiscovery, appDir);
 f.PermitOnly();
 // Use Path.GetFullPath() to canonicalize the file name
 // Use FileStream.OpenRead to open the file
 // Use FileStream.Read to access and return the data
}

Partial trust ASP.NET Web applications that run with medium trust use code access security to restrict the directories that your application can access. Medium trust policy permits your application to access the directories beneath your application's virtual root directory. For more information about running ASP.NET applications at medium trust, see "How To: Use Medium Trust in ASP.NET 2.0" at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000020.asp.

Personal tools