Skip to content

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:

  1. Technical severity: CVSS preferred, Severity fallback.
  2. Asset Criticality: customer-defined business importance.
  3. HasExploit: whether hxEASM currently records known exploit availability.
  4. 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_score
  • severity
  • has_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:

  1. Are the factor weights appropriate?
  2. Are technical caps appropriate?
  3. Are Low/Medium/High/Critical boundaries appropriate?
  4. Is CVSS 3.0 + critical/external/exploit = Medium acceptable?
  5. Is CVSS 5.0 + critical/external/exploit = High acceptable?
  6. Should HasExploit=false be treated differently once automatic enrichment exists?
  7. What evidence is sufficient to classify Internet Exposure?
  8. Should risk confidence be visible to customers?
  9. Should Risk Score influence SLA in a later phase?
  10. 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_score calculation semantics differ from proposed Risk Model V1 even though the scale is already 0-100.
  • HasExploit=false does not prove no public exploit exists.
  • Risk Confidence does not currently exist.
  • A recalculation engine does not currently exist.