@@ -18,6 +18,7 @@ package sbom
1818
1919import (
2020 "context"
21+ "encoding/json"
2122 "fmt"
2223 "strings"
2324
@@ -31,6 +32,8 @@ import (
3132 aimage "github.com/aquasecurity/trivy/pkg/fanal/artifact/image"
3233 "github.com/aquasecurity/trivy/pkg/fanal/cache"
3334 "github.com/aquasecurity/trivy/pkg/fanal/image"
35+ "github.com/aquasecurity/trivy/pkg/fanal/secret"
36+ stypes "github.com/aquasecurity/trivy/pkg/fanal/types"
3437 "github.com/aquasecurity/trivy/pkg/fanal/utils"
3538 "github.com/docker/index-cli-plugin/registry"
3639 "github.com/docker/index-cli-plugin/types"
@@ -42,6 +45,7 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
4245 Name : "trivy" ,
4346 Status : types .Success ,
4447 Packages : make ([]types.Package , 0 ),
48+ Secrets : make ([]types.Secret , 0 ),
4549 }
4650
4751 defer close (resultChan )
@@ -80,6 +84,53 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
8084 }
8185
8286 a := applier .NewApplier (cacheClient )
87+ scanner , err := secret .NewScanner ("" )
88+ if err != nil {
89+ result .Status = types .Failed
90+ result .Error = errors .Wrap (err , "failed to create secret scanner" )
91+ resultChan <- result
92+ return
93+ }
94+ config := & cache .Source .Image .Metadata .Config
95+ for o , h := range config .History {
96+ js , _ := json .MarshalIndent (h , "" , " " )
97+ secrets := scanner .Scan (secret.ScanArgs {
98+ FilePath : "history" ,
99+ Content : js ,
100+ })
101+ if len (secrets .Findings ) > 0 {
102+ result .Secrets = append (result .Secrets , convertSecretFindings (secrets , types.SecretSource {
103+ Type : "history" ,
104+ Location : & types.Location {
105+ Ordinal : o ,
106+ Digest : lm .DigestByOrdinal [o ],
107+ DiffId : lm .DiffIdByOrdinal [o ],
108+ },
109+ }))
110+ }
111+ }
112+ for k , v := range config .Config .Labels {
113+ secrets := scanner .Scan (secret.ScanArgs {
114+ FilePath : "label" ,
115+ Content : []byte (fmt .Sprintf ("%s=%s" , k , v )),
116+ })
117+ if len (secrets .Findings ) > 0 {
118+ result .Secrets = append (result .Secrets , convertSecretFindings (secrets , types.SecretSource {
119+ Type : "label" ,
120+ }))
121+ }
122+ }
123+ for _ , l := range config .Config .Env {
124+ secrets := scanner .Scan (secret.ScanArgs {
125+ FilePath : "env" ,
126+ Content : []byte (l ),
127+ })
128+ if len (secrets .Findings ) > 0 {
129+ result .Secrets = append (result .Secrets , convertSecretFindings (secrets , types.SecretSource {
130+ Type : "env" ,
131+ }))
132+ }
133+ }
83134 for v := range imageInfo .BlobIDs {
84135 mergedLayer , err := a .ApplyLayers (imageInfo .ID , []string {imageInfo .BlobIDs [v ]})
85136 if err != nil {
@@ -92,6 +143,17 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
92143 return
93144 }
94145 }
146+ for _ , s := range mergedLayer .Secrets {
147+ result .Secrets = append (result .Secrets , convertSecretFindings (s , types.SecretSource {
148+ Type : "file" ,
149+ Location : & types.Location {
150+ Path : s .FilePath ,
151+ Ordinal : lm .OrdinalByDiffId [s .Layer .DiffID ],
152+ Digest : s .Layer .Digest ,
153+ DiffId : s .Layer .DiffID ,
154+ },
155+ }))
156+ }
95157 for _ , app := range mergedLayer .Applications {
96158 switch app .Type {
97159 case "gobinary" :
@@ -110,9 +172,10 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
110172 pkg := types.Package {
111173 Purl : purl .String (),
112174 Locations : []types.Location {{
113- Path : "/" + app .FilePath ,
114- Digest : lm .ByDiffId [lib .Layer .DiffID ],
115- DiffId : lib .Layer .DiffID ,
175+ Path : "/" + app .FilePath ,
176+ Ordinal : lm .OrdinalByDiffId [lib .Layer .DiffID ],
177+ Digest : lm .ByDiffId [lib .Layer .DiffID ],
178+ DiffId : lib .Layer .DiffID ,
116179 }},
117180 }
118181 result .Packages = append (result .Packages , pkg )
@@ -137,9 +200,10 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
137200 pkg := types.Package {
138201 Purl : purl .String (),
139202 Locations : []types.Location {{
140- Path : "/" + lib .FilePath ,
141- Digest : lm .ByDiffId [lib .Layer .DiffID ],
142- DiffId : lib .Layer .DiffID ,
203+ Path : "/" + lib .FilePath ,
204+ Ordinal : lm .OrdinalByDiffId [lib .Layer .DiffID ],
205+ Digest : lm .ByDiffId [lib .Layer .DiffID ],
206+ DiffId : lib .Layer .DiffID ,
143207 }},
144208 }
145209 result .Packages = append (result .Packages , pkg )
@@ -148,6 +212,7 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
148212 }
149213 }
150214 }
215+
151216 resultChan <- result
152217}
153218
@@ -157,3 +222,25 @@ func initializeCache() (cache.Cache, error) {
157222 cacheClient , err = cache .NewFSCache (utils .CacheDir ())
158223 return cacheClient , err
159224}
225+
226+ func convertSecretFindings (s stypes.Secret , source types.SecretSource ) types.Secret {
227+ secret := types.Secret {
228+ Source : source ,
229+ Findings : make ([]types.SecretFinding , 0 ),
230+ }
231+ for _ , f := range s .Findings {
232+ finding := types.SecretFinding {
233+ RuleID : f .RuleID ,
234+ Category : string (f .Category ),
235+ Title : f .Title ,
236+ Severity : f .Severity ,
237+ Match : f .Match ,
238+ }
239+ if source .Type == "file" {
240+ finding .StartLine = f .StartLine
241+ finding .EndLine = f .EndLine
242+ }
243+ secret .Findings = append (secret .Findings , finding )
244+ }
245+ return secret
246+ }
0 commit comments