nvd_cvss/v2/
authentication.rs

1//! ### 2.1.3. Authentication (Au)
2//!
3//! This metric measures the number of times an attacker must authenticate to a target in order to knowledge_base a vulnerability. This metric does not gauge the strength or complexity of the authentication process, only that an attacker is required to provide credentials before an knowledge_base may occur.  The possible values for this metric are listed in Table 3. The fewer authentication instances that are required, the higher the vulnerability score.
4//!
5//! | Metric Value | Description |
6//! | --- | --- |
7//! | Multiple (M) | Exploiting the vulnerability requires that the attacker authenticate two or more times, even if the same credentials are used each time. An example is an attacker authenticating to an operating system in addition to providing credentials to access an application hosted on that system. |
8//! | Single (S) | The vulnerability requires an attacker to be logged into the system (such as at a command line or via a desktop session or web interface). |
9//! | None (N) | Authentication is not required to knowledge_base the vulnerability. |
10//!
11//! The metric should be applied based on the authentication the attacker requires before launching an attack.  For example, if a mail server is vulnerable to a command that can be issued before a user authenticates, the metric should be scored as "None" because the attacker can launch the knowledge_base before credentials are required.  If the vulnerable command is only available after successful authentication, then the vulnerability should be scored as "Single" or "Multiple," depending on how many instances of authentication must occur before issuing the command.
12//!
13
14use std::fmt::{Display, Formatter};
15use std::str::FromStr;
16
17use serde::{Deserialize, Serialize};
18
19use crate::error::{CVSSError, Result};
20use crate::metric::{Help, Metric, MetricType, MetricTypeV2, Worth};
21
22/// Authentication
23#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
24#[serde(rename_all = "UPPERCASE")]
25pub enum AuthenticationType {
26  /// requires multiple instances of authentication: 0.45
27  Multiple,
28  /// requires single instance of authentication: 0.56
29  Single,
30  /// requires no authentication: 0.704
31  None,
32}
33
34impl Display for AuthenticationType {
35  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
36    write!(f, "{}:{}", Self::name(), self.as_str())
37  }
38}
39
40impl AuthenticationType {
41  pub fn metric_help(&self) -> Help {
42    self.help()
43  }
44}
45impl Metric for AuthenticationType {
46  const TYPE: MetricType = MetricType::V2(MetricTypeV2::Au);
47
48  fn help(&self) -> Help {
49    match self {
50      Self::Multiple => Help {
51        worth: Worth::Bad,
52        des: "Exploiting the vulnerability requires that the attacker authenticate two or more times, even if the same credentials are used each time. An example is an attacker authenticating to an operating system in addition to providing credentials to access an application hosted on that system.".to_string(),
53      },
54      Self::Single => Help {
55        worth: Worth::Worse,
56        des: "The vulnerability requires an attacker to be logged into the system (such as at a command line or via a desktop session or web interface).".to_string(),
57      },
58      Self::None => Help {
59        worth: Worth::Worst,
60        des: "Authentication is not required to knowledge_base the vulnerability.".to_string(),
61      },
62    }
63  }
64
65  fn score(&self) -> f32 {
66    match self {
67      Self::Multiple => 0.45,
68      Self::Single => 0.56,
69      Self::None => 0.704,
70    }
71  }
72
73  fn as_str(&self) -> &'static str {
74    match self {
75      Self::Multiple => "M",
76      Self::Single => "S",
77      Self::None => "N",
78    }
79  }
80}
81impl FromStr for AuthenticationType {
82  type Err = CVSSError;
83
84  fn from_str(s: &str) -> Result<Self> {
85    let name = Self::name();
86    // let s = s.to_uppercase();
87    let (_name, v) = s
88      .split_once(&format!("{}:", name))
89      .ok_or(CVSSError::InvalidCVSS {
90        key: name.to_string(),
91        value: s.to_string(),
92        expected: name.to_string(),
93      })?;
94    let c = v.chars().next();
95    match c {
96      Some('M') => Ok(Self::Multiple),
97      Some('S') => Ok(Self::Single),
98      Some('N') => Ok(Self::None),
99      _ => Err(CVSSError::InvalidCVSS {
100        key: name.to_string(),
101        value: format!("{:?}", c),
102        expected: "M,S,N".to_string(),
103      }),
104    }
105  }
106}