Create rule S5445: Insecure temporary file creation methods should not be used (#4671)

* Add go to rule S5445

* Initial draft

* Add examples for temporary directories

---------

Co-authored-by: teemu-rytilahti-sonarsource <teemu-rytilahti-sonarsource@users.noreply.github.com>
Co-authored-by: Teemu Rytilahti <teemu.rytilahti@sonarsource.com>
This commit is contained in:
github-actions[bot] 2025-02-21 12:02:48 +01:00 committed by GitHub
parent 972b0e39c2
commit 59fba4deac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 102 additions and 0 deletions

View File

@ -0,0 +1,2 @@
{
}

100
rules/S5445/go/rule.adoc Normal file
View File

@ -0,0 +1,100 @@
include::../common/rationale.adoc[]
== Why is this an issue?
include::../common/description.adoc[]
=== What is the potential impact?
include::../common/impact.adoc[]
== How to fix it
=== Code examples
include::../common/fix/code-rationale.adoc[]
==== Noncompliant code example
Creating a temporary filename under a publicly writable path may allow an attacker to read and modify the file contents. See also S5443 - Using publicly writable directories is security-sensitive.
[source,go,diff-id=1,diff-type=noncompliant]
----
fname := filepath.Join(os.TempDir(), "example.conf") // Noncompliant: fname=/tmp/example.conf
os.WriteFile(fname, []byte("hello world"), 0644)
----
Similarly, constructing a temporary directory using predictable paths should be avoided:
[source,go,diff-id=2,diff-type=noncompliant]
----
dname := filepath.Join(os.TempDir(), "example") // Noncompliant: dname=/tmp/example/
os.MkdirAll(dname, 0700)
fname := filepath.Join(dname, "example.conf")
os.WriteFile(fname, []byte("hello world"), 0600) // Writes to /tmp/example/example.conf
----
==== Compliant solution
Using `os.CreateTemp` creates a temporary file with an unpredictable filename and limited permissions:
[source,go,diff-id=1,diff-type=compliant]
----
file, _ := os.CreateTemp("", "example-pattern-*")
// Example file=/tmp/example-pattern-3425235234
file.WriteString("hello world")
----
If you need a temporary directory for multiple files, you can use `os.MkdirTemp()`:
[source,go,diff-id=2,diff-type=compliant]
----
dname, _ := os.MkdirTemp("", "example-*")
fname := filepath.Join(dname, "example.conf")
os.WriteFile(fn, []byte("hello world"), 0600) // Writes to /tmp/example-243556/example.conf
----
=== How does this work?
include::../common/fix/introduction.adoc[]
include::../common/fix/secure-api.adoc[]
Here, the example compliant code uses the more secure
`os.CreateTemp` function to handle the temporary file creation.
include::../common/fix/manual-setup.adoc[]
//=== Pitfalls
//=== Going the extra mile
== Resources
include::../common/resources/documentation.adoc[]
* https://pkg.go.dev/os#CreateTemp[os.CreateTemp()] - documentation
//=== Articles & blog posts
//=== Conference presentations
include::../common/resources/standards.adoc[]
//=== Benchmarks
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
'''
== Comments And Links
(visible only on this page)
include::../comments-and-links.adoc[]
endif::env-github,rspecator-view[]