Vulnerability

security

Vulnerability

Definition

A vulnerability is a weakness, flaw, or deficiency in a system, application, process, or configuration that can be exploited by a threat actor to gain unauthorized access, escalate privileges, exfiltrate data, disrupt services, or otherwise cause harm. Vulnerabilities exist at every layer of the technology stack -- from hardware and firmware through operating systems, network protocols, application code, and business logic to human processes and organizational procedures. They represent the intersection of a system's attack surface with the capabilities of potential adversaries.

Overview

Vulnerabilities are the foundational unit of security risk assessment. Without vulnerabilities, threats cannot materialize into incidents. The relationship between threats, vulnerabilities, and risk is expressed as: Risk = Threat x Vulnerability x Impact. An adversary (threat) exploits a weakness (vulnerability) to cause damage (impact). Reducing vulnerabilities directly reduces risk, making vulnerability management one of the most impactful security activities an organization can undertake.

The formal tracking of vulnerabilities began with the Common Vulnerabilities and Exposures (CVE) system, established by MITRE in 1999. Each CVE entry receives a unique identifier (e.g., CVE-2024-12345) and a severity score calculated using the Common Vulnerability Scoring System (CVSS). As of 2026, the CVE database contains over 250,000 entries, with approximately 25,000-30,000 new vulnerabilities disclosed annually -- a number that continues to grow as software complexity increases.

Vulnerability Lifecycle

PhaseDescriptionKey Activities
IntroductionVulnerability is created (coding error, misconfiguration, design flaw)Code review, secure development
DiscoveryVulnerability is found by researcher, automated tool, or attackerScanning, penetration testing, bug bounty
DisclosureVulnerability is reported to vendor/publicResponsible disclosure, CVE assignment
AnalysisSeverity assessed, impact evaluatedCVSS scoring, exploitability analysis
RemediationPatch developed and deployed, or mitigation appliedPatch management, configuration hardening
VerificationFix confirmed, vulnerability closedRe-scanning, regression testing

Vulnerability Classification

Vulnerabilities are classified by several taxonomies:

By Origin:

  • Software bugs: Buffer overflows, injection flaws, race conditions, logic errors
  • Configuration errors: Default credentials, open ports, permissive permissions, missing encryption
  • Design flaws: Weak authentication schemes, insecure protocols, missing access controls
  • Process failures: Inadequate change management, missing monitoring, human error

By Severity (CVSS v3.1):

RatingScoreDescription
Critical9.0-10.0Remote code execution, complete system compromise
High7.0-8.9Significant data exposure, privilege escalation
Medium4.0-6.9Limited impact, requires preconditions
Low0.1-3.9Minimal impact, difficult to exploit
None0.0Informational finding

Technical Details

CVSS Scoring Components

The Common Vulnerability Scoring System (CVSS) evaluates vulnerabilities across three metric groups:

Base Metrics (intrinsic properties):

  • Attack Vector (Network, Adjacent, Local, Physical)
  • Attack Complexity (Low, High)
  • Privileges Required (None, Low, High)
  • User Interaction (None, Required)
  • Scope (Unchanged, Changed)
  • Confidentiality Impact (None, Low, High)
  • Integrity Impact (None, Low, High)
  • Availability Impact (None, Low, High)

Temporal Metrics (change over time):

  • Exploit Code Maturity (Unproven, Proof-of-Concept, Functional, High)
  • Remediation Level (Official Fix, Temporary Fix, Workaround, Unavailable)
  • Report Confidence (Unknown, Reasonable, Confirmed)

Environmental Metrics (organization-specific):

  • Modified base metrics reflecting the target environment
  • Confidentiality/Integrity/Availability requirements

Vulnerability Categories (OWASP Top 10 2021)

RankCategoryDescriptionExample
A01Broken Access ControlMissing authorization checksIDOR, privilege escalation
A02Cryptographic FailuresWeak or missing encryptionPlaintext passwords, weak TLS
A03InjectionUntrusted data in commandsSQL injection, XSS, command injection
A04Insecure DesignMissing security controls by designNo rate limiting, no fraud detection
A05Security MisconfigurationDefault/incomplete configurationOpen cloud storage, verbose errors
A06Vulnerable ComponentsOutdated libraries/frameworksKnown CVEs in dependencies
A07Authentication FailuresBroken identity verificationCredential stuffing, weak passwords
A08Data Integrity FailuresUntrusted deserialization, CI/CDSupply chain compromise
A09Logging FailuresInsufficient monitoringMissing audit trail, no alerting
A10SSRFServer-side request forgeryInternal network scanning via app

Zero-Day Vulnerabilities

A zero-day vulnerability is one that is unknown to the vendor and has no available patch. Zero-days are the most dangerous class of vulnerabilities because:

  • No patch exists to remediate them
  • Traditional signature-based detection cannot identify exploits
  • They may have been exploited in the wild before discovery
  • They command premium prices on vulnerability markets (both legitimate and criminal)

Defense against zero-days requires defense-in-depth strategies: zero trust architecture, behavioral detection, micro-segmentation, and rapid incident response capabilities.

Implementation in Prismatic Platform

Vulnerability Scanner

The Prismatic Platform implements vulnerability scanning as part of the EASM capabilities in Prismatic Perimeter:

defmodule PrismaticPerimeter.Vulnerability.Scanner do
  @moduledoc """
  Vulnerability scanning engine for external attack surface assessment.
  Identifies known vulnerabilities in discovered assets and services.
  """

  @type scan_target :: %{
    host: String.t(),
    port: non_neg_integer(),
    service: String.t(),
    version: String.t() | nil
  }

  @type scan_result :: %{
    target: scan_target(),
    vulnerabilities: [vulnerability_finding()],
    scan_duration_ms: non_neg_integer(),
    timestamp: DateTime.t()
  }

  @type vulnerability_finding :: %{
    cve_id: String.t() | nil,
    title: String.t(),
    severity: :critical | :high | :medium | :low | :info,
    cvss_score: float(),
    description: String.t(),
    affected_component: String.t(),
    remediation: String.t(),
    references: [String.t()]
  }

  @spec scan(String.t(), keyword()) :: {:ok, [scan_result()]} | {:error, term()}
  def scan(domain, opts \\ []) do
    with {:ok, assets} <- PrismaticPerimeter.AssetDiscovery.discover(domain),
         targets <- build_scan_targets(assets),
         {:ok, results} <- execute_parallel_scan(targets, opts) do
      enriched = Enum.map(results, &enrich_with_cve_data/1)

      :telemetry.execute(
        [:prismatic, :vulnerability, :scan_complete],
        %{
          targets_scanned: length(targets),
          vulnerabilities_found: count_total_vulns(enriched),
          critical_count: count_by_severity(enriched, :critical)
        },
        %{domain: domain}
      )

      {:ok, enriched}
    end
  end

  @spec execute_parallel_scan([scan_target()], keyword()) :: {:ok, [scan_result()]} | {:error, term()}
  defp execute_parallel_scan(targets, opts) do
    max_concurrency = Keyword.get(opts, :max_concurrency, 10)
    timeout = Keyword.get(opts, :timeout, 30_000)

    results =
      targets
      |> Task.async_stream(
        fn target -> scan_target(target, opts) end,
        max_concurrency: max_concurrency,
        timeout: timeout,
        on_timeout: :kill_task
      )
      |> Enum.reduce([], fn
        {:ok, {:ok, result}}, acc -> [result | acc]
        {:ok, {:error, _reason}}, acc -> acc
        {:exit, _reason}, acc -> acc
      end)

    {:ok, Enum.reverse(results)}
  end

  @spec scan_target(scan_target(), keyword()) :: {:ok, scan_result()} | {:error, term()}
  defp scan_target(target, _opts) do
    start_time = System.monotonic_time(:millisecond)

    findings =
      []
      |> check_version_vulnerabilities(target)
      |> check_configuration_vulnerabilities(target)
      |> check_protocol_vulnerabilities(target)
      |> check_certificate_vulnerabilities(target)

    duration = System.monotonic_time(:millisecond) - start_time

    {:ok, %{
      target: target,
      vulnerabilities: findings,
      scan_duration_ms: duration,
      timestamp: DateTime.utc_now()
    }}
  end
end

CVE Tracking and Enrichment

defmodule PrismaticPerimeter.Vulnerability.CVETracker do
  @moduledoc """
  CVE tracking and enrichment service. Maintains a local cache
  of CVE data and provides lookup and correlation capabilities.
  """

  @type cve_entry :: %{
    cve_id: String.t(),
    description: String.t(),
    cvss_v3: float() | nil,
    cvss_v2: float() | nil,
    severity: :critical | :high | :medium | :low,
    published_date: DateTime.t(),
    modified_date: DateTime.t(),
    affected_products: [String.t()],
    references: [String.t()],
    exploit_available: boolean(),
    patch_available: boolean()
  }

  @spec lookup(String.t()) :: {:ok, cve_entry()} | {:error, :not_found}
  def lookup(cve_id) do
    case :ets.lookup(:cve_cache, cve_id) do
      [{^cve_id, entry}] -> {:ok, entry}
      [] -> fetch_and_cache(cve_id)
    end
  end

  @spec find_by_product(String.t(), String.t()) :: {:ok, [cve_entry()]} | {:error, term()}
  def find_by_product(product, version) do
    cpe = build_cpe_string(product, version)

    entries =
      :ets.foldl(
        fn {_id, entry}, acc ->
          if cpe_matches?(entry.affected_products, cpe) do
            [entry | acc]
          else
            acc
          end
        end,
        [],
        :cve_cache
      )

    {:ok, Enum.sort_by(entries, & &1.cvss_v3, :desc)}
  end

  @spec severity_from_cvss(float()) :: :critical | :high | :medium | :low
  def severity_from_cvss(score) when score >= 9.0, do: :critical
  def severity_from_cvss(score) when score >= 7.0, do: :high
  def severity_from_cvss(score) when score >= 4.0, do: :medium
  def severity_from_cvss(_score), do: :low
end

Security Rating Impact Calculation

defmodule PrismaticPerimeter.Vulnerability.RatingImpact do
  @moduledoc """
  Calculates the impact of discovered vulnerabilities on
  an organization's security rating score.
  """

  @type rating_impact :: %{
    total_deduction: float(),
    vulnerability_breakdown: [deduction_detail()],
    rating_before: float(),
    rating_after: float(),
    grade_impact: :unchanged | :downgraded
  }

  @type deduction_detail :: %{
    cve_id: String.t() | nil,
    severity: atom(),
    deduction_points: float(),
    rationale: String.t()
  }

  @severity_weights %{
    critical: 50.0,
    high: 25.0,
    medium: 10.0,
    low: 2.0,
    info: 0.0
  }

  @spec calculate_impact([map()], float()) :: {:ok, rating_impact()} | {:error, term()}
  def calculate_impact(vulnerabilities, current_rating) do
    deductions =
      vulnerabilities
      |> Enum.map(fn vuln ->
        base_weight = Map.get(@severity_weights, vuln.severity, 0.0)
        age_factor = calculate_age_factor(vuln)
        exploit_factor = if vuln[:exploit_available], do: 1.5, else: 1.0
        patch_factor = if vuln[:patch_available], do: 0.7, else: 1.0

        deduction = base_weight * age_factor * exploit_factor * patch_factor

        %{
          cve_id: vuln[:cve_id],
          severity: vuln.severity,
          deduction_points: deduction,
          rationale: build_rationale(vuln, deduction)
        }
      end)

    total_deduction = deductions |> Enum.map(& &1.deduction_points) |> Enum.sum()
    rating_after = max(300.0, current_rating - total_deduction)

    {:ok, %{
      total_deduction: total_deduction,
      vulnerability_breakdown: deductions,
      rating_before: current_rating,
      rating_after: rating_after,
      grade_impact: grade_change(current_rating, rating_after)
    }}
  end

  @spec calculate_age_factor(map()) :: float()
  defp calculate_age_factor(%{published_date: published}) do
    days_old = DateTime.diff(DateTime.utc_now(), published, :day)

    cond do
      days_old > 365 -> 2.0
      days_old > 180 -> 1.5
      days_old > 90 -> 1.2
      days_old > 30 -> 1.0
      true -> 0.8
    end
  end

  defp calculate_age_factor(_), do: 1.0

  @spec grade_change(float(), float()) :: :unchanged | :downgraded
  defp grade_change(before, after_score) do
    if score_to_grade(before) == score_to_grade(after_score),
      do: :unchanged,
      else: :downgraded
  end

  @spec score_to_grade(float()) :: String.t()
  defp score_to_grade(score) when score >= 800, do: "A"
  defp score_to_grade(score) when score >= 700, do: "B"
  defp score_to_grade(score) when score >= 600, do: "C"
  defp score_to_grade(score) when score >= 500, do: "D"
  defp score_to_grade(_score), do: "F"
end

Comparison with Alternatives

ConceptScopeRelationship to Vulnerability
VulnerabilitySpecific weakness in systemThe weakness itself
ThreatPotential danger to systemThe actor/event that exploits a vulnerability
RiskProbability x ImpactThreat exploiting vulnerability causing damage
ExploitCode/technique to abuse weaknessThe method of leveraging a vulnerability
CVEStandard identifierCataloging system for known vulnerabilities
Weakness (CWE)General category of flawAbstract pattern that manifests as vulnerability
ExposureReachable from outsideVulnerability accessible via attack surface

Vulnerability Management Tools Comparison

Tool CategoryExamplesApproachPrismatic Equivalent
Network ScannersNessus, QualysAgent/agentless scanningEASM vulnerability scanner
DASTOWASP ZAP, Burp SuiteDynamic application testingPerimeter application scanning
SASTSonarQube, SemgrepSource code analysisCredo + custom checks
SCASnyk, DependabotDependency vulnerabilityMix audit integration
EASMBitSight, SecurityScorecardExternal surface monitoringPrismatic Perimeter

Best Practices

  1. Automate vulnerability scanning: Manual vulnerability assessment does not scale. Implement continuous automated scanning integrated into CI/CD pipelines and production monitoring to detect new vulnerabilities as they appear.

  2. Prioritize by context, not just CVSS: A critical CVSS score on an internal development server is less urgent than a high CVSS score on a public-facing production API. Use environmental context -- asset value, exposure, exploitability, and business impact -- to prioritize remediation.

  3. Track mean time to remediate (MTTR): Measure how long vulnerabilities remain unpatched after discovery. Set SLAs by severity: critical (24 hours), high (7 days), medium (30 days), low (90 days). Track and report on SLA compliance.

  4. Maintain a vulnerability inventory: Keep a comprehensive record of all discovered vulnerabilities, their status (open, in progress, resolved, accepted risk), and remediation history. This inventory supports compliance reporting for ZKB and NIS2.

  5. Implement defense in depth: No vulnerability management program catches everything. Layer security controls (zero trust, micro-segmentation, WAF, IDS/IPS) to reduce the impact of vulnerabilities that escape detection or remediation.

  6. Include dependency vulnerabilities: Track vulnerabilities in third-party libraries and frameworks, not just custom code. Use mix audit for Elixir dependencies and integrate SCA tools into the build pipeline.

  7. Correlate with threat intelligence: Not all vulnerabilities are equally likely to be exploited. Cross-reference discovered vulnerabilities with threat intelligence feeds to identify vulnerabilities being actively exploited in the wild.

Common Pitfalls

  • Scan and forget: Running vulnerability scans without acting on results creates a false sense of security. Every scan must trigger a prioritized remediation workflow with accountability and deadlines.

  • Patching without testing: Applying patches to production without testing can cause outages worse than the vulnerability. Maintain a testing pipeline where patches are validated before production deployment.

  • Ignoring low-severity findings: Low-severity vulnerabilities can be chained together to achieve high-severity outcomes. Attackers routinely combine multiple low/medium findings to achieve critical impact.

  • Over-reliance on CVSS scores: CVSS measures intrinsic severity but not organizational context. A vulnerability in a sandboxed test environment has different urgency than the same vulnerability in a payment processing system.

  • Missing configuration vulnerabilities: Automated scanners focus on known CVEs but may miss configuration errors, default credentials, excessive permissions, and logic flaws. Supplement automated scanning with manual review and penetration testing.

  • Not tracking accepted risks: When a vulnerability cannot be immediately remediated, document the risk acceptance decision with justification, compensating controls, and review date. Untracked accepted risks become unmanaged risks.

Use Cases

External Attack Surface Management: Prismatic Perimeter discovers and scans external-facing assets to identify vulnerabilities visible to attackers. Results feed into security rating calculations that produce A-F grades for organizations.

Compliance Vulnerability Management: ZKB Section 23 and NIS2 Article 21(2)(e) mandate vulnerability management programs. The Prismatic vulnerability scanner provides the technical foundation for compliance with these regulatory requirements.

Supply Chain Risk Assessment: Evaluating supplier security posture includes assessing their external vulnerability exposure. Critical suppliers with unpatched critical vulnerabilities represent supply chain risk that must be addressed under ZKB Sec. 15.

Incident Investigation: When investigating security incidents, vulnerability data provides crucial context. Understanding which vulnerabilities existed on compromised systems helps determine the attack vector and scope of compromise.

Continuous Security Monitoring: Integrating vulnerability scanning into operational monitoring detects newly introduced vulnerabilities from software updates, configuration changes, or new CVE disclosures affecting existing software versions.

  • CVE -- Standard identification system for known vulnerabilities
  • Vulnerability Assessment -- Systematic process of identifying vulnerabilities
  • Attack Surface -- Total exposure area where vulnerabilities may exist
  • Penetration Testing -- Manual exploitation of vulnerabilities for validation
  • Security Rating -- Quantified security score impacted by vulnerabilities
  • OWASP -- Top 10 vulnerability categories for web applications
  • EASM -- External scanning that discovers vulnerabilities
  • Security Assessment -- Broader evaluation including vulnerability analysis
  • Zero Trust -- Architecture reducing vulnerability exploitation impact
  • Encryption -- Control mitigating data exposure from vulnerabilities
  • Security Operations -- Operational response to vulnerability findings
  • NIS2 -- EU directive mandating vulnerability management

See Also

  • Architecture -- Platform architecture overview
  • Technologies -- Technology stack details
  • Apps -- Application ecosystem including Prismatic Perimeter
  • ZKB -- Czech cybersecurity regulation requiring vulnerability management
  • Audit Logging -- Evidence trail for vulnerability remediation

Connect & Contribute

Created by Tomas Korcak (korczis) | Open Source under GHL