Skip to content

Commit

Permalink
Allow overriding risk magnitudes
Browse files Browse the repository at this point in the history
  • Loading branch information
jaym committed Jul 8, 2024
1 parent a3c2374 commit 2ec3464
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 7 deletions.
71 changes: 64 additions & 7 deletions policy/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ type resolverCache struct {
assetFiltersChecksum string
assetFilters map[string]struct{}
codeIdToMrn map[string][]string

risksFactors map[string]*RiskFactor
// assigned queries, listed by their UUID (i.e. policy context)
executionQueries map[string]*ExecutionQuery
dataQueries map[string]struct{}
Expand Down Expand Up @@ -528,6 +528,7 @@ func (s *LocalServices) tryResolve(ctx context.Context, bundleMrn string, assetF
reportingJobsByMsum: map[string][]*ReportingJob{},
reportingJobsByCodeId: map[string][]*ReportingJob{},
reportingJobsActive: map[string]bool{},
risksFactors: map[string]*RiskFactor{},
bundleMap: bundleMap,
compilerConfig: conf,
}
Expand All @@ -544,6 +545,14 @@ func (s *LocalServices) tryResolve(ctx context.Context, bundleMrn string, assetF

cache.reportingJobsByUUID[reportingJob.Uuid] = reportingJob

if err := s.collectRisks(ctx, cache, bundleMrn); err != nil {
logCtx.Error().
Err(err).
Str("bundle", bundleMrn).
Msg("resolver> internal error, trying to collect risk modifications")
return nil, err
}

// phase 2: optimizations for assets
// assets are always connected to a space, so figure out if a space policy exists
// everything else in an asset can be aggregated into a shared policy
Expand Down Expand Up @@ -710,6 +719,37 @@ func (s *LocalServices) refreshChecksums(executionJob *ExecutionJob, collectorJo
}
}

func (s *LocalServices) collectRisks(ctx context.Context, cache *resolverCache, policyMrn string) error {
policyObj, ok := cache.bundleMap.Policies[policyMrn]
if !ok || policyObj == nil {
return errors.New("cannot find policy '" + policyMrn + "' while resolving")
}

for _, g := range policyObj.Groups {
for _, p := range g.Policies {
if err := s.collectRisks(ctx, cache, p.Mrn); err != nil {
return err
}
}
}

for _, rf := range policyObj.RiskFactors {
s.mergeRisk(cache, rf)
}

return nil
}

func (s *LocalServices) mergeRisk(cache *resolverCache, riskFactor *RiskFactor) {
if existing, ok := cache.risksFactors[riskFactor.Mrn]; ok {
if riskFactor.Magnitude != nil {
existing.Magnitude = riskFactor.Magnitude
}
} else {
cache.risksFactors[riskFactor.Mrn] = riskFactor
}
}

func (s *LocalServices) policyToJobs(ctx context.Context, policyMrn string, ownerJob *ReportingJob,
parentCache *policyResolverCache, now time.Time,
) error {
Expand Down Expand Up @@ -803,8 +843,11 @@ func (s *LocalServices) policyToJobs(ctx context.Context, policyMrn string, owne

func (s *LocalServices) risksToJobs(ctx context.Context, policy *Policy, ownerJob *ReportingJob, cache *policyResolverCache) error {
matchingRisks := map[string]*RiskFactor{}
for i := range policy.RiskFactors {
rf := policy.RiskFactors[i]
for _, policyRf := range policy.RiskFactors {
rf := cache.global.risksFactors[policyRf.Mrn]
if rf == nil {
return errors.New("cannot find risk factor '" + policyRf.Mrn + "' while resolving")
}
if rf.Filters != nil {
for j := range rf.Filters.Items {
filter := rf.Filters.Items[j]
Expand All @@ -820,21 +863,35 @@ func (s *LocalServices) risksToJobs(ctx context.Context, policy *Policy, ownerJo
}

for _, risk := range matchingRisks {
magnitude := risk.Magnitude

cache.global.riskInfos[risk.Mrn] = &RiskFactor{
Scope: risk.Scope,
Magnitude: risk.Magnitude,
Magnitude: magnitude,
Resources: risk.Resources,
DeprecatedV11Magnitude: risk.GetMagnitude().GetValue(),
DeprecatedV11IsAbsolute: risk.GetMagnitude().GetIsToxic(),
DeprecatedV11Magnitude: magnitude.GetValue(),
DeprecatedV11IsAbsolute: magnitude.GetIsToxic(),
}

rjUuid := cache.global.relativeChecksum(risk.Mrn)

if riskJob := cache.global.reportingJobsByUUID[rjUuid]; riskJob != nil {
ownerJob.ChildJobs[riskJob.Uuid] = &explorer.Impact{
Scoring: explorer.ScoringSystem_IGNORE_SCORE,
}

riskJob.Notify = append(riskJob.Notify, ownerJob.Uuid)
continue
}

riskJob := &ReportingJob{
QrId: risk.Mrn,
Uuid: cache.global.relativeChecksum(risk.Mrn),
Uuid: rjUuid,
ChildJobs: map[string]*explorer.Impact{},
Type: ReportingJob_RISK_FACTOR,
Notify: []string{ownerJob.Uuid},
}

cache.global.reportingJobsByUUID[riskJob.Uuid] = riskJob
ownerJob.ChildJobs[riskJob.Uuid] = &explorer.Impact{
Scoring: explorer.ScoringSystem_IGNORE_SCORE,
Expand Down
85 changes: 85 additions & 0 deletions policy/resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1718,3 +1718,88 @@ queries:
require.Equal(t, queryMrn("variant2"), qrIdToRj[b.Queries[2].CodeId].Mrns[1])
})
}

func TestResolve_RiskFactors(t *testing.T) {
b := parseBundle(t, `
owner_mrn: //test.sth
queries:
- uid: query-1
title: query-1
mql: 1 == 1
- uid: query-2
title: query-2
mql: 1 == 2
policies:
- name: testpolicy1
uid: testpolicy1
risk_factors:
- uid: sshd-service
magnitude: 0.9
groups:
- filters: asset.name == "asset1"
checks:
- uid: query-1
- uid: query-2
policies:
- uid: risk-factors-security
- uid: risk-factors-security
name: Mondoo Risk Factors analysis
version: "1.0.0"
risk_factors:
- uid: sshd-service
title: SSHd Service running
indicator: asset-in-use
magnitude: 0.6
filters:
- mql: |
asset.name == "asset1"
checks:
- uid: sshd-service-running
mql: 1 == 1
- uid: sshd-service-na
title: SSHd Service running
indicator: asset-in-use
magnitude: 0.5
filters:
- mql: |
return false
checks:
- uid: sshd-service-running-na
mql: 1 == 2
`)

srv := initResolver(t, []*testAsset{
{asset: "asset1", policies: []string{policyMrn("testpolicy1")}},
}, []*policy.Bundle{b})

rp, err := srv.Resolve(context.Background(), &policy.ResolveReq{
PolicyMrn: "asset1",
AssetFilters: []*explorer.Mquery{{Mql: "asset.name == \"asset1\""}},
})
require.NoError(t, err)
require.NotNil(t, rp)

qrIdToRj := map[string]*policy.ReportingJob{}
for _, rj := range rp.CollectorJob.ReportingJobs {
qrIdToRj[rj.QrId] = rj
}

require.Len(t, rp.CollectorJob.ReportingJobs, 7)
require.NotNil(t, qrIdToRj[policyMrn("testpolicy1")])
require.NotNil(t, qrIdToRj[policyMrn("risk-factors-security")])
rfRj := qrIdToRj["//test.sth/risks/sshd-service"]
require.NotNil(t, rfRj)
require.Nil(t, qrIdToRj["//test.sth/risks/sshd-service-na"])

var queryRjUuid string
for uuid := range rfRj.ChildJobs {
queryRjUuid = uuid
}
require.NotEmpty(t, queryRjUuid)
queryRj := rp.CollectorJob.ReportingJobs[queryRjUuid]
require.NotNil(t, queryRj)

require.Contains(t, rfRj.ChildJobs, queryRj.Uuid)

require.Equal(t, float32(0.9), rp.CollectorJob.RiskFactors["//test.sth/risks/sshd-service"].Magnitude.GetValue())
}

0 comments on commit 2ec3464

Please sign in to comment.