Safe use of temporary files

My program uses a static library that can only accept file names, not the actual contents of the file. I can do nothing with the source code of the library. Therefore, I want to: create a completely new file, save the data for its processing, upload it to disk (?), Transfer its name to the library, and then delete it.

But I also want this process to be safe enough:
1) the file must be recreated without any fictitious data (perhaps this is not critical, but anything); 2) anyone, except my process, cannot read or write from / to this file (I want the library to process my actual data, and not dummy data, some of which wiseguy managed to connect); 3) after I finished with this file, I need to delete it (well, if someone TerminateProcess() me, I think that nothing can be done, but still).

The library seems to use non-Unicode fopen() to open this file, so I'm not quite sure how to handle all this, since the program is designed to work on Windows. Any suggestions?

+6
source share
6 answers

You already have a lot of suggestions, but another option that I don’t think is mentioned is the use of named pipes. This will depend on the library in question, whether it works or not, but it might be worth a try. You can create a named pipe in your application using the CreateNamedPipe function and pass the pipe name to the library for work (the file name you will pass will be \\. \ Pipe \ PipeName ). Regardless of whether the library accepts a file name or not, you will need to try, but if it works, your file should never actually be written to disk.

+4
source

This can be achieved with CreateFile and GetTempFileName (if you do not know if you can write to the current working directory, you can also use GetTempPath ).

  • Define a directory to store your temporary file; the current directory (".") or the result of GetTempPath will be good candidates.
  • Use GetTempFileName to create a temporary file name.
  • Finally, call CreateFile to create a temporary file.

For the last step you need to consider a few things:

  • The dwFlagsAndAttributes CreateFile parameter should probably include FILE_ATTRIBUTE_TEMPORARY .
  • The dwFlagsAndAttributes parameter should probably also include FILE_FLAG_DELETE_ON_CLOSE to make sure the file is deleted no matter what (this probably also works if your process crashes, in which case the system closes all the handles for you).
  • The dwShareMode CreateFile parameter should probably be FILE_SHARE_READ for other attempts to open the file to succeed, but only for reading. This means that your library code can read the file, but no one can write it.
+2
source

This article should give you some good recommendations on this issue.

The point is:

  • The POSIX mkstemp () function is a safe and preferred solution, if available. Unfortunately, it is not available on Windows, so you will need to find a shell that correctly implements this function using the Windows API calls.
  • On Windows, the tmpfile_s () function is the only one that actually opens a temporary file atomically (instead of just creating a file name) protecting you from race conditions. Unfortunately, this function does not allow you to specify in which directory the file will be created, which is a potential security problem.
+1
source

First of all, you can create a file in the user's temporary folder (for example, C: \ Users \\ AppData \ Local \ Temp) - this is an ideal place for such files. Secondly, when you create a file , you can specify which access to access you provide.

A fragment of the CreateFile Help page on MSDN:

<i> dwShareMode

  • 0 Prevents other processes from opening a file or device if they request deletion, reading, or writing.
  • FILE_SHARE_DELETE Includes subsequent open operations with a file or device request to remove access. Otherwise, other processes will not be able to open the file or device if they are prompted to remove access. If this flag is not specified, but the file or device was opened for access to deletion, the function does not work. Note. Delete access allows you to perform delete and rename operations.
  • FILE_SHARE_READ Includes subsequent open operations on a file or device to request read access. Otherwise, other processes will not be able to open the file or device if they request read access. If this flag is not specified, but the file or device was open for read access, the function does not work.
  • FILE_SHARE_WRITE Includes subsequent open file or device access operations to request write access. Otherwise, other processes will not be able to open the file or device if they request write access. If this flag is not specified, but the file or device was open for write access or has a mapping of files with write ability, the function fails.
0
source

While the suggestions offered are good, like using FILE_SHARE_READ, FILE_DELETE_ON_CLOSE etc., I don’t think there is an absolutely safe way to do this.

I used Process Explorer to close files designed to prevent the second process from starting. I did this because the first process was stuck and "was not killed, not dead, but did not respond," so I had a good reason for this - and I did not want to restart the machine at this particular point due to other processes running in system.

If someone uses some kind of debugger (including something non-commercial, written specifically for this purpose), joins your running process, sets a breakpoint and stops the code, then closes the file you opened, it can write to the file, which you just created.

You can make it harder, but you cannot stop someone with sufficient privileges / skills / capabilities from intercepting your program and manipulating data.

Please note that file and folder protection only works if you reliably know that users do not have privileged accounts on the computer. Typically, Windows users are administrators immediately or have a different account for administrator purposes - and I have access to sudo / root in almost all the Linux boxes I use at work - there are some file servers that I don’t [and should not] have root access. But all the boxes that I use myself or I can borrow for testing purposes, I can get in the root environment. This is not very unusual.

The solution I can think of is to find another library that uses a different interface [or get the sources of the library and change it so that it]. Not that this would prevent the stop, change, and move attack using the debugger approach described above.

0
source

Create your file in your executable folder using the CreateFile API. You can specify the file name UUID each time it is created so that no other process can guess the file name in order to open it. and set its attribute to hidden. After use, simply delete the file. It's enough?

-1
source

All Articles