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:
parent
972b0e39c2
commit
59fba4deac
2
rules/S5445/go/metadata.json
Normal file
2
rules/S5445/go/metadata.json
Normal file
@ -0,0 +1,2 @@
|
||||
{
|
||||
}
|
100
rules/S5445/go/rule.adoc
Normal file
100
rules/S5445/go/rule.adoc
Normal 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[]
|
Loading…
x
Reference in New Issue
Block a user