mirror of
https://github.com/securego/gosec.git
synced 2024-11-06 03:55:50 +00:00
Add a new rule which detects when a file is created with os.Create but the configured permissions are less than 0666
It seems that the os.Create will create by default a file with 0666 permissions. This should be detected when the configured permissions are less than 0666. By default will not detect this case unless the more restrictive mode is configured. Signed-off-by: Cosmin Cojocar <gcojocar@adobe.com>
This commit is contained in:
parent
293d887525
commit
0d332a1027
4 changed files with 89 additions and 0 deletions
|
@ -157,6 +157,7 @@ directory you can supply `./...` as the input argument.
|
||||||
- G304: File path provided as taint input
|
- G304: File path provided as taint input
|
||||||
- G305: File traversal when extracting zip/tar archive
|
- G305: File traversal when extracting zip/tar archive
|
||||||
- G306: Poor file permissions used when writing to a new file
|
- G306: Poor file permissions used when writing to a new file
|
||||||
|
- G307: Poor file permissions used when crating a file with os.Create
|
||||||
- G401: Detect the usage of DES, RC4, MD5 or SHA1
|
- G401: Detect the usage of DES, RC4, MD5 or SHA1
|
||||||
- G402: Look for bad TLS connection settings
|
- G402: Look for bad TLS connection settings
|
||||||
- G403: Ensure minimum RSA key length of 2048 bits
|
- G403: Ensure minimum RSA key length of 2048 bits
|
||||||
|
|
|
@ -30,6 +30,7 @@ type filePermissions struct {
|
||||||
calls []string
|
calls []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ID returns the ID of the rule.
|
||||||
func (r *filePermissions) ID() string {
|
func (r *filePermissions) ID() string {
|
||||||
return r.MetaData.ID
|
return r.MetaData.ID
|
||||||
}
|
}
|
||||||
|
@ -55,6 +56,7 @@ func modeIsSubset(subset int64, superset int64) bool {
|
||||||
return (subset | superset) == superset
|
return (subset | superset) == superset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Match checks if the rule is matched.
|
||||||
func (r *filePermissions) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
|
func (r *filePermissions) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
|
||||||
for _, pkg := range r.pkgs {
|
for _, pkg := range r.pkgs {
|
||||||
if callexpr, matched := gosec.MatchCallByPackage(n, c, pkg, r.calls...); matched {
|
if callexpr, matched := gosec.MatchCallByPackage(n, c, pkg, r.calls...); matched {
|
||||||
|
@ -116,3 +118,48 @@ func NewMkdirPerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||||
},
|
},
|
||||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type osCreatePermissions struct {
|
||||||
|
issue.MetaData
|
||||||
|
defaultMode int64
|
||||||
|
mode int64
|
||||||
|
pkgs []string
|
||||||
|
calls []string
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultOsCreateMode = 0o666
|
||||||
|
|
||||||
|
// ID returns the ID of the rule.
|
||||||
|
func (r *osCreatePermissions) ID() string {
|
||||||
|
return r.MetaData.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match checks if the rule is matched.
|
||||||
|
func (r *osCreatePermissions) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
|
||||||
|
for _, pkg := range r.pkgs {
|
||||||
|
if _, matched := gosec.MatchCallByPackage(n, c, pkg, r.calls...); matched {
|
||||||
|
if !modeIsSubset(defaultOsCreateMode, r.mode) {
|
||||||
|
return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOsCreatePerms reates a rule to detect file creation with a more permissive than configured
|
||||||
|
// permission mask.
|
||||||
|
func NewOsCreatePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||||
|
mode := getConfiguredMode(conf, id, 0o666)
|
||||||
|
return &osCreatePermissions{
|
||||||
|
mode: mode,
|
||||||
|
pkgs: []string{"os"},
|
||||||
|
calls: []string{"Create"},
|
||||||
|
MetaData: issue.MetaData{
|
||||||
|
ID: id,
|
||||||
|
Severity: issue.Medium,
|
||||||
|
Confidence: issue.High,
|
||||||
|
What: fmt.Sprintf("Expect file permissions to be %#o or less but os.Create used with default permissions %#o",
|
||||||
|
mode, defaultOsCreateMode),
|
||||||
|
},
|
||||||
|
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||||
|
}
|
||||||
|
|
|
@ -91,6 +91,7 @@ func Generate(trackSuppressions bool, filters ...RuleFilter) RuleList {
|
||||||
{"G304", "File path provided as taint input", NewReadFile},
|
{"G304", "File path provided as taint input", NewReadFile},
|
||||||
{"G305", "File path traversal when extracting zip archive", NewArchive},
|
{"G305", "File path traversal when extracting zip archive", NewArchive},
|
||||||
{"G306", "Poor file permissions used when writing to a file", NewWritePerms},
|
{"G306", "Poor file permissions used when writing to a file", NewWritePerms},
|
||||||
|
{"G307", "Poor file permissions used when creating a file with os.Create", NewOsCreatePerms},
|
||||||
|
|
||||||
// crypto
|
// crypto
|
||||||
{"G401", "Detect the usage of DES, RC4, MD5 or SHA1", NewUsesWeakCryptography},
|
{"G401", "Detect the usage of DES, RC4, MD5 or SHA1", NewUsesWeakCryptography},
|
||||||
|
|
|
@ -2913,6 +2913,46 @@ func main() {
|
||||||
}`}, 1, gosec.NewConfig()},
|
}`}, 1, gosec.NewConfig()},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SampleCodeG307 - Poor permissions for os.Create
|
||||||
|
SampleCodeG307 = []CodeSample{
|
||||||
|
{[]string{`package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func check(e error) {
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
f, err := os.Create("/tmp/dat2")
|
||||||
|
check(err)
|
||||||
|
defer f.Close()
|
||||||
|
}`}, 0, gosec.NewConfig()},
|
||||||
|
{[]string{`package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func check(e error) {
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
f, err := os.Create("/tmp/dat2")
|
||||||
|
check(err)
|
||||||
|
defer f.Close()
|
||||||
|
}`}, 1, gosec.Config{"G307": "0o600"}},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG401 - Use of weak crypto MD5
|
// SampleCodeG401 - Use of weak crypto MD5
|
||||||
SampleCodeG401 = []CodeSample{
|
SampleCodeG401 = []CodeSample{
|
||||||
{[]string{`
|
{[]string{`
|
||||||
|
|
Loading…
Reference in a new issue