Redemption Steps

The best ways to redeem your code are to apply the following rules:

  • If you can keep all files for your application in a place that attackers cannot control under any circumstances, its a great idea to do so. Even if you dont do any checking within your program, if you can maintain the security of that directory operationally, most of these problems go away. This generally is best done by creating a safe directory accessible only to the application. Often, the easiest way to provide per-application access control is to create a new user under which the program runs. Otherwise, other applications running as the same user will still be able to manipulate the same files.

  • Never use a filename for more than one file operation; pass a handle or file descriptor from the first operation to successive function calls.

  • Resolve the path to the file youre going to access, following symbolic links and any backwards traversals before performing validation on the path.

  • If you insist on opening a temporary file in a public directory, the most reliable way is to take eight bytes from the system cryptographic random number generator (see Sin 18), base64 encode it, replace the / character that the encoding might output with a , or some other benign character, and then
    use the result in your filename.

  • Where appropriate (read: if in doubt), lock the file when it is first accessed or created by your code.

  • If you know the file will be new and zero bytes in size , then truncate it. This way an attacker cannot give you a prepopulated rogue temporary file.

  • Never trust a filename not under your direct control.

  • Check whether the file is a real file, not a pipe, a device, or a symlink .

With these steps in mind, lets look at some code examples.

Perl Redemption

Use a file handle, not the filename, to verify the file exists and then open it.

 #!/usr/bin/perl my $file = "$ENV{HOME}/.config"; if (open(FILE, "< $file")) {  read_config(*FILE) if is_accessible(*FILE); } 

C/C++ Redemption on *nix

In some environments, theres an easy solution, the realpath() library call. There are two gotchas with this API call. First, the call isnt thread-safe, so you will need to stick a lock around it if theres any possibility that it can be called from multiple threads. Second, on some platforms, there are unexpected quirks in the behavior. Lets first look at the signature:

 char *realpath(const char *original_path, char resolved_path[PATH_MAX]); 

This function returns the second parameter on success, and NULL if theres an error in the pathname.

The intent here is that you put the potentially unsafe path in, and the function will traverse symbolic links, remove double dots, etc. On some operating systems, however, the first parameter has to be an absolute path for the result to be an absolute path. Sad, but true. To ensure portable code, you need to make sure that you prepend your current working directory to the value before passing it in. You can easily obtain your current working directory with getcwd ().

C/C++ Redemption on Windows

The following code takes a filename from an untrusted user and verifies its a real disk-based file; if its not, the code fails.

Note 

If you want to be more hardcore, you could also check to see if the filename is a valid size.

 HANDLE hFile = CreateFile(pFullPathName,  0,0,NULL,  OPEN_EXISTING,  SECURITY_SQOS_PRESENT  SECURITY_IDENTIFICATION,  NULL); if (hFile != INVALID_HANDLE_VALUE && GetFileType(hFile) == FILE_TYPE_DISK {  // looks like a normal file! } 

Getting the Location of the Users Temporary Directory

Storing temporary files in the users directory is safer than storing temporary files in a shared location. You can get the users temporary, private directory accessing the TMP environment variable.

.NET Code Redemption

In managed code environments and languages, such as C#, VB.NET, and ASP.NET, you can get the users temporary directory by calling the following code. In the case of ASP.NET, the temp file will be placed in the ASP.NET process identity directory.

C#

 using System.IO; ... string tempName = Path.GetTempFileName(); 

VB.NET

 Imports System.IO ... Dim tempName = Path.GetTempFileName 

Managed C++

 using namespace System::IO; ... String ^s = Path::GetTempFileName(); 


19 Deadly Sins of Software Security. Programming Flaws and How to Fix Them
Writing Secure Code
ISBN: 71626751
EAN: 2147483647
Year: 2003
Pages: 239

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net