1717package rules
1818
1919import (
20+ "crypto/tls"
2021 "fmt"
2122 "go/ast"
2223
@@ -25,10 +26,12 @@ import (
2526
2627type insecureConfigTLS struct {
2728 gosec.MetaData
28- MinVersion int16
29- MaxVersion int16
30- requiredType string
31- goodCiphers []string
29+ MinVersion int16
30+ MaxVersion int16
31+ requiredType string
32+ goodCiphers []string
33+ actualMinVersion int16
34+ actualMaxVersion int16
3235}
3336
3437func (t * insecureConfigTLS ) ID () string {
@@ -45,7 +48,6 @@ func stringInSlice(a string, list []string) bool {
4548}
4649
4750func (t * insecureConfigTLS ) processTLSCipherSuites (n ast.Node , c * gosec.Context ) * gosec.Issue {
48-
4951 if ciphers , ok := n .(* ast.CompositeLit ); ok {
5052 for _ , cipher := range ciphers .Elts {
5153 if ident , ok := cipher .(* ast.SelectorExpr ); ok {
@@ -62,7 +64,6 @@ func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gosec.Context)
6264func (t * insecureConfigTLS ) processTLSConfVal (n * ast.KeyValueExpr , c * gosec.Context ) * gosec.Issue {
6365 if ident , ok := n .Key .(* ast.Ident ); ok {
6466 switch ident .Name {
65-
6667 case "InsecureSkipVerify" :
6768 if node , ok := n .Value .(* ast.Ident ); ok {
6869 if node .Name != "false" {
@@ -85,20 +86,24 @@ func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gosec.Cont
8586
8687 case "MinVersion" :
8788 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 )
89+ t .actualMinVersion = (int16 )(ival )
90+ } else {
91+ if se , ok := n .Value .(* ast.SelectorExpr ); ok {
92+ if pkg , ok := se .X .(* ast.Ident ); ok && pkg .Name == "tls" {
93+ t .actualMinVersion = t .mapVersion (se .Sel .Name )
94+ }
9095 }
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 )
9396 }
9497
9598 case "MaxVersion" :
9699 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 )
100+ t .actualMaxVersion = (int16 )(ival )
101+ } else {
102+ if se , ok := n .Value .(* ast.SelectorExpr ); ok {
103+ if pkg , ok := se .X .(* ast.Ident ); ok && pkg .Name == "tls" {
104+ t .actualMaxVersion = t .mapVersion (se .Sel .Name )
105+ }
99106 }
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 )
102107 }
103108
104109 case "CipherSuites" :
@@ -112,6 +117,35 @@ func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gosec.Cont
112117 return nil
113118}
114119
120+ func (t * insecureConfigTLS ) mapVersion (version string ) int16 {
121+ var v int16
122+ switch version {
123+ case "VersionTLS13" :
124+ v = tls .VersionTLS13
125+ case "VersionTLS12" :
126+ v = tls .VersionTLS12
127+ case "VersionTLS11" :
128+ v = tls .VersionTLS11
129+ case "VersionTLS10" :
130+ v = tls .VersionTLS10
131+ }
132+ return v
133+ }
134+
135+ func (t * insecureConfigTLS ) checkVersion (n ast.Node , c * gosec.Context ) * gosec.Issue {
136+ if t .actualMaxVersion == 0 && t .actualMinVersion >= t .MinVersion {
137+ // no warning is generated since the min version is grater than the secure min version
138+ return nil
139+ }
140+ if t .actualMinVersion < t .MinVersion {
141+ return gosec .NewIssue (c , n , t .ID (), "TLS MinVersion too low." , gosec .High , gosec .High )
142+ }
143+ if t .actualMaxVersion < t .MaxVersion {
144+ return gosec .NewIssue (c , n , t .ID (), "TLS MaxVersion too low." , gosec .High , gosec .High )
145+ }
146+ return nil
147+ }
148+
115149func (t * insecureConfigTLS ) Match (n ast.Node , c * gosec.Context ) (* gosec.Issue , error ) {
116150 if complit , ok := n .(* ast.CompositeLit ); ok && complit .Type != nil {
117151 actualType := c .Info .TypeOf (complit .Type )
@@ -124,6 +158,7 @@ func (t *insecureConfigTLS) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, e
124158 }
125159 }
126160 }
161+ return t .checkVersion (complit , c ), nil
127162 }
128163 }
129164 return nil , nil
0 commit comments