A vulnerability has a severity. An application has a risk.
One score per application, built from exposure, data sensitivity, exploitability and change velocity — with every factor visible and every weight yours to change.
The problem with sorting by severity
Severity is assigned by someone who has never seen your architecture. CVSS 9.8 means "this is bad in general". It says nothing about whether the vulnerable function is ever called, whether the service is reachable from the internet, or whether it touches a single piece of customer data.
So teams do the only thing a flat list allows: sort by severity and work top-down. That's how you end up patching a critical in an internal batch job while the payments API keeps a "medium" open for eight months.
Volume makes it worse. Once the list passes a few hundred items, severity sorting stops being triage and becomes a lottery.
How M.A.R.I.A. scores an application
M.A.R.I.A. scores the application, not the finding. The score combines:
- Exposure — internet-facing, internal, or isolated
- Data sensitivity — PII, payment data, credentials, or nothing that matters
- Exploitability — known exploited, public exploit available, exploitation probability
- Reachability — whether the vulnerable code path is actually used
- Change velocity — code that changes daily carries different risk from code frozen for two years
- Finding severity and density — the raw signal from your scanners, as one input among several rather than the whole answer
Every score opens up. You see the factors, their weights, and which findings drive the number. Nothing is a black box — a score nobody can explain gets ignored exactly like the alerts it replaced.
And the weights are yours. A fintech and an internal tools team don't have the same risk model, and M.A.R.I.A. doesn't pretend they do.
The honesty engine underneath the number
A risk score is only useful if it can go down. That sounds obvious, and it's where most tools quietly fail: they count every finding a repository has ever had, so fixing things never moves the number. M.A.R.I.A.'s score counts open risk — and the counting policy is pure, versioned and deliberately hard to game:
- Fixing reduces the score; accepting risk does not. Accepted risk keeps counting — because if silencing a finding improved your posture, the cheapest way to "get secure" would be to look away instead of fix.
- A critical is never silenced without accountability. High and critical findings stay visible regardless of gate, context or config; a scanner that declares a critical "suppressed" is refused — the claim becomes attributed evidence and the finding still surfaces.
- Unknown is never rendered as "no". Every tri-state signal keeps its middle value; missing data is stated, not assumed safe.
- The ruler is versioned. Changing the methodology never produces a fake "risk improved" — a score can only be compared against one built the same way.
Proven in production: a repository dropped from 92 to 84 the moment six criticals were marked fixed. Before this engine existed, that number couldn't move at all.
Why it matters
Because a number everyone trusts changes the conversation.
- A developer stops asking "which of these 212 findings do I do first?"
- A tech lead can justify spending a sprint on one service instead of spreading fixes thin across ten.
- A CTO gets a portfolio view that answers "where are we actually exposed?" instead of a bar chart of open findings that goes up every time you buy another scanner.
One honest number beats a thousand accurate alerts.
A practical example
Two applications in the same organization. One of them has fewer findings and far more risk.
payments-api RISK 84 (High) internal-reports RISK 22 (Low)
βββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββ
Findings 212 Findings 347
Critical 14 Critical 31
Internet-facing YES Internet-facing NO
Handles PII YES Handles PII NO
Deploys/week 4 Deploys/week 0.2
Top 3 drivers of payments-api risk:
1 CVE-2025-31324 Β· spring-core Β· reachable from /api/v1/checkout +23
2 Hardcoded AWS key Β· config/prod.yml Β· valid, unrotated 94 days +19
3 No auth on /internal/debug Β· exposed via ingress +12
3 findings drive 61% of the risk. Fix those and the score drops 84 β 41.
Illustrative example
internal-reports has more findings and more criticals — and a quarter of the risk. Severity sorting would have sent your team to the wrong repository. That's the whole argument, in one table.
See it scored on a real portfolio.
The demo organization has a dozen applications with real scanner output behind them.