gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/github.com/securego/gosec/rules/ssrf.go (about)

     1  package rules
     2  
     3  import (
     4  	"go/ast"
     5  	"go/types"
     6  
     7  	"github.com/securego/gosec"
     8  )
     9  
    10  type ssrf struct {
    11  	gosec.MetaData
    12  	gosec.CallList
    13  }
    14  
    15  // ID returns the identifier for this rule
    16  func (r *ssrf) ID() string {
    17  	return r.MetaData.ID
    18  }
    19  
    20  // ResolveVar tries to resolve the first argument of a call expression
    21  // The first argument is the url
    22  func (r *ssrf) ResolveVar(n *ast.CallExpr, c *gosec.Context) bool {
    23  	if len(n.Args) > 0 {
    24  		arg := n.Args[0]
    25  		if ident, ok := arg.(*ast.Ident); ok {
    26  			obj := c.Info.ObjectOf(ident)
    27  			if _, ok := obj.(*types.Var); ok && !gosec.TryResolve(ident, c) {
    28  				return true
    29  			}
    30  		}
    31  	}
    32  	return false
    33  }
    34  
    35  // Match inspects AST nodes to determine if certain net/http methods are called with variable input
    36  func (r *ssrf) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
    37  	// Call expression is using http package directly
    38  	if node := r.ContainsCallExpr(n, c); node != nil {
    39  		if r.ResolveVar(node, c) {
    40  			return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil
    41  		}
    42  	}
    43  	return nil, nil
    44  }
    45  
    46  // NewSSRFCheck detects cases where HTTP requests are sent
    47  func NewSSRFCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
    48  	rule := &ssrf{
    49  		CallList: gosec.NewCallList(),
    50  		MetaData: gosec.MetaData{
    51  			ID:         id,
    52  			What:       "Potential HTTP request made with variable url",
    53  			Severity:   gosec.Medium,
    54  			Confidence: gosec.Medium,
    55  		},
    56  	}
    57  	rule.AddAll("net/http", "Do", "Get", "Head", "Post", "PostForm", "RoundTrip")
    58  	return rule, []ast.Node{(*ast.CallExpr)(nil)}
    59  }