github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/cloud/aws/scanner/scanner.go (about) 1 package scanner 2 3 import ( 4 "context" 5 "fmt" 6 "io/fs" 7 8 "golang.org/x/xerrors" 9 10 "github.com/aquasecurity/defsec/pkg/framework" 11 "github.com/aquasecurity/defsec/pkg/scan" 12 "github.com/aquasecurity/defsec/pkg/scanners/options" 13 "github.com/aquasecurity/defsec/pkg/state" 14 aws "github.com/aquasecurity/trivy-aws/pkg/scanner" 15 "github.com/devseccon/trivy/pkg/cloud/aws/cache" 16 "github.com/devseccon/trivy/pkg/commands/operation" 17 "github.com/devseccon/trivy/pkg/flag" 18 "github.com/devseccon/trivy/pkg/log" 19 "github.com/devseccon/trivy/pkg/misconf" 20 ) 21 22 type AWSScanner struct { 23 } 24 25 func NewScanner() *AWSScanner { 26 return &AWSScanner{} 27 } 28 29 func (s *AWSScanner) Scan(ctx context.Context, option flag.Options) (scan.Results, bool, error) { 30 31 awsCache := cache.New(option.CacheDir, option.MaxCacheAge, option.Account, option.Region) 32 included, missing := awsCache.ListServices(option.Services) 33 34 var scannerOpts []options.ScannerOption 35 if !option.NoProgress { 36 tracker := newProgressTracker() 37 defer tracker.Finish() 38 scannerOpts = append(scannerOpts, aws.ScannerWithProgressTracker(tracker)) 39 } 40 41 if len(missing) > 0 { 42 scannerOpts = append(scannerOpts, aws.ScannerWithAWSServices(missing...)) 43 } 44 45 if option.Debug { 46 scannerOpts = append(scannerOpts, options.ScannerWithDebug(&log.PrefixedLogger{Name: "aws"})) 47 } 48 49 if option.Trace { 50 scannerOpts = append(scannerOpts, options.ScannerWithTrace(&log.PrefixedLogger{Name: "aws"})) 51 } 52 53 if option.Region != "" { 54 scannerOpts = append( 55 scannerOpts, 56 aws.ScannerWithAWSRegion(option.Region), 57 ) 58 } 59 60 if option.Endpoint != "" { 61 scannerOpts = append( 62 scannerOpts, 63 aws.ScannerWithAWSEndpoint(option.Endpoint), 64 ) 65 } 66 67 var policyPaths []string 68 var downloadedPolicyPaths []string 69 var err error 70 downloadedPolicyPaths, err = operation.InitBuiltinPolicies(context.Background(), option.CacheDir, option.Quiet, option.SkipPolicyUpdate, option.MisconfOptions.PolicyBundleRepository) 71 if err != nil { 72 if !option.SkipPolicyUpdate { 73 log.Logger.Errorf("Falling back to embedded policies: %s", err) 74 } 75 } else { 76 log.Logger.Debug("Policies successfully loaded from disk") 77 policyPaths = append(policyPaths, downloadedPolicyPaths...) 78 scannerOpts = append(scannerOpts, 79 options.ScannerWithEmbeddedPolicies(false), 80 options.ScannerWithEmbeddedLibraries(false)) 81 } 82 83 var policyFS fs.FS 84 policyFS, policyPaths, err = misconf.CreatePolicyFS(append(policyPaths, option.RegoOptions.PolicyPaths...)) 85 if err != nil { 86 return nil, false, xerrors.Errorf("unable to create policyfs: %w", err) 87 } 88 89 scannerOpts = append(scannerOpts, 90 options.ScannerWithPolicyFilesystem(policyFS), 91 options.ScannerWithPolicyDirs(policyPaths...), 92 ) 93 94 dataFS, dataPaths, err := misconf.CreateDataFS(option.RegoOptions.DataPaths) 95 if err != nil { 96 log.Logger.Errorf("Could not load config data: %s", err) 97 } 98 scannerOpts = append(scannerOpts, 99 options.ScannerWithDataDirs(dataPaths...), 100 options.ScannerWithDataFilesystem(dataFS), 101 ) 102 103 scannerOpts = addPolicyNamespaces(option.RegoOptions.PolicyNamespaces, scannerOpts) 104 105 if option.Compliance.Spec.ID != "" { 106 scannerOpts = append(scannerOpts, options.ScannerWithSpec(option.Compliance.Spec.ID)) 107 } else { 108 scannerOpts = append(scannerOpts, options.ScannerWithFrameworks( 109 framework.Default, 110 framework.CIS_AWS_1_2)) 111 } 112 113 scanner := aws.New(scannerOpts...) 114 115 var freshState *state.State 116 if len(missing) > 0 || option.CloudOptions.UpdateCache { 117 var err error 118 freshState, err = scanner.CreateState(ctx) 119 if err != nil { 120 return nil, false, err 121 } 122 } 123 124 fullState, err := createState(freshState, awsCache) 125 if err != nil { 126 return nil, false, err 127 } 128 129 if fullState == nil { 130 return nil, false, fmt.Errorf("no resultant state found") 131 } 132 133 if err := awsCache.AddServices(fullState, missing); err != nil { 134 return nil, false, err 135 } 136 137 defsecResults, err := scanner.Scan(ctx, fullState) 138 if err != nil { 139 return nil, false, err 140 } 141 142 return defsecResults, len(included) > 0, nil 143 } 144 145 func createState(freshState *state.State, awsCache *cache.Cache) (*state.State, error) { 146 var fullState *state.State 147 if previousState, err := awsCache.LoadState(); err == nil { 148 if freshState != nil { 149 fullState, err = previousState.Merge(freshState) 150 if err != nil { 151 return nil, err 152 } 153 } else { 154 fullState = previousState 155 } 156 } else { 157 fullState = freshState 158 } 159 return fullState, nil 160 } 161 162 func addPolicyNamespaces(namespaces []string, scannerOpts []options.ScannerOption) []options.ScannerOption { 163 if len(namespaces) > 0 { 164 scannerOpts = append( 165 scannerOpts, 166 options.ScannerWithPolicyNamespaces(namespaces...), 167 ) 168 } 169 return scannerOpts 170 }