Many applications require to create and maintain temporary files. Often these temporary files are created without the enduser knowing about the same. Security attacks realized due to insecure temporary file management is a critical category of security attacks on software applications. Application developers are required to follow certain security best practices when creating temporary files. In this article I shall discuss these best practices.
Vulnerabilities due to poor tmp file implementations
filename = mktemp(template);
fd = open(filename, …);
But an adversary can create a file with the same name between the two statements.
Then, victim.c will either end up opening the adversary’s file, or will fail to create the temporary file itself.
Attack#2 Symbolic Link Vulnerability
If the attacker knows where the application creates its temporary files and can guess the name of the next temporary file, the following attack can be realized:
- Attacker will put a symbolic link at the temporary file location.
- The attacker will link the symbolic link to a privileged file.
- Now, the application will unknowingly write to the privileged file instead of writing to the file in the temp directory.
Security Considerations when designing Temporary File modules
1. Avoid temporary files altogether
Temporary files often end up creating more problems than solving them. The effort (time/money) required to develop a temporary file management module often outweighs the features that get added to the application.
2. Reasearch the platform support for temporary files
Before starting out to code the temporary file generation module, assess the existing support for file generation on the target platform. For example, Windows has the GetTempPath() API call that provides the default temporary directory path.
3. Ensure file name uniqueness
The filename of the temporary file must be unique. This ensures that the application does not end up clobbering any existing data on the disk. If a file having the same name already exists on the disk, the logic of file name generation should generate (see next point) a new file name and use that instead.
4. Ensure file name randomness
When generating the file name of the temporary file ensure that the name is not guessable. Typically, the default APIs that are supplied by the operating system for generating temporary files create filenames containing monotonically increasing integers. Therefore it becomes possible to predict the filename of the next temporary file that the application will generate. Use cryptography to generate unique file names. For eg. the CryptGenRandom() function may be used to achieve this.
5. Ensure proper permissions for the temporary file
Ensure that the temporary file have the appropriate ACLs (access control lists) set on them. Avoid publically writable temporary directories if possible. If using a publically writable directory, make a directory within the publically writable directory for temporary files, with read and write permissions for the application only. Temporary files are often used to hold intermittent state information about the operation in progress and may contain confidential information.
6. Ensure secure cleanup of temporary files after usage
One of the most common attacks on applications that use temporary files is the recovery of previously deleted temporary files from the disk. This is trivially possible with the help of software available on the Internet. In order to mitigate against this operation, shred temporary files. Depending on the sensitivity of the information contained in the temporary file, ensure that the cleanup is commensurate with the security levels desired.
7. Prevent covert access
Sometimes the application's temporary files containing sensitive information may be indexed by the underlying Operating System service that may be active on the user system. For example, the indexing service on Windows, when active, silently builds an index of all files on disk. It is possible that sensitive information will end up getting indexed so that a malicious user may use the Search Files/Folders feature to obtain application intelligence.
8. Dont use dangerous functions for temporary file generation
Dont use mktemp(), tmpnam(), tempname(), tmpfile() for generating temporary files. Also don’t reuse the parameter in mkstemp(f) in any other function call, such as stat(), chmod(), etc because the same name may refer to a different file.
9. Avoid storing very sensitive information in temporary files
As a rule, avoid storing sensitive information in temporary files. This is a very common reason for most attacks on applications. An application may employ sophisticated security safeguards such as encryption for securing its data but between encryption may be unwittingly storing sensitive information to an unprotected temporary file. Avoid this at all costs.
10. Rely on absolute file paths and file handles
When building the file paths of the temporary file, use absolute paths. Do not use relative file paths. Also, if the directory path where the temporary files are being housed is being accepted from the user, ensure that it has been sanitised. To prevent time-of-check-to-time-of-use (TOCTOU) attacks, ensure that you use file handles (and not file paths) for future access to the temporary files. Many a vulnerability have been imputed to applications using relative file paths for temporary file access.
11. Securely create temporary files
If open() is being used to create a temporary file use the O_CREAT|O_EXCL flags. If the Windows CreateFile() is being used to create a temporary file use the CREATE_NEW attribute. Calling the APIs with these flags ensures that these APIs fail if a file is already present with the same name in the temporary directory.
Temporary files are sometimes very useful for the application developer. However, improper implementation of temp file modules leads to the realization of several attacks on the application. The application developer must use the techniques contained in this article to mitigate against these security issues.