Skip to content

Scoring Methodology

This page describes how NetVuln Tool classifies finding severity, computes the Bullium Risk Score, applies the dual (actual vs operational) scoring model, and determines risk trends.

The relevant scripts are scripts/classify_severity.sh (severity rules), scripts/cve_lookup.sh (CVSS lookup), and scripts/risk_score.sh (scoring, grading, operational model, and trend).

Severity Classification

Each finding is assigned a severity level using a three-tier approach, applied in order of priority.

1. CVE/CVSS Lookup (Primary)

When a CVE identifier is detected in scan output, NetVuln Tool queries external sources for the CVSS base score:

  • Primary source: cvedetails.com (HTML scraping)
  • Fallback source: NVD API v2 (services.nvd.nist.gov)
  • CVSS versions: v3.1 preferred, then v3.0, then v2
CVSS ScoreSeverity
9.0 - 10.0Critical
7.0 - 8.9High
4.0 - 6.9Medium
0.1 - 3.9Low
0.0 / N/AInfo

Results are cached per-session to avoid redundant lookups. Rate limiting (a 2-second minimum between requests) is applied to respect API limits.

2. Pattern-Based Classification (Fallback)

Findings without CVE identifiers are classified by matching title and description text against known vulnerability patterns.

Critical patterns: Remote Code Execution (RCE), command/shell injection, default or blank credentials, unrestricted admin interfaces, SQL injection, and known critical CVEs (MS17-010, EternalBlue, Heartbleed, ShellShock, Log4Shell, ProxyLogon).

High patterns: Weak SSL/TLS (SSLv2, SSLv3, RC4, POODLE, BEAST, DROWN), SMB null sessions, anonymous access, cleartext protocols on sensitive services (Telnet, FTP), exposed databases without authentication, privilege escalation, path traversal.

Medium patterns: Missing security headers (HSTS, CSP, X-Frame-Options), outdated or end-of-life software, weak SSH configuration, self-signed or expired certificates, SNMP default community strings, DNS zone transfers allowed.

Low patterns: Information disclosure (server version banners), minor configuration issues (cookie flags, directory listing, X-Powered-By header), ICMP responses and timestamps.

Info: Unmatched findings default to informational.

3. Port-Based Classification (Default)

For findings that do not match any pattern, severity is assigned based on the exposed service type:

ServicePortsDefault Severity
Telnet, RSH, Rlogin, Rexec23, 514, 513, 512High
FTP, SNMP21, 161Medium
Database servicesMySQL (3306), PostgreSQL (5432), MongoDB (27017), SQL Server (1433), Oracle (1521)Medium
Remote Desktop, VNC3389, 5900Medium
Other servicesany other portInfo

Bullium Risk Score (0-100)

The risk score provides a single numeric indicator of overall exposure, computed from weighted finding counts plus bonuses for high-risk exposed services.

Formula

Score = (Critical × 25) + (High × 15) + (Medium × 5) + (Low × 1) + Port Bonuses

The score is capped at 100 (minimum 0).

Severity Weights

SeverityPoints per Finding
Critical25
High15
Medium5
Low1
Info0

Port Bonuses

Additional points are added for open high-risk services detected on any host:

CategoryPointsPorts
Cleartext services+10 eachTelnet (23), FTP (21)
Management ports+8 eachRDP (3389), VNC (5900, 5901), MySQL (3306), PostgreSQL (5432), SQL Server (1433), MongoDB (27017), Redis (6379)

Example Calculation

A scan with 1 critical, 2 high, and 3 medium findings, plus open Telnet and RDP:

Severity:  (1 × 25) + (2 × 15) + (3 × 5) = 25 + 30 + 15 = 70
Bonuses:   Telnet (+10) + RDP (+8) = 18
Total:     70 + 18 = 88

Grade Scale

The risk score maps to a letter grade:

GradeScore RangeRating
A0 - 20Excellent, minimal risk exposure
B21 - 40Good, low risk with minor issues
C41 - 60Fair, moderate risk, action recommended
D61 - 80Poor, significant risk, remediation needed
F81 - 100Critical, severe exposure, immediate action required

Dual Scoring Model (Actual vs Operational)

Added in v3.1.0, the dual scoring model reports two scores side by side so that risk that has been formally accepted does not hide from the raw number.

  • Actual score (risk_score / risk_grade): the raw exposure computed above, counting every finding.
  • Operational score (risk_score_operational / risk_grade_operational): the same calculation with the severity weight of accepted, non-expired exceptions subtracted. It answers "what is the residual risk after leadership has signed off on known items?"

calculate_operational_score() in risk_score.sh collects the finding_ids from every .remediation[] entry whose exception_status is accepted and whose exception_expired is false, sums the severity weights of those findings, subtracts that total from the actual score (floored at 0), and re-grades the result. Port bonuses are deliberately not discounted: an exposed management port exists regardless of any paperwork.

When a session has no active exceptions, the operational score equals the actual score and the exception impact is zero.

Exception Impact Fields

Written to .summary alongside the two scores:

FieldTypeDescription
risk_score_operationalnumberPost-exception score (0-100)
risk_grade_operationalstringPost-exception grade (A-F)
exception_impact.excepted_countnumberCount of active (accepted, non-expired) exceptions
exception_impact.score_deltanumberActual score minus operational score
exception_impact.excepted_findingsobjectBy-severity breakdown of excepted findings

Exceptions are created and managed with remediation_update.sh --accept / --revoke. See Session Data for the full remediation and exception field schema, and the API Contract for how the portal extracts the exception summary at upload time.

Risk Trend

When multiple scans of the same target scope exist in the session directory, the current score is compared to the most recent prior scan:

  • Improving: the current score is lower than the previous score (risk decreased)
  • Worsening: the current score is higher than the previous score (risk increased)
  • Stable: no change since the last scan

Trend comparison uses target-scope matching so that only scans of the same IP range or domain are compared. Historical scores are stored chronologically for long-term tracking. When operational scores are present, a parallel operational trend (risk_trend.operational_scores, operational_direction, operational_change) is tracked as well.

Source Files

FilePurpose
scripts/risk_score.shRisk score calculation, grading, operational (dual) model, trend analysis
scripts/classify_severity.shPattern-based severity classification rules
scripts/cve_lookup.shCVE/CVSS lookup from cvedetails.com and the NVD API
scripts/remediation_update.shManual remediation status and exception (accept/revoke) management
scripts/report_template.shReport HTML, including the scoring reference section

Apache-2.0 licensed (appliance subtree proprietary)