@@ -18,6 +18,7 @@ package sbom
18
18
19
19
import (
20
20
"context"
21
+ "encoding/json"
21
22
"fmt"
22
23
"strings"
23
24
@@ -31,6 +32,8 @@ import (
31
32
aimage "github.com/aquasecurity/trivy/pkg/fanal/artifact/image"
32
33
"github.com/aquasecurity/trivy/pkg/fanal/cache"
33
34
"github.com/aquasecurity/trivy/pkg/fanal/image"
35
+ "github.com/aquasecurity/trivy/pkg/fanal/secret"
36
+ stypes "github.com/aquasecurity/trivy/pkg/fanal/types"
34
37
"github.com/aquasecurity/trivy/pkg/fanal/utils"
35
38
"github.com/docker/index-cli-plugin/registry"
36
39
"github.com/docker/index-cli-plugin/types"
@@ -42,6 +45,7 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
42
45
Name : "trivy" ,
43
46
Status : types .Success ,
44
47
Packages : make ([]types.Package , 0 ),
48
+ Secrets : make ([]types.Secret , 0 ),
45
49
}
46
50
47
51
defer close (resultChan )
@@ -80,6 +84,53 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
80
84
}
81
85
82
86
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
+ }
83
134
for v := range imageInfo .BlobIDs {
84
135
mergedLayer , err := a .ApplyLayers (imageInfo .ID , []string {imageInfo .BlobIDs [v ]})
85
136
if err != nil {
@@ -92,6 +143,17 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
92
143
return
93
144
}
94
145
}
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
+ }
95
157
for _ , app := range mergedLayer .Applications {
96
158
switch app .Type {
97
159
case "gobinary" :
@@ -110,9 +172,10 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
110
172
pkg := types.Package {
111
173
Purl : purl .String (),
112
174
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 ,
116
179
}},
117
180
}
118
181
result .Packages = append (result .Packages , pkg )
@@ -137,9 +200,10 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
137
200
pkg := types.Package {
138
201
Purl : purl .String (),
139
202
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 ,
143
207
}},
144
208
}
145
209
result .Packages = append (result .Packages , pkg )
@@ -148,6 +212,7 @@ func trivySbom(cache *registry.ImageCache, lm *types.LayerMapping, resultChan ch
148
212
}
149
213
}
150
214
}
215
+
151
216
resultChan <- result
152
217
}
153
218
@@ -157,3 +222,25 @@ func initializeCache() (cache.Cache, error) {
157
222
cacheClient , err = cache .NewFSCache (utils .CacheDir ())
158
223
return cacheClient , err
159
224
}
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