gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/github.com/securego/gosec/rules/tls.go (about) 1 // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:generate tlsconfig 16 17 package rules 18 19 import ( 20 "fmt" 21 "go/ast" 22 23 "github.com/securego/gosec" 24 ) 25 26 type insecureConfigTLS struct { 27 gosec.MetaData 28 MinVersion int16 29 MaxVersion int16 30 requiredType string 31 goodCiphers []string 32 } 33 34 func (t *insecureConfigTLS) ID() string { 35 return t.MetaData.ID 36 } 37 38 func stringInSlice(a string, list []string) bool { 39 for _, b := range list { 40 if b == a { 41 return true 42 } 43 } 44 return false 45 } 46 47 func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gosec.Context) *gosec.Issue { 48 49 if ciphers, ok := n.(*ast.CompositeLit); ok { 50 for _, cipher := range ciphers.Elts { 51 if ident, ok := cipher.(*ast.SelectorExpr); ok { 52 if !stringInSlice(ident.Sel.Name, t.goodCiphers) { 53 err := fmt.Sprintf("TLS Bad Cipher Suite: %s", ident.Sel.Name) 54 return gosec.NewIssue(c, ident, t.ID(), err, gosec.High, gosec.High) 55 } 56 } 57 } 58 } 59 return nil 60 } 61 62 func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gosec.Context) *gosec.Issue { 63 if ident, ok := n.Key.(*ast.Ident); ok { 64 switch ident.Name { 65 66 case "InsecureSkipVerify": 67 if node, ok := n.Value.(*ast.Ident); ok { 68 if node.Name != "false" { 69 return gosec.NewIssue(c, n, t.ID(), "TLS InsecureSkipVerify set true.", gosec.High, gosec.High) 70 } 71 } else { 72 // TODO(tk): symbol tab look up to get the actual value 73 return gosec.NewIssue(c, n, t.ID(), "TLS InsecureSkipVerify may be true.", gosec.High, gosec.Low) 74 } 75 76 case "PreferServerCipherSuites": 77 if node, ok := n.Value.(*ast.Ident); ok { 78 if node.Name == "false" { 79 return gosec.NewIssue(c, n, t.ID(), "TLS PreferServerCipherSuites set false.", gosec.Medium, gosec.High) 80 } 81 } else { 82 // TODO(tk): symbol tab look up to get the actual value 83 return gosec.NewIssue(c, n, t.ID(), "TLS PreferServerCipherSuites may be false.", gosec.Medium, gosec.Low) 84 } 85 86 case "MinVersion": 87 if ival, ierr := gosec.GetInt(n.Value); ierr == nil { 88 if (int16)(ival) < t.MinVersion { 89 return gosec.NewIssue(c, n, t.ID(), "TLS MinVersion too low.", gosec.High, gosec.High) 90 } 91 // TODO(tk): symbol tab look up to get the actual value 92 return gosec.NewIssue(c, n, t.ID(), "TLS MinVersion may be too low.", gosec.High, gosec.Low) 93 } 94 95 case "MaxVersion": 96 if ival, ierr := gosec.GetInt(n.Value); ierr == nil { 97 if (int16)(ival) < t.MaxVersion { 98 return gosec.NewIssue(c, n, t.ID(), "TLS MaxVersion too low.", gosec.High, gosec.High) 99 } 100 // TODO(tk): symbol tab look up to get the actual value 101 return gosec.NewIssue(c, n, t.ID(), "TLS MaxVersion may be too low.", gosec.High, gosec.Low) 102 } 103 104 case "CipherSuites": 105 if ret := t.processTLSCipherSuites(n.Value, c); ret != nil { 106 return ret 107 } 108 109 } 110 111 } 112 return nil 113 } 114 115 func (t *insecureConfigTLS) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { 116 if complit, ok := n.(*ast.CompositeLit); ok && complit.Type != nil { 117 actualType := c.Info.TypeOf(complit.Type) 118 if actualType != nil && actualType.String() == t.requiredType { 119 for _, elt := range complit.Elts { 120 if kve, ok := elt.(*ast.KeyValueExpr); ok { 121 issue := t.processTLSConfVal(kve, c) 122 if issue != nil { 123 return issue, nil 124 } 125 } 126 } 127 } 128 } 129 return nil, nil 130 }