forked from aquasecurity/tfsec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
scanner.go
80 lines (70 loc) 路 2.09 KB
/
scanner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package scanner
import (
"fmt"
"io/ioutil"
"strings"
"github.com/k1rd3rf/tfsec/internal/app/tfsec/parser"
)
// Scanner scans HCL blocks by running all registered checks against them
type Scanner struct {
}
// New creates a new Scanner
func New() *Scanner {
return &Scanner{}
}
// Find element in list
func checkInList(code RuleID, list []string) bool {
codeCurrent := fmt.Sprintf("%s", code)
for _, codeIgnored := range list {
if codeIgnored == codeCurrent {
return true
}
}
return false
}
// Scan takes all available hcl blocks and an optional context, and returns a slice of results. Each result indicates a potential security problem.
func (scanner *Scanner) Scan(blocks []*parser.Block, excludedChecksList []string) []Result {
var results []Result
context := &Context{blocks: blocks}
for _, block := range blocks {
for _, check := range GetRegisteredChecks() {
if check.IsRequiredForBlock(block) {
for _, result := range check.Run(block, context) {
if !scanner.checkRangeIgnored(result.RuleID, result.Range) && !checkInList(result.RuleID, excludedChecksList) {
result.Link = fmt.Sprintf("https://github.com/tfsec/tfsec/wiki/%s", result.RuleID)
results = append(results, result)
}
}
}
}
}
return results
}
func (scanner *Scanner) checkRangeIgnored(code RuleID, r parser.Range) bool {
raw, err := ioutil.ReadFile(r.Filename)
if err != nil {
return false
}
ignoreAll := "tfsec:ignore:*"
ignoreCode := fmt.Sprintf("tfsec:ignore:%s", code)
lines := append([]string{""}, strings.Split(string(raw), "\n")...)
for number := r.StartLine; number <= r.EndLine; number++ {
if number <= 0 || number >= len(lines) {
continue
}
if strings.Contains(lines[number], ignoreAll) || strings.Contains(lines[number], ignoreCode) {
return true
}
}
if r.StartLine-1 > 0 {
line := lines[r.StartLine-1]
line = strings.TrimSpace(strings.ReplaceAll(strings.ReplaceAll(line, "//", ""), "#", ""))
segments := strings.Split(line, " ")
for _, segment := range segments {
if segment == ignoreAll || segment == ignoreCode {
return true
}
}
}
return false
}