precogly / precogly/precogly

Prevent cross-threat mitigation credit in residual risk scoring

Open
#495 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
155
Forks
37
Avg merge
1d 17h
Merged PRs (30d)
82

Description

## Summary

Residual-risk calculation can grant mitigation credit from one linked threat to an entirely different linked threat that remains exposed.

## Steps to reproduce

1. Create a risk with a high inherent score.
2. Link two threats from different components to that risk.
3. Give Threat A a countermeasure with 100% effectiveness.
4. Leave Threat B with no countermeasures.
5. Recalculate the risk.

Example: Threat A is API Gateway input injection on an AWS WAF component, while Threat B is insufficient logging on an AWS Lambda component.

## Actual behavior

The calculation averages effectiveness across countermeasures found on the linked threats. The uncovered threat contributes no residual exposure, so the risk can receive an almost complete mitigation reduction even though one contributing threat has no control.

For an inherent score of 100, a fully effective control on only Threat A can produce a residual score of approximately 1 while Threat B remains exposed.

## Expected behavior

Controls should receive mitigation credit only for the threat exposure they actually cover. An uncovered contributing threat must continue to influence the aggregate residual risk. The calculation should operate at threat level before aggregating linked threats, according to the project's agreed scoring policy.

The fix does not need to prescribe one universal aggregation formula, but it must prevent a verified control on one component from erasing an unrelated exposed threat.

## Evidence

`compute_residual_score()` iterates over countermeasures globally across the risk's linked threats and averages their effectiveness:

https://github.com/precogly/precogly/blob/cb37379df2bfa9b43b02327e006b4cb6f92e035f/backend/apps/threats/services.py

https://github.com/user-attachments/assets/3dede572-8284-483d-a23e-177d2106122d

Contributor guide

Open the contributing guide

Research direction

Start in backend/apps/threats/services.py at compute_residual_score() and reproduce the linked-threat scenario described in the issue. Trace how countermeasure effectiveness is collected and aggregated across threats. Done means an uncovered linked threat still contributes residual exposure while controls receive credit only for the threat exposure they cover; the issue does not specify a single aggregation formula.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.