Skip to content

Commit e1a6705

Browse files
committed
Pull out additional Generate logic into functions; add tests
Signed-off-by: egibs <20933572+egibs@users.noreply.github.com>
1 parent e7d9568 commit e1a6705

2 files changed

Lines changed: 352 additions & 21 deletions

File tree

pkg/report/report.go

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,51 @@ func fileMatchesRule(meta []yarax.Metadata, ext string) bool {
377377
return true
378378
}
379379

380+
// skipMatch determines whether to avoid processing a rule match.
381+
func skipMatch(ignoreMalcontent, override, scan bool, risk, threshold, highestRisk int) bool {
382+
switch {
383+
case risk == -1:
384+
return true
385+
// The malcontent rule is classified as harmless
386+
// A !ignoreMalcontent condition will prevent the rule from being filtered
387+
case !scan && risk < threshold && !ignoreMalcontent && !override:
388+
return true
389+
// If running a scan as opposed to an analyze,
390+
// drop any matches that fall below the highest risk
391+
case scan && risk < highestRisk && !ignoreMalcontent && !override:
392+
return true
393+
}
394+
return false
395+
}
396+
397+
// skipScanFile determines whether a scanned file should
398+
// be ignored when running a scan and the file's risk is below HIGH.
399+
func skipScanFile(scan bool, overallRiskScore int) bool {
400+
if scan && overallRiskScore < HIGH {
401+
return true
402+
}
403+
return false
404+
}
405+
406+
// applyCriticalUpgrade evaluates whether to apply a risk increase
407+
// depending on c.QuantityIncreasesRisk, the file's high behavior count, and the file's size.
408+
func applyCriticalUpgrade(ctx context.Context, quantityIncreasesRisk bool, riskCounts map[int]int, overallRiskScore int, size int64) bool {
409+
// If something has a lot of high, it's probably critical
410+
if quantityIncreasesRisk && upgradeRisk(ctx, overallRiskScore, riskCounts, size) {
411+
return true
412+
}
413+
return false
414+
}
415+
416+
// isMalcontent determines whether the scanned file is the malcontent binary itself
417+
// which causes false positives and is generally better to ignore entirely.
418+
func isMalcontent(path string) bool {
419+
if strings.ToLower(filepath.Base(path)) == NAME || strings.ToLower(filepath.Base(path)) == "mal" {
420+
return true
421+
}
422+
return false
423+
}
424+
380425
func Generate(ctx context.Context, path string, mrs *yarax.ScanResults, c malcontent.Config, expath string, _ *clog.Logger, fc []byte, kind *programkind.FileType, highestRisk int) (*malcontent.FileReport, error) {
381426
if ctx.Err() != nil {
382427
return &malcontent.FileReport{}, ctx.Err()
@@ -416,27 +461,17 @@ func Generate(ctx context.Context, path string, mrs *yarax.ScanResults, c malcon
416461
ignoreMalcontent = true
417462
}
418463

419-
if kind != nil && kind.Ext != "" {
420-
if !fileMatchesRule(m.Metadata(), kind.Ext) {
421-
continue
422-
}
464+
if kind != nil && kind.Ext != "" && !fileMatchesRule(m.Metadata(), kind.Ext) {
465+
continue
423466
}
424467

425468
override := slices.Contains(m.Tags(), "override")
426469

427470
risk = behaviorRisk(m.Namespace(), m.Identifier(), m.Tags())
428471
overallRiskScore = max(overallRiskScore, risk)
429472
riskCounts[risk]++
430-
// The malcontent rule is classified as harmless
431-
// A !ignoreMalcontent condition will prevent the rule from being filtered
432-
// If running a scan as opposed to an analyze,
433-
// drop any matches that fall below the highest risk
434-
switch {
435-
case risk == -1:
436-
continue
437-
case !c.Scan && risk < minScore && !ignoreMalcontent && !override:
438-
continue
439-
case c.Scan && risk < highestRisk && !c.QuantityIncreasesRisk && !ignoreMalcontent && !override:
473+
474+
if skipMatch(ignoreMalcontent, override, c.Scan, risk, minScore, highestRisk) {
440475
continue
441476
}
442477

@@ -488,19 +523,15 @@ func Generate(ctx context.Context, path string, mrs *yarax.ScanResults, c malcon
488523
// Scans will still need to drop <= medium results
489524
overallRiskScore = highestBehaviorRisk(fr)
490525

491-
// If something has a lot of high, it's probably critical
492-
if c.QuantityIncreasesRisk && upgradeRisk(ctx, overallRiskScore, riskCounts, size) {
526+
if applyCriticalUpgrade(ctx, c.QuantityIncreasesRisk, riskCounts, overallRiskScore, size) {
493527
overallRiskScore = CRITICAL
494528
}
495529

496-
if c.Scan && overallRiskScore < HIGH {
530+
if skipScanFile(c.Scan, overallRiskScore) {
497531
fr.Skipped = "overall risk too low for scan"
498532
}
499533

500-
// Check for both the full and shortened variants of malcontent
501-
isMalBinary := (filepath.Base(path) == NAME || filepath.Base(path) == "mal")
502-
503-
if all(ignoreSelf, fr.IsMalcontent, ignoreMalcontent, isMalBinary) {
534+
if all(ignoreSelf, fr.IsMalcontent, ignoreMalcontent, isMalcontent(path)) {
504535
fr.Skipped = "ignoring malcontent binary"
505536
}
506537

0 commit comments

Comments
 (0)