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  }