64 lines
2.2 KiB
Plaintext
64 lines
2.2 KiB
Plaintext
Creating temporary files using insecure methods exposes the application to race conditions on filenames: a malicious user can try to create a file with a predictable name before the application does. A successful attack can result in other files being accessed, modified, corrupted or deleted. This risk is even higher if the application run with elevated permissions.
|
||
|
||
|
||
In the past, it has led to the following vulnerabilities:
|
||
|
||
* https://nvd.nist.gov/vuln/detail/CVE-2014-1858[CVE-2014-1858]
|
||
* https://nvd.nist.gov/vuln/detail/CVE-2014-1932[CVE-2014-1932]
|
||
|
||
``++Path.GetTempFileName()++`` generates predictable file names and is inherently unreliable and insecure. Additionally, the method will raise an ``++IOException++`` if it is used to create more than 65535 files without deleting previous temporary files.
|
||
|
||
== Recommended Secure Coding Practices
|
||
|
||
Out of the box, .NET is missing secure-by-design APIs to create temporary files. To overcome this, one of the following options can be used:
|
||
|
||
* Use a dedicated sub-folder with tightly controlled permissions
|
||
* Created temporary files in a publicly writable folder and make sure:
|
||
** Generated filename is unpredictable
|
||
** File is readable and writable only by the creating user ID
|
||
** File descriptor is not inherited by child processes
|
||
** File is destroyed as soon as it is closed
|
||
|
||
== Noncompliant Code Example
|
||
|
||
[source,csharp]
|
||
----
|
||
var tempPath = Path.GetTempFileName(); // Noncompliant
|
||
|
||
using (var writer = new StreamWriter(tempPath))
|
||
{
|
||
writer.WriteLine("content");
|
||
}
|
||
----
|
||
|
||
== Compliant Solution
|
||
|
||
[source,csharp]
|
||
----
|
||
var randomPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||
|
||
// Creates a new file with write, non inheritable permissions which is deleted on close.
|
||
using (var fileStream = new FileStream(randomPath, FileMode.CreateNew, FileAccess.Write, FileShare.None, 4096, FileOptions.DeleteOnClose))
|
||
using (var writer = new StreamWriter(fileStream))
|
||
{
|
||
writer.WriteLine("content");
|
||
}
|
||
----
|
||
|
||
include::../see.adoc[]
|
||
|
||
ifdef::env-github,rspecator-view[]
|
||
|
||
'''
|
||
== Implementation Specification
|
||
(visible only on this page)
|
||
|
||
include::message.adoc[]
|
||
|
||
'''
|
||
== Comments And Links
|
||
(visible only on this page)
|
||
|
||
include::../comments-and-links.adoc[]
|
||
endif::env-github,rspecator-view[]
|