Writing Secure Code

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

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();

Категории