Skip to content

Commit dfe1f8f

Browse files
kendrickcurtisafsmeira
authored andcommitted
bugfix in tool.go to live with nil PURLs and fixed absent line number reporting in openssf scanner
1 parent f41a50a commit dfe1f8f

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

internal/tool/openssf_scanner.go

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"encoding/json"
88
"fmt"
99
"log"
10+
"net/url"
1011
"os"
1112
"path/filepath"
1213
"runtime"
@@ -131,6 +132,11 @@ func (s *OpenSSFScanner) checkPackage(pkg ftypes.Package, target string, toolExe
131132
pkgType := s.getPackageType(pkg)
132133
pkgNameLower := strings.ToLower(pkg.Name)
133134

135+
// If we can't determine package type from PURL, try to infer it from the target file
136+
if pkgType == "" {
137+
pkgType = s.inferPackageTypeFromTarget(target)
138+
}
139+
134140
candidates := s.lookup(pkgType, pkgNameLower)
135141
if len(candidates) == 0 {
136142
return nil
@@ -144,6 +150,32 @@ func (s *OpenSSFScanner) checkPackage(pkg ftypes.Package, target string, toolExe
144150
return nil
145151
}
146152

153+
// inferPackageTypeFromTarget tries to infer the package type from the target file path
154+
func (s *OpenSSFScanner) inferPackageTypeFromTarget(target string) string {
155+
switch {
156+
case strings.HasSuffix(target, "package.json"):
157+
return "npm"
158+
case strings.HasSuffix(target, "package-lock.json"):
159+
return "npm"
160+
case strings.HasSuffix(target, "yarn.lock"):
161+
return "npm"
162+
case strings.HasSuffix(target, "go.mod"):
163+
return "golang"
164+
case strings.HasSuffix(target, "requirements.txt"):
165+
return "pypi"
166+
case strings.HasSuffix(target, "Pipfile"):
167+
return "pypi"
168+
case strings.HasSuffix(target, "poetry.lock"):
169+
return "pypi"
170+
case strings.HasSuffix(target, "pom.xml"):
171+
return "maven"
172+
case strings.HasSuffix(target, "build.gradle"):
173+
return "gradle"
174+
default:
175+
return ""
176+
}
177+
}
178+
147179
// getPackageType extracts the package type from PURL
148180
func (s *OpenSSFScanner) getPackageType(pkg ftypes.Package) string {
149181
if pkg.Identifier.PURL != nil {
@@ -152,6 +184,20 @@ func (s *OpenSSFScanner) getPackageType(pkg ftypes.Package) string {
152184
return ""
153185
}
154186

187+
// getPackageDisplayName returns a display name for the package, handling nil PURLs
188+
func (s *OpenSSFScanner) getPackageDisplayName(pkg ftypes.Package) string {
189+
if pkg.Identifier.PURL != nil {
190+
// Use the same logic as the main tool for consistency
191+
purlStripPkg := strings.TrimPrefix(pkg.Identifier.PURL.ToString(), "pkg:")
192+
if ppp, err := url.PathUnescape(purlStripPkg); err == nil {
193+
return ppp
194+
}
195+
return purlStripPkg
196+
}
197+
// Fallback to package name when PURL is not available
198+
return pkg.Name
199+
}
200+
155201
// createIssue creates a malicious package issue
156202
func (s *OpenSSFScanner) createIssue(pkg ftypes.Package, target string, cand osvShallow, toolExecution codacy.ToolExecution) []codacy.Result {
157203
lineNumber := s.findPackageLineNumber(toolExecution.SourceDir, target, pkg.Name)
@@ -197,7 +243,7 @@ func (s *OpenSSFScanner) scanNpmManifest(sourceDir, relativePath string, knownFi
197243
return nil
198244
}
199245

200-
return s.checkNpmDependencies(pj.Dependencies, relativePath)
246+
return s.checkNpmDependencies(pj.Dependencies, sourceDir, relativePath)
201247
}
202248

203249
// parseNpmPackage parses an npm package.json file
@@ -216,18 +262,18 @@ func (s *OpenSSFScanner) parseNpmPackage(sourceDir, relativePath string) (*npmPk
216262
}
217263

218264
// checkNpmDependencies checks npm dependencies for malicious packages
219-
func (s *OpenSSFScanner) checkNpmDependencies(dependencies map[string]string, relativePath string) []codacy.Result {
265+
func (s *OpenSSFScanner) checkNpmDependencies(dependencies map[string]string, sourceDir, relativePath string) []codacy.Result {
220266
var out []codacy.Result
221267
for name, ver := range dependencies {
222-
if issue := s.checkNpmDependency(name, ver, relativePath); issue != nil {
268+
if issue := s.checkNpmDependency(name, ver, sourceDir, relativePath); issue != nil {
223269
out = append(out, *issue)
224270
}
225271
}
226272
return out
227273
}
228274

229275
// checkNpmDependency checks a single npm dependency
230-
func (s *OpenSSFScanner) checkNpmDependency(name, ver, relativePath string) *codacy.Issue {
276+
func (s *OpenSSFScanner) checkNpmDependency(name, ver, sourceDir, relativePath string) *codacy.Issue {
231277
pkgNameLower := strings.ToLower(name)
232278
candidates := s.lookup("npm", pkgNameLower)
233279
if len(candidates) == 0 {
@@ -236,10 +282,11 @@ func (s *OpenSSFScanner) checkNpmDependency(name, ver, relativePath string) *cod
236282

237283
for _, cand := range candidates {
238284
if s.versionMatches(ver, cand.Versions, cand.Ranges) {
285+
lineNumber := s.findPackageLineNumber(sourceDir, relativePath, name)
239286
issue := codacy.Issue{
240287
File: relativePath,
241288
Message: fmt.Sprintf("Malicious package detected: %s@%s - %s", name, ver, cand.Summary),
242-
Line: 1,
289+
Line: lineNumber,
243290
PatternID: ruleIDMaliciousPackages,
244291
SourceID: cand.ID,
245292
}

internal/tool/tool.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,11 @@ func (t codacyTrivy) getVulnerabilities(ctx context.Context, report ptypes.Repor
193193
}
194194

195195
for _, vuln := range result.Vulnerabilities {
196+
// Skip vulnerabilities without a valid PURL to avoid panic
196197
if vuln.PkgIdentifier.PURL == nil {
197198
continue
198199
}
200+
199201
purl := vuln.PkgIdentifier.PURL.ToString()
200202
// If the line number is not available, use the fallback.
201203
if value, ok := lineNumberByPurl[purl]; !ok || value == 0 {
@@ -231,6 +233,9 @@ func (t codacyTrivy) getVulnerabilities(ctx context.Context, report ptypes.Repor
231233

232234
}
233235

236+
if toolExecution.Files == nil {
237+
return mapIssuesWithoutLineNumber(issues), nil
238+
}
234239
return mapIssuesWithoutLineNumber(filterIssuesFromKnownFiles(issues, *toolExecution.Files)), nil
235240
}
236241

0 commit comments

Comments
 (0)