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  }