This reverts commit 562dd7242b.
This commit is contained in:
@@ -280,7 +280,14 @@ trufflehog gcs --project-id=<project-ID> --cloud-environment --results=verified,
|
||||
Use the `--image` flag multiple times to scan multiple images.
|
||||
|
||||
```bash
|
||||
# to scan from a remote registry
|
||||
trufflehog docker --image trufflesecurity/secrets --results=verified,unknown
|
||||
|
||||
# to scan from the local docker daemon
|
||||
trufflehog docker --image docker://new_image:tag --results=verified,unknown
|
||||
|
||||
# to scan from an image saved as a tarball
|
||||
trufflehog docker --image file://path_to_image.tar --results=verified,unknown
|
||||
```
|
||||
|
||||
## 12: Scan in CI
|
||||
@@ -672,7 +679,7 @@ TruffleHog will send a JSON POST request containing the regex matches to a
|
||||
configured webhook endpoint. If the endpoint responds with a `200 OK` response
|
||||
status code, the secret is considered verified.
|
||||
|
||||
Custom Detectors support a few different filtering mechanisms: entropy, regex targeting the entire match, regex targeting the captured secret,
|
||||
Custom Detectors support a few different filtering mechanisms: entropy, regex targeting the entire match, regex targeting the captured secret,
|
||||
and excluded word lists checked against the secret (captured group if present, entire match if capture group is not present). Note that if
|
||||
your custom detector has multiple `regex` set (in this example `hogID`, and `hogToken`), then the filters get applied to each regex. [Here](examples/generic_with_filters.yml) is an example of a custom detector using these filters.
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ var (
|
||||
circleCiScanToken = circleCiScan.Flag("token", "CircleCI token. Can also be provided with environment variable").Envar("CIRCLECI_TOKEN").Required().String()
|
||||
|
||||
dockerScan = cli.Command("docker", "Scan Docker Image")
|
||||
dockerScanImages = dockerScan.Flag("image", "Docker image to scan. Use the file:// prefix to point to a local tarball, otherwise a image registry is assumed.").Required().Strings()
|
||||
dockerScanImages = dockerScan.Flag("image", "Docker image to scan. Use the file:// prefix to point to a local tarball, the docker:// prefix to point to the docker daemon, otherwise an image registry is assumed.").Required().Strings()
|
||||
dockerScanToken = dockerScan.Flag("token", "Docker bearer token. Can also be provided with environment variable").Envar("DOCKER_TOKEN").String()
|
||||
dockerExcludePaths = dockerScan.Flag("exclude-paths", "Comma separated list of paths to exclude from scan").String()
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/daemon"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
"github.com/google/go-containerregistry/pkg/v1/tarball"
|
||||
gzip "github.com/klauspost/pgzip"
|
||||
@@ -179,8 +180,8 @@ func (s *Source) Chunks(ctx context.Context, chunksChan chan *sources.Chunk, _ .
|
||||
func (s *Source) processImage(ctx context.Context, image string) (imageInfo, error) {
|
||||
var (
|
||||
imgInfo imageInfo
|
||||
hasDigest bool
|
||||
imageName name.Reference
|
||||
err error
|
||||
)
|
||||
|
||||
remoteOpts, err := s.remoteOpts()
|
||||
@@ -189,6 +190,7 @@ func (s *Source) processImage(ctx context.Context, image string) (imageInfo, err
|
||||
}
|
||||
|
||||
const filePrefix = "file://"
|
||||
const dockerPrefix = "docker://"
|
||||
if strings.HasPrefix(image, filePrefix) {
|
||||
image = strings.TrimPrefix(image, filePrefix)
|
||||
imgInfo.base = image
|
||||
@@ -196,18 +198,21 @@ func (s *Source) processImage(ctx context.Context, image string) (imageInfo, err
|
||||
if err != nil {
|
||||
return imgInfo, err
|
||||
}
|
||||
} else if strings.HasPrefix(image, dockerPrefix) {
|
||||
image = strings.TrimPrefix(image, dockerPrefix)
|
||||
imgInfo, imageName, err = s.extractImageNameTagDigest(image)
|
||||
if err != nil {
|
||||
return imgInfo, err
|
||||
}
|
||||
imgInfo.image, err = daemon.Image(imageName)
|
||||
if err != nil {
|
||||
return imgInfo, err
|
||||
}
|
||||
} else {
|
||||
imgInfo.base, imgInfo.tag, hasDigest = baseAndTagFromImage(image)
|
||||
|
||||
if hasDigest {
|
||||
imageName, err = name.NewDigest(image)
|
||||
} else {
|
||||
imageName, err = name.NewTag(image)
|
||||
}
|
||||
imgInfo, imageName, err = s.extractImageNameTagDigest(image)
|
||||
if err != nil {
|
||||
return imgInfo, err
|
||||
}
|
||||
|
||||
imgInfo.image, err = remote.Image(imageName, remoteOpts...)
|
||||
if err != nil {
|
||||
return imgInfo, err
|
||||
@@ -219,6 +224,29 @@ func (s *Source) processImage(ctx context.Context, image string) (imageInfo, err
|
||||
return imgInfo, nil
|
||||
}
|
||||
|
||||
// extractImageNameTagDigest parses the provided Docker image string and returns a name.Reference
|
||||
// representing either the image's tag or digest, and any error encountered during parsing.
|
||||
func (*Source) extractImageNameTagDigest(image string) (imageInfo, name.Reference, error) {
|
||||
var (
|
||||
hasDigest bool
|
||||
imgInfo imageInfo
|
||||
imgName name.Reference
|
||||
err error
|
||||
)
|
||||
imgInfo.base, imgInfo.tag, hasDigest = baseAndTagFromImage(image)
|
||||
|
||||
if hasDigest {
|
||||
imgName, err = name.NewDigest(image)
|
||||
} else {
|
||||
imgName, err = name.NewTag(image)
|
||||
}
|
||||
if err != nil {
|
||||
return imgInfo, imgName, err
|
||||
}
|
||||
|
||||
return imgInfo, imgName, nil
|
||||
}
|
||||
|
||||
// getHistoryEntries collates an image's configuration history together with the
|
||||
// corresponding layer digests for any non-empty layers.
|
||||
func getHistoryEntries(ctx context.Context, imgInfo imageInfo, layers []v1.Layer) ([]historyEntryInfo, error) {
|
||||
|
||||
@@ -134,6 +134,78 @@ func TestDockerImageScanWithDigest(t *testing.T) {
|
||||
assert.Equal(t, 1, historyCounter)
|
||||
}
|
||||
|
||||
func TestDockerImageScanFromLocalDaemon(t *testing.T) {
|
||||
dockerDaemonTestCases := []struct {
|
||||
name string
|
||||
image string
|
||||
}{
|
||||
{
|
||||
name: "TestDockerImageScanFromLocalDaemon",
|
||||
image: "docker://trufflesecurity/secrets",
|
||||
},
|
||||
{
|
||||
name: "TestDockerImageScanFromLocalDaemonWithDigest",
|
||||
image: "docker://trufflesecurity/secrets@sha256:864f6d41209462d8e37fc302ba1532656e265f7c361f11e29fed6ca1f4208e11",
|
||||
},
|
||||
{
|
||||
name: "TestDockerImageScanFromLocalDaemonWithTag",
|
||||
image: "docker://trufflesecurity/secrets:latest",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range dockerDaemonTestCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// This test assumes the local Docker daemon is running and the image exists locally.
|
||||
// You may need to pull or build the image "trufflesecurity/secrets" locally before running this test.
|
||||
dockerConn := &sourcespb.Docker{
|
||||
Credential: &sourcespb.Docker_Unauthenticated{
|
||||
Unauthenticated: &credentialspb.Unauthenticated{},
|
||||
},
|
||||
Images: []string{tt.image},
|
||||
}
|
||||
|
||||
conn := &anypb.Any{}
|
||||
err := conn.MarshalFrom(dockerConn)
|
||||
assert.NoError(t, err)
|
||||
|
||||
s := &Source{}
|
||||
err = s.Init(context.TODO(), "test source", 0, 0, false, conn, 1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
chunksChan := make(chan *sources.Chunk, 1)
|
||||
chunkCounter := 0
|
||||
layerCounter := 0
|
||||
historyCounter := 0
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for chunk := range chunksChan {
|
||||
assert.NotEmpty(t, chunk)
|
||||
chunkCounter++
|
||||
|
||||
if isHistoryChunk(t, chunk) {
|
||||
historyCounter++
|
||||
} else {
|
||||
layerCounter++
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
err = s.Chunks(context.TODO(), chunksChan)
|
||||
assert.NoError(t, err)
|
||||
|
||||
close(chunksChan)
|
||||
wg.Wait()
|
||||
|
||||
assert.Equal(t, 2, chunkCounter)
|
||||
assert.Equal(t, 1, layerCounter)
|
||||
assert.Equal(t, 1, historyCounter)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseAndTagFromImage(t *testing.T) {
|
||||
tests := []struct {
|
||||
image string
|
||||
|
||||
Reference in New Issue
Block a user