Risk Model V1
!!! warning "Status: Proposed / Design Review Required" Risk Model V1 is a design proposal. It is not implemented in hxEASM yet.
It is not implemented in vulnerability persistence, API responses, frontend views, filtering/sorting, reports, automatic recalculation, or Internet Exposure classification.
hxEASM already has a `risk_score` field today on the same `0-100` scale, but that existing field uses simpler non-contextual technical scoring behavior. Risk Model V1 must not be treated as the current `risk_score` behavior.
Purpose
Risk Model V1 is intended to separate technical vulnerability severity from contextual vulnerability prioritization.
CVSS / Severity = technical severity
risk_score = contextual vulnerability priority, 0-100
risk_level = Low / Medium / High / Critical
risk_confidence = confidence in the completeness/reliability of the risk inputs
Risk Model V1 does not replace CVSS or Severity. CVSS and Severity remain the original technical severity signals. The proposed risk_score ranks findings in the context of a customer's environment.
V1 Inputs
Risk Model V1 uses four proposed factors:
- Technical severity: CVSS preferred, Severity fallback.
- Asset Criticality: customer-defined business importance.
- HasExploit: whether hxEASM currently records known exploit availability.
- Internet Exposure: whether the affected asset is internal, external, or unknown.
These factors were selected because they represent technical danger, business importance, exploitability, and attack-surface exposure.
Excluded Factors
The following fields are not proposed as direct V1 score inputs:
| Factor | Reason |
|---|---|
| Vulnerability workflow status | closed/fixed, closed/fp, and closed/skipped are handling states, not intrinsic vulnerability danger. |
| Asset Approved | Approval is an inventory review state, not technical or business danger. |
| Asset Disabled | Disabled is an operational execution state. Disabled assets remain stored and may still have vulnerabilities. |
| Asset Stale | Stale is a data freshness signal and is better represented through confidence or future freshness logic. |
| Vulnerability age | Age is useful for SLA and escalation, but not part of V1 intrinsic risk. |
| Repeated observations | Reobservation may improve confidence, but should not directly change V1 score. |
| Source plugin reliability | Useful later, but requires a source-quality taxonomy. |
| Port/service weighting | Potentially valuable, but requires careful service classification to avoid hidden heuristics. |
Some excluded factors may be reconsidered in later model versions.
Technical Normalization
If CVSS exists:
technical = clamp(CVSS / 10, 0, 1)
If CVSS is unavailable, use Severity fallback:
info = 0.10
low = 0.25
medium = 0.50
high = 0.75
critical = 1.00
CVSS and Severity must not be counted simultaneously. CVSS is preferred; Severity is fallback.
Asset Criticality Normalization
unknown = 0.00
low = 0.20
medium = 0.45
high = 0.75
critical = 1.00
unknown contributes zero risk points rather than pretending to be Medium or Critical. Incomplete data is represented separately through risk_confidence.
HasExploit Normalization
has_exploit = false -> 0.00
has_exploit = true -> 1.00
HasExploit=false means "No known exploit is currently recorded in hxEASM." It is not proof that no exploit exists.
Automatic exploit enrichment is a separate capability and may improve this signal later.
Internet Exposure Normalization
Proposed states:
internal = 0.00
unknown = 0.00
external = 1.00
hxEASM does not currently have a canonical, reliable Internet Exposure field sufficient to fully implement this factor.
Domains, URLs, and subdomains must not automatically be treated as Internet-facing. Exposure classification should be performed by a separate component:
ExposureClassifier
|
v
internet_exposure
exposure_confidence
exposure_source/evidence
|
v
RiskCalculator
The RiskCalculator should consume internet_exposure = internal | external | unknown. It should not contain complex graph traversal, IP classification, or plugin provenance logic.
Proposed Formula
raw_score =
70 * technical
+ 12 * asset_criticality
+ 10 * internet_exposure
+ 8 * has_exploit
Weights:
| Factor | Weight |
|---|---|
| Technical severity | 70% |
| Asset Criticality | 12% |
| Internet Exposure | 10% |
| HasExploit | 8% |
Technical severity remains dominant while contextual factors can materially reprioritize vulnerabilities.
Technical Caps
technical < 0.25 -> maximum risk_score = 39
technical < 0.50 -> maximum risk_score = 59
technical < 0.70 -> maximum risk_score = 79
technical >= 0.70 -> maximum risk_score = 100
Intent: a low technical severity vulnerability must not become Critical purely because it exists on an important Internet-facing asset.
Technical Floors
technical >= 0.90 -> minimum risk_score = 60
technical >= 0.70 -> minimum risk_score = 30
otherwise -> minimum risk_score = 0
Design note: with the current V1 weights, these floors are mathematically redundant in normal calculations because technical >= 0.90 already contributes at least 63 points and technical >= 0.70 already contributes at least 49 points. They are retained as explicit semantic guardrails so future weight changes cannot accidentally allow extreme technical severity to fall below intended minimum levels.
Final Calculation
risk_score = clamp(raw_score, technical_floor, technical_cap)
Final score bounds:
0 <= risk_score <= 100
Risk Levels
0.00 <= score < 30.00 Low
30.00 <= score < 60.00 Medium
60.00 <= score < 80.00 High
80.00 <= score <= 100.00 Critical
There are no gaps or overlaps.
Risk Confidence
risk_score answers:
How highly should this vulnerability currently be prioritized?
risk_confidence answers:
How complete/reliable are the inputs used to calculate that priority?
Proposed confidence calculation:
confidence =
0.45 * technical_confidence
+ 0.20 * asset_criticality_confidence
+ 0.25 * exposure_confidence
+ 0.10 * exploit_confidence
Technical:
CVSS present = 1.00
Severity fallback = 0.75
Asset Criticality:
known = 1.00
unknown = 0.40
Exposure:
internal/external classified = 1.00
unknown = 0.30
Exploit:
HasExploit=true = 0.90
HasExploit=false + known source = 0.75
HasExploit=false + unknown source = 0.60
Confidence levels:
>= 0.80 -> High
>= 0.55 -> Medium
< 0.55 -> Low
Risk Score and Risk Confidence are separate concepts and must not be mixed.
Missing Data Behavior
Missing context must not block risk calculation. Missing context must also not silently add risk points.
| Missing data | Proposed behavior |
|---|---|
| CVSS missing | Fall back to Severity. |
| Asset Criticality unknown | Risk contribution is 0; confidence is reduced. |
| Internet Exposure unknown | Risk contribution is 0; confidence is reduced. |
| HasExploit false with unknown source | Exploit contribution is 0; confidence is reduced. |
Worked Examples
| Scenario | Calculation | Result | Demonstrates |
|---|---|---|---|
| CVSS 10, Low Asset, Internal, No known exploit | 70*1.00 + 12*0.20 = 72.4 |
72.4 - High |
Extreme technical severity cannot be suppressed below High by weak context. |
| CVSS 10, Critical Asset, External, HasExploit | 70*1 + 12*1 + 10*1 + 8*1 = 100 |
100 - Critical |
Maximum technical and contextual risk reaches Critical. |
| CVSS 8.8, Low Asset, Internal, No exploit | 70*0.88 + 12*0.20 = 64.0 |
64.0 - High |
High technical severity remains important even with weak context. |
| CVSS 8.8, Critical Asset, External, HasExploit | 70*0.88 + 12 + 10 + 8 = 91.6 |
91.6 - Critical |
Strong context promotes an already serious issue. |
| CVSS 3.0, Critical Asset, External, HasExploit | 70*0.30 + 12 + 10 + 8 = 51 |
51 - Medium |
Low technical severity cannot become Critical purely from context. |
| CVSS 5.0, Critical Asset, External, HasExploit | 70*0.50 + 12 + 10 + 8 = 65 |
65 - High |
Medium technical severity can be promoted by strong context. |
| Severity High, Unknown Asset Criticality, Unknown Exposure, No exploit | 70*0.75 = 52.5 |
52.5 - Medium |
Unknown context does not add hidden risk points; confidence is reduced. |
| Severity High, Critical Asset, External, No exploit | 70*0.75 + 12 + 10 = 74.5 |
74.5 - High |
Business and exposure context can reprioritize without exploit availability. |
Proposed Recalculation Triggers - Not Implemented
A future implementation should recalculate Risk Model V1 when these inputs change.
Vulnerability inputs:
cvss_scoreseverityhas_exploit- affected asset association
Asset inputs:
criticality- future Internet Exposure classification
Future enrichment:
- CVSS enrichment
- exploit enrichment
- exposure enrichment
Workflow status changes should not recalculate intrinsic risk merely because status changed.
Proposed Future API - Not Implemented
Suggested future response shape:
{
"risk_score": 87.4,
"risk_level": "critical",
"risk_confidence": "high",
"risk_version": "v1",
"risk_calculated_at": "2026-08-23T12:00:00Z",
"risk_factors": {
"technical": 0.88,
"technical_source": "cvss",
"asset_criticality": 1.0,
"has_exploit": true,
"internet_exposure": "external"
}
}
Possible future filtering/sorting:
sort=risk_score_desc
risk_level=critical
min_risk_score=70
max_risk_score=90
These API fields and filters are proposals and do not currently exist unless verified independently in a future implementation.
Proposed Future Persistence - Not Implemented
The current Threat table already has risk_score NUMERIC(5,2) on a 0-100 scale. Proposed future persistence for the full contextual Risk Model V1 adds explicit model metadata around that field:
risk_score NUMERIC(5,2)
risk_level TEXT
risk_confidence TEXT
risk_version TEXT
risk_calculated_at TIMESTAMP
risk_factors JSONB
Important existing constraint: the current risk_score field already uses NUMERIC(5,2) and a 0-100 scale, but it still represents existing non-contextual/technical scoring behavior. A future Risk Model V1 implementation must add the contextual model fields and recalculation behavior explicitly rather than treating the current score as the full V1 model.
No database change is part of this proposal document.
Versioning
risk_version = "v1"
Formula versioning is necessary because weights and factors may evolve, old reports need interpretation, existing vulnerabilities may need recalculation, and analysts need reproducibility.
No policy engine is proposed for V1.
Review Required Before Implementation
Implementation must not begin until the model is reviewed.
Recommended review stakeholders:
- Security Research / Vulnerability Management
- Product / hxEASM architecture
- penetration testing / offensive security specialists
- customer-facing security analysts if applicable
Questions requiring review:
- Are the factor weights appropriate?
- Are technical caps appropriate?
- Are Low/Medium/High/Critical boundaries appropriate?
- Is CVSS 3.0 + critical/external/exploit = Medium acceptable?
- Is CVSS 5.0 + critical/external/exploit = High acceptable?
- Should
HasExploit=falsebe treated differently once automatic enrichment exists? - What evidence is sufficient to classify Internet Exposure?
- Should risk confidence be visible to customers?
- Should Risk Score influence SLA in a later phase?
- Are the explicit technical guardrails worth retaining despite currently being mathematically redundant?
Known Gaps
- Canonical Internet Exposure classification does not exist yet.
- Plugin-generated vulnerabilities often have Severity but not numeric CVSS.
- Existing
risk_scorecalculation semantics differ from proposed Risk Model V1 even though the scale is already0-100. HasExploit=falsedoes not prove no public exploit exists.- Risk Confidence does not currently exist.
- A recalculation engine does not currently exist.