mirror of
				https://github.com/mgechev/revive.git
				synced 2025-10-30 23:37:49 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			89 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package rule
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"go/ast"
 | |
| 	"go/token"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/mgechev/revive/lint"
 | |
| )
 | |
| 
 | |
| // UnsecureURLSchemeRule checks if a file contains string literals with unsecure URL schemes (for example: http://... in place of https://...).
 | |
| type UnsecureURLSchemeRule struct{}
 | |
| 
 | |
| // Apply applied the rule to the given file.
 | |
| func (*UnsecureURLSchemeRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
 | |
| 	if file.IsTest() {
 | |
| 		return nil // skip test files
 | |
| 	}
 | |
| 
 | |
| 	var failures []lint.Failure
 | |
| 	onFailure := func(failure lint.Failure) {
 | |
| 		failures = append(failures, failure)
 | |
| 	}
 | |
| 
 | |
| 	w := lintUnsecureURLSchemeRule{
 | |
| 		onFailure: onFailure,
 | |
| 	}
 | |
| 
 | |
| 	ast.Walk(w, file.AST)
 | |
| 	return failures
 | |
| }
 | |
| 
 | |
| // Name returns the rule name.
 | |
| func (*UnsecureURLSchemeRule) Name() string {
 | |
| 	return "unsecure-url-scheme"
 | |
| }
 | |
| 
 | |
| type lintUnsecureURLSchemeRule struct {
 | |
| 	onFailure func(lint.Failure)
 | |
| }
 | |
| 
 | |
| const schemeSeparator = "://"
 | |
| const schemeHTTP = "http"
 | |
| const schemeWS = "ws"
 | |
| const urlPrefixHTTP = schemeHTTP + schemeSeparator
 | |
| const urlPrefixWS = schemeWS + schemeSeparator
 | |
| const lenURLPrefixHTTP = len(urlPrefixHTTP)
 | |
| const lenURLPrefixWS = len(urlPrefixWS)
 | |
| 
 | |
| func (w lintUnsecureURLSchemeRule) Visit(node ast.Node) ast.Visitor {
 | |
| 	n, ok := node.(*ast.BasicLit)
 | |
| 	if !ok || n.Kind != token.STRING {
 | |
| 		return w // not a string literal
 | |
| 	}
 | |
| 
 | |
| 	value, _ := strconv.Unquote(n.Value) // n.Value has one of the following forms: "..." or `...`
 | |
| 
 | |
| 	var scheme string
 | |
| 	var lenURLPrefix int
 | |
| 	switch {
 | |
| 	case strings.HasPrefix(value, urlPrefixHTTP):
 | |
| 		scheme = schemeHTTP
 | |
| 		lenURLPrefix = lenURLPrefixHTTP
 | |
| 	case strings.HasPrefix(value, urlPrefixWS):
 | |
| 		scheme = schemeWS
 | |
| 		lenURLPrefix = lenURLPrefixWS
 | |
| 	default:
 | |
| 		return nil // not an URL or not an unsecure one
 | |
| 	}
 | |
| 
 | |
| 	if len(value) <= lenURLPrefix {
 | |
| 		return nil // there is no host part in the string
 | |
| 	}
 | |
| 
 | |
| 	if strings.Contains(value, "localhost") || strings.Contains(value, "127.0.0.1") || strings.Contains(value, "0.0.0.0") || strings.Contains(value, "//::") {
 | |
| 		return nil // do not fail on local URL
 | |
| 	}
 | |
| 
 | |
| 	w.onFailure(lint.Failure{
 | |
| 		Confidence: 1,
 | |
| 		Failure:    fmt.Sprintf("prefer secure protocol %s over %s in %s", scheme+"s", scheme, n.Value),
 | |
| 		Node:       n,
 | |
| 	})
 | |
| 
 | |
| 	return nil
 | |
| }
 |