github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/secrets/secrets.go (about) 1 // Copyright 2025 Google LLC 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 // Package secrets contains a Scalibr filesystem Extractor that wraps the Veles 16 // secret scanning library to find secrets (i.e. credentials) in files on the 17 // filesystem. 18 package secrets 19 20 import ( 21 "context" 22 "fmt" 23 "path/filepath" 24 "strings" 25 26 "github.com/google/osv-scalibr/extractor/filesystem" 27 "github.com/google/osv-scalibr/inventory" 28 "github.com/google/osv-scalibr/plugin" 29 "github.com/google/osv-scalibr/veles" 30 ) 31 32 const ( 33 // Name is the unique name of this extractor. 34 Name = "secrets/veles" 35 36 version = 1 37 ) 38 39 var ( 40 fileExtensions = map[string]bool{ 41 ".cfg": true, 42 ".env": true, 43 ".html": true, 44 ".ipynb": true, 45 ".json": true, 46 ".log": true, 47 ".md": true, 48 ".py": true, 49 ".textproto": true, 50 ".toml": true, 51 ".txt": true, 52 ".xml": true, 53 ".yaml": true, 54 ".pem": true, 55 ".crt": true, 56 ".key": true, 57 ".der": true, 58 ".cer": true, 59 ".pypirc": true, 60 } 61 ) 62 63 // Extractor extracts secrets from the filesystem using the Veles secret 64 // scanning library. 65 // Other than most extractors, it adds Secrets to the Inventory, not Packages. 66 type Extractor struct { 67 e *veles.DetectionEngine 68 } 69 70 // NewWithEngine creates a new Extractor that uses the specified 71 // DetectionEngine. 72 func NewWithEngine(e *veles.DetectionEngine) filesystem.Extractor { 73 return &Extractor{e: e} 74 } 75 76 // Name of the Extractor. 77 func (e Extractor) Name() string { 78 return Name 79 } 80 81 // Version of the Extractor. 82 func (e Extractor) Version() int { 83 return version 84 } 85 86 // Requirements of the Extractor. 87 func (e Extractor) Requirements() *plugin.Capabilities { 88 return &plugin.Capabilities{} 89 } 90 91 // FileRequired returns true, if the file should be checked for secrets. 92 func (e Extractor) FileRequired(api filesystem.FileAPI) bool { 93 ext := strings.ToLower(filepath.Ext(api.Path())) 94 return fileExtensions[ext] 95 } 96 97 // Extract extracts secrets from scan input. 98 func (e Extractor) Extract(ctx context.Context, input *filesystem.ScanInput) (inventory.Inventory, error) { 99 secrets, err := e.e.Detect(ctx, input.Reader) 100 if err != nil { 101 return inventory.Inventory{}, fmt.Errorf("unable to scan for secrets: %w", err) 102 } 103 i := inventory.Inventory{} 104 for _, s := range secrets { 105 i.Secrets = append(i.Secrets, &inventory.Secret{ 106 Secret: s, 107 Location: input.Path, 108 }) 109 } 110 return i, nil 111 }