Skip to content
English
  • There are no suggestions because the search field is empty.

06.02 The Risk Formula

Reference for SimpleRisk's six scoring methods — Classic, CVSS, DREAD, OWASP, Custom, and Contributing Risk. Includes each formula, the score normalization to 0–10, the score-to-level mapping, and the SLA thresholds. Use this article when you need exact behavior for a methodology.

Why this is a reference article

This article documents how SimpleRisk computes risk scores. For the operator workflow of picking a methodology, see Default Risk Scoring Method. For configuring a custom matrix, see Custom Risk Scoring. What follows is exact behavior (formulas, ranges, defaults, mapping rules) at the level a reviewer needs to verify a specific score or troubleshoot a per-risk display.

The six scoring methods

The system identifies methods by numeric ID (1–6); the IDs are stable across versions and appear in the risk_scoring.scoring_method column for each risk. The methods:

1: Classic

  • Per-risk score formula: (L × I) + (2 × I)
  • Maximum-score formula: (L_max × I_max) + (2 × I_max)

2: CVSS

  • Per-risk score formula: (L × I) + I
  • Maximum-score formula: (L_max × I_max) + I_max

3: DREAD

  • Per-risk score formula: L × I
  • Maximum-score formula: L_max × I_max

4: OWASP

  • Per-risk score formula: (L × I) + L
  • Maximum-score formula: (L_max × I_max) + L_max

5: Custom

  • Per-risk score formula: Lookup from custom matrix
  • Maximum-score formula: (Defined per matrix; default 10)

6: Contributing Risk

  • Per-risk score formula: (L × I) + (2 × L)
  • Maximum-score formula: (L_max × I_max) + (2 × L_max)

Where:

  • L = the per-risk likelihood value (an integer drawn from the configured likelihood scale).
  • I = the per-risk impact value (an integer drawn from the configured impact scale).
  • L_max = the maximum likelihood value (typically 5; configurable via count_of_likelihoods).
  • I_max = the maximum impact value (typically 5; configurable via count_of_impacts).

The formulas are intentionally simple — three are arithmetic operations on impact and likelihood, with different additive terms that produce different weightings. They aren't full implementations of the externally-named frameworks (CVSS isn't the actual CVSS metric vector calculation; DREAD doesn't take five separate inputs; OWASP isn't the OWASP Risk Rating Methodology). Treat the names as labels for the weighting characteristic, not as standards conformance.

Score normalization

Raw formula output ranges from 0 to the methodology's maximum. With the typical L_max = I_max = 5:

Classic

  • Raw min: 0
  • Raw max: 35

CVSS

  • Raw min: 0
  • Raw max: 30

DREAD

  • Raw min: 0
  • Raw max: 25

OWASP

  • Raw min: 0
  • Raw max: 30

Contributing Risk

  • Raw min: 0
  • Raw max: 35

Different methods produce different raw maxes, which makes cross-methodology score comparison meaningless without normalization.

The setting need_risk_score_normalization (boolean — default true) controls whether scores are normalized to 0–10 for display. When normalization is on:

displayed_score = (raw_score / max_raw_score_for_methodology) × 10

Every methodology produces 0–10 displayed scores, comparable across methodologies. When normalization is off, the raw score is shown — methodology-specific ranges as above. Most installs leave normalization on.

Score-to-level mapping

The numeric score maps to a qualitative level (Insignificant / Low / Medium / High / Very High) via the risk_levels table. The default thresholds (assuming normalized 0–10 scores):

Very High

  • Score range: > 7.5
  • Default color: Red

High

  • Score range: > 5 to ≤ 7.5
  • Default color: Orange

Medium

  • Score range: > 2.5 to ≤ 5
  • Default color: Yellow

Low

  • Score range: > 0 to ≤ 2.5
  • Default color: Green

Insignificant

  • Score range: ≤ 0
  • Default color: Light grey

The thresholds are configurable via the risk_levels table; the management surface is on the Configure → Settings → Risk Formula page (the "Risk Levels" section). Each row in risk_levels has:

  • id — internal level identifier (1–5 for the defaults).
  • name — internal name (e.g., "VeryHigh", "High").
  • display_name — the user-facing label (e.g., "Very High", "Critical" if your program renames it).
  • value — the score threshold (the upper bound of the level above this one).
  • color — the display hex color or named color.

To rename levels, update display_name. To shift thresholds, update value (which represents the lower bound of this level — anything ≥ value is in this level).

Functions that resolve a score to a level:

  • get_risk_level_name($score) — returns the level's display_name for a numeric score.
  • get_risk_color($score) — returns the level's color for a numeric score.

SLA thresholds

Each level has an associated review-cadence SLA — the number of days within which a risk at that level should be reviewed. The settings:

  • sla_threshold_very_high — default 30 days.
  • sla_threshold_high — default 60 days.
  • sla_threshold_medium — default 90 days.
  • sla_threshold_low — default 180 days.
  • sla_threshold_insignificant — default 180 days.

Range: 1–3650 days. The SLAs feed the next-review-date computation (see Risk Review Cadence).

Inputs to the per-risk score

Every risk record carries the inputs that drive its score. The risk_scoring table:

  • id — the risk ID (1:1 with the risk table).
  • scoring_method — the methodology ID (1–6).
  • Per-method input columns (the specific columns differ by methodology):
  • Classic / CVSS / DREAD / OWASP / Contributing Risk: CLASSIC_likelihood, CLASSIC_impact (or methodology-specific column names that follow the same pattern).
  • Custom (5): lookup against the custom matrix; per-risk impact and likelihood values still stored.
  • calculated_risk — the most recent computed score for the risk. Updated by calculate_risk() whenever the risk's inputs change.

When the score is computed

Recompute triggers:

  • At submissionsubmit_risk() calls calculate_risk() to populate the initial calculated_risk.
  • At edit — when impact or likelihood is changed via the UI or the API, update_risk() recomputes.
  • At residual-risk change — mitigation effectiveness can update the residual risk score (a separate value tracked alongside the inherent risk).
  • At methodology change for the specific risk — if a user edits a risk and changes its scoring_method, the new method's formula applies.
  • At bulk recalculationrecalculate_all_risk_scores() iterates every risk and recomputes against its current methodology and inputs. Triggered by the Recalculate Risk Scores admin action.

The score is not recomputed automatically when:

  • The system default risk_model setting changes — only new submissions pick it up; existing risks need a recalculate.
  • The risk_levels thresholds change — the score is unchanged; only its level mapping shifts.
  • The count_of_likelihoods or count_of_impacts changes — the maximum changes (which affects normalization), but no per-risk recomputation occurs until triggered.

Inherent vs residual risk

SimpleRisk tracks two scores per risk:

  • Inherent risk — the score computed from the (impact, likelihood) inputs as submitted, with no mitigation considered. This is the calculated_risk value.
  • Residual risk — the post-mitigation score, computed from the inherent risk reduced by the mitigation effectiveness. The residual_risk value.

Both are produced from the same methodology; the difference is that residual factors in the mitigation. Reports and dashboards typically display calculated_risk (inherent) by default; programs focused on post-mitigation posture may switch displays to residual_risk.

The next_review_date_uses setting (values: inherent or residual) controls which score drives the review-cadence calculation (see Risk Review Cadence).

Default fallback

For invalid inputs (a risk with scoring_method outside 1–6, or Custom method 5 with no matrix configured), the system returns default_risk_score (default 10). This is a safety net, not a correctness guarantee — risks scoring as the default value should be investigated.

Putting it together: an example

Take a risk with: - Likelihood = 3 (on a 1–5 scale; count_of_likelihoods = 5). - Impact = 4 (on a 1–5 scale; count_of_impacts = 5). - Methodology: Classic (ID 1).

Step 1 — Compute the raw score:

Raw = (L × I) + (2 × I)
    = (3 × 4) + (2 × 4)
    = 12 + 8
    = 20

Step 2 — Compute the methodology max:

Max_Classic = (L_max × I_max) + (2 × I_max)
            = (5 × 5) + (2 × 5)
            = 25 + 10
            = 35

Step 3 — Normalize (need_risk_score_normalization = true):

Displayed = (20 / 35) × 10
          = 5.71

Step 4 — Map to level (defaults: > 5 to ≤ 7.5 = High):

Level = High

The risk displays as 5.71 / High in the UI.

For comparison, the same (L=3, I=4) risk scored under DREAD (ID 3):

Raw = L × I = 3 × 4 = 12
Max_DREAD = 5 × 5 = 25
Displayed = (12 / 25) × 10 = 4.80
Level = Medium (> 2.5 to ≤ 5)

Same inputs, different methodology, different level. This is why methodology matters and why mixed-methodology registers are hard to interpret.

Reference

  • Implementing files: simplerisk/includes/functions.php (calculate_risk($impact, $likelihood) ~line 6045 — the dispatch and per-method computation; calculate_maximum_risk_score($scoring_method) ~line 6141 — the per-method maximum; get_scoring_method_name($method) ~line 17225 — method-ID to display-name; get_risk_color($score), get_risk_level_name($score) — score-to-level resolution; recalculate_all_risk_scores()); simplerisk/admin/configure_risk_formula.php (configuration UI).
  • Database tables: risk_scoring (per-risk inputs and calculated_risk); risk_levels (level thresholds and display); settings (the configuration values).
  • Key settings: risk_model (system default method 1–6); need_risk_score_normalization (boolean — default true); default_risk_score (fallback for invalid inputs, default 10); count_of_likelihoods (likelihood scale max, typically 5); count_of_impacts (impact scale max, typically 5); next_review_date_uses (inherent or residual — which score drives review cadence); sla_threshold_very_high, sla_threshold_high, sla_threshold_medium, sla_threshold_low, sla_threshold_insignificant (SLA days per level — defaults 30/60/90/180/180).
  • Built-in methods: 1 Classic, 2 CVSS, 3 DREAD, 4 OWASP, 5 Custom (Customization Extra), 6 Contributing Risk. Method 5 (Custom) uses a per-cell matrix lookup; the other five use the formulas in the table above.

Related