Reputation: 3765
There is a static library I use in my program which can only take filenames as its input, not actual file contents. There is nothing I can do about the library's source code. So I want to: create a brand-new file, store data to being processed into it, flush it onto the disk(?), pass its name to the library, then delete it.
But I also want this process to be rather secure:
1) the file must be created anew, without any bogus data (maybe it's not critical, but whatever);
2) anyone but my process must not be able read or write from/to this file (I want the library to process my actual data, not bogus data some wiseguy managed to plug in);
3) after I'm done with this file, it must be deleted (okay, if someone TerminateProcess()
me, I guess there is nothing much can be done, but still).
The library seems to use non-Unicode fopen()
to open the given file though, so I am not quite sure how to handle all this, since the program is intended to run on Windows. Any suggestions?
Upvotes: 6
Views: 3909
Reputation: 276
This article should give you some good guidelines on the issue.
The gist of the matter is this:
Upvotes: 2
Reputation: 37122
You have a lot of suggestions already, but another option that I don't think has been mentioned is using named pipes. It will depend on the library in question as to 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 name of the pipe to the library to operate on (the filename you would pass would be \\.\pipe\PipeName). Whether the library accepts a filename like that or not is something you would have to try, but if it works the advantage is your file never has to actually be written to disk.
Upvotes: 4
Reputation: 129314
Whilst suggestions given are good, such as using FILE_SHARE_READ, FILE_DELETE_ON_CLOSE, etc, I don't think there is a completely safe way to do thist.
I have used Process Explorer to close files that are meant to prevent a second process starting - I did this because the first process got stuck and was "not killable and not dead, but not responding", so I had a valid reason to do this - and I didn't want to reboot the machine at that particular point due to other processes running on the system.
If someone uses a debugger of some sort [including something non-commercial, written specifically for this purpose], attaches to your running process, sets a breakpoint and stops the code, then closes the file you have open, it can write to the file you just created.
You can make it harder, but you can't stop someone with sufficient privileges/skills/capabilities from intercepting your program and manipulating the data.
Note that file/folder protection only works if you reliably know that users don't have privileged accounts on the machine - typical Windows users are either admins right away, or have another account for admin purposes - and I have access to sudo/root on nearly all of the Linux boxes I use at work - there are some fileservers that I don't [and shouldn't] have root access. But all the boxes I use myself or can borrow of testing purposes, I can get to a root environment. This is not very unusual.
A solution I can think of is to find a different library that uses a different interface [or get the sources of the library and modify it so that it]. Not that this prevents a "stop, modify and go" attack using the debugger approach described above.
Upvotes: 0
Reputation: 94289
This can be achieved using the CreateFile
and GetTempFileName
functions (if you don't know if you can write to the current working directory, you may also want to use , GetTempPath
).
GetTempPath
would be good candidates.GetTempFileName
to create a temporary file name.CreateFile
to create the temporary file.For the last step, there are a few things to consider:
dwFlagsAndAttributes
parameter of CreateFile
should probably include FILE_ATTRIBUTE_TEMPORARY
.dwFlagsAndAttributes
parameter should probably also include FILE_FLAG_DELETE_ON_CLOSE
to make sure that the file gets deleted no matter what (this probably also works if your process crashes, in which case the system closes all handles for you).dwShareMode
parameter of CreateFile
should probably be FILE_SHARE_READ
so that other attempts to open the file will succeed, but only for reading. This means that your library code will be able to read the file, but nobody will be able to write to it.Upvotes: 2
Reputation: 25927
Primarily, you can create file in user's temporary folder (eg. C:\Users\\AppData\Local\Temp) - it is a perfect place for such files. Secondly, when creating a file, you can specify, what kind of access sharing do you provide.
Fragment of CreateFile help page on MSDN:
dwShareMode
- 0 Prevents other processes from opening a file or device if they request delete, read, or write access.
- FILE_SHARE_DELETE Enables subsequent open operations on a file or device to request delete access. Otherwise, other processes cannot open the file or device if they request delete access. If this flag is not specified, but the file or device has been opened for delete access, the function fails. Note: Delete access allows both delete and rename operations.
- FILE_SHARE_READ Enables subsequent open operations on a file or device to request read access. Otherwise, other processes cannot open the file or device if they request read access. If this flag is not specified, but the file or device has been opened for read access, the function fails.
- FILE_SHARE_WRITE Enables subsequent open operations on a file or device to request write access. Otherwise, other processes cannot open the file or device if they request write access. If this flag is not specified, but the file or device has been opened for write access or has a file mapping with write access, the function fails.
Upvotes: 0
Reputation: 1005
Create your file in your executable's folder using CreateFile API, You can give the file name some UUID, each time its created, so that no other process can guess the file name to open it. and set its attribute to hidden. After using it, just delete the file .Is it enough?
Upvotes: -1