Skip to content

Commit

Permalink
fix: use correct types for modifiedSub*
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremylong committed Feb 16, 2025
1 parent 59d6b88 commit 18d9c98
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ public CvssV4Data(Version version, String vectorString, AttackVectorType attackV
ModifiedPrivilegesRequiredType modifiedPrivilegesRequired,
ModifiedUserInteractionType modifiedUserInteraction, ModifiedCiaType modifiedVulnConfidentialityImpact,
ModifiedCiaType modifiedVulnIntegrityImpact, ModifiedCiaType modifiedVulnAvailabilityImpact,
ModifiedCiaType modifiedSubConfidentialityImpact, ModifiedCiaType modifiedSubIntegrityImpact,
ModifiedCiaType modifiedSubAvailabilityImpact, SafetyType safety, AutomatableType automatable,
ModifiedSubCType modifiedSubConfidentialityImpact, ModifiedSubIaType modifiedSubIntegrityImpact,
ModifiedSubIaType modifiedSubAvailabilityImpact, SafetyType safety, AutomatableType automatable,
RecoveryType recovery, ValueDensityType valueDensity,
VulnerabilityResponseEffortType vulnerabilityResponseEffort, ProviderUrgencyType providerUrgency,
Double baseScore, SeverityType baseSeverity, Double threatScore, SeverityType threatSeverity,
Expand Down Expand Up @@ -200,15 +200,15 @@ public CvssV4Data(Version version, String vectorString, AttackVectorType attackV
@JsonProperty("modifiedSubsequentSystemConfidentiality")
@JsonAlias("modifiedSubConfidentialityImpact")
@JsonSetter(nulls = Nulls.SKIP)
private ModifiedCiaType modifiedSubConfidentialityImpact = ModifiedCiaType.NOT_DEFINED;
private ModifiedSubCType modifiedSubConfidentialityImpact = ModifiedSubCType.NOT_DEFINED;
@JsonProperty("modifiedSubsequentSystemIntegrity")
@JsonAlias("modifiedSubIntegrityImpact")
@JsonSetter(nulls = Nulls.SKIP)
private ModifiedCiaType modifiedSubIntegrityImpact = ModifiedCiaType.NOT_DEFINED;
private ModifiedSubIaType modifiedSubIntegrityImpact = ModifiedSubIaType.NOT_DEFINED;
@JsonProperty("modifiedSubsequentSystemAvailability")
@JsonAlias("modifiedSubAvailabilityImpact")
@JsonSetter(nulls = Nulls.SKIP)
private ModifiedCiaType modifiedSubAvailabilityImpact = ModifiedCiaType.NOT_DEFINED;
private ModifiedSubIaType modifiedSubAvailabilityImpact = ModifiedSubIaType.NOT_DEFINED;
@JsonProperty("safety")
@JsonAlias("Safety")
@JsonSetter(nulls = Nulls.SKIP)
Expand Down Expand Up @@ -477,23 +477,23 @@ public ModifiedCiaType getModifiedVulnAvailabilityImpact() {
* @return modifiedSubConfidentialityImpact
*/
@JsonProperty("modifiedSubConfidentialityImpact")
public ModifiedCiaType getModifiedSubConfidentialityImpact() {
public ModifiedSubCType getModifiedSubConfidentialityImpact() {
return modifiedSubConfidentialityImpact;
}

/**
* @return modifiedSubIntegrityImpact
*/
@JsonProperty("modifiedSubIntegrityImpact")
public ModifiedCiaType getModifiedSubIntegrityImpact() {
public ModifiedSubIaType getModifiedSubIntegrityImpact() {
return modifiedSubIntegrityImpact;
}

/**
* @return modifiedSubAvailabilityImpact
*/
@JsonProperty("modifiedSubAvailabilityImpact")
public ModifiedCiaType getModifiedSubAvailabilityImpact() {
public ModifiedSubIaType getModifiedSubAvailabilityImpact() {
return modifiedSubAvailabilityImpact;
}

Expand Down Expand Up @@ -650,15 +650,15 @@ public String toString() {
}
// (\/MSC:[XNLH])?(\/MSI:[XNLHS])?(\/MSA:[XNLHS])?(\/S:[XNP])?(\/AU:[XNY])?(\/R:[XAUI])?
if (modifiedSubConfidentialityImpact != null) {
v.append("/MSC:").append(modifiedSubConfidentialityImpact == ModifiedCiaType.NOT_DEFINED ? "X"
v.append("/MSC:").append(modifiedSubConfidentialityImpact == ModifiedSubCType.NOT_DEFINED ? "X"
: modifiedSubConfidentialityImpact.value().charAt(0));
}
if (modifiedSubIntegrityImpact != null) {
v.append("/MSI:").append(modifiedSubIntegrityImpact == ModifiedCiaType.NOT_DEFINED ? "X"
v.append("/MSI:").append(modifiedSubIntegrityImpact == ModifiedSubIaType.NOT_DEFINED ? "X"
: modifiedSubIntegrityImpact.value().charAt(0));
}
if (modifiedSubAvailabilityImpact != null) {
v.append("/MSA:").append(modifiedSubAvailabilityImpact == ModifiedCiaType.NOT_DEFINED ? "X"
v.append("/MSA:").append(modifiedSubAvailabilityImpact == ModifiedSubIaType.NOT_DEFINED ? "X"
: modifiedSubAvailabilityImpact.value().charAt(0));
}
if (safety != null) {
Expand Down Expand Up @@ -1239,6 +1239,106 @@ public String value() {

}

public enum ModifiedSubCType {

NEGLIGIBLE("NEGLIGIBLE"), LOW("LOW"), HIGH("HIGH"), NOT_DEFINED("NOT_DEFINED");

private final static Map<String, ModifiedSubCType> CONSTANTS = new HashMap<>();

static {
for (ModifiedSubCType c : values()) {
CONSTANTS.put(c.value, c);
}
}

private final String value;

ModifiedSubCType(String value) {
this.value = value;
}

@JsonCreator
public static ModifiedSubCType fromValue(String value) {
// allow conversion from vector string
if (value != null && value.length() == 1) {
if ("x".equalsIgnoreCase(value)) {
return NOT_DEFINED;
}
for (ModifiedSubCType t : values()) {
if (t.value.startsWith(value.toUpperCase())) {
return t;
}
}
}
ModifiedSubCType constant = CONSTANTS.get(value);
if (constant == null) {
throw new IllegalArgumentException(value);
} else {
return constant;
}
}

@Override
public String toString() {
return this.value;
}

@JsonValue
public String value() {
return this.value;
}
}

public enum ModifiedSubIaType {

NEGLIGIBLE("NEGLIGIBLE"), LOW("LOW"), HIGH("HIGH"), SAFETY("SAFETY"), NOT_DEFINED("NOT_DEFINED");

private final static Map<String, ModifiedSubIaType> CONSTANTS = new HashMap<>();

static {
for (ModifiedSubIaType c : values()) {
CONSTANTS.put(c.value, c);
}
}

private final String value;

ModifiedSubIaType(String value) {
this.value = value;
}

@JsonCreator
public static ModifiedSubIaType fromValue(String value) {
// allow conversion from vector string
if (value != null && value.length() == 1) {
if ("x".equalsIgnoreCase(value)) {
return NOT_DEFINED;
}
for (ModifiedSubIaType t : values()) {
if (t.value.startsWith(value.toUpperCase())) {
return t;
}
}
}
ModifiedSubIaType constant = CONSTANTS.get(value);
if (constant == null) {
throw new IllegalArgumentException(value);
} else {
return constant;
}
}

@Override
public String toString() {
return this.value;
}

@JsonValue
public String value() {
return this.value;
}
}

public enum SafetyType {

NEGLIGIBLE("NEGLIGIBLE"), PRESENT("PRESENT"), NOT_DEFINED("NOT_DEFINED");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void thereAndBackAgain() throws IOException {
json = r.lines().collect(Collectors.joining("\n"));
}
CveApiJson20 current = objectMapper.readValue(json, CveApiJson20.class);
assertEquals(2000, current.getVulnerabilities().size());
assertEquals(2001, current.getVulnerabilities().size());

String serialized = objectMapper.writeValueAsString(current);
CveApiJson20 hydrated = objectMapper.readValue(serialized, CveApiJson20.class);
Expand Down
84 changes: 84 additions & 0 deletions open-vulnerability-clients/src/test/resources/nvd.json
Original file line number Diff line number Diff line change
Expand Up @@ -323476,6 +323476,90 @@
}
]
}
},
{
"cve": {
"id": "CVE-2025-26793",
"sourceIdentifier": "[email protected]",
"published": "2025-02-15T15:15:23.587",
"lastModified": "2025-02-15T15:15:23.587",
"vulnStatus": "Received",
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "The Web GUI configuration panel of Hirsch (formerly Identiv and Viscount) Enterphone MESH through 2024 ships with default credentials (username freedom, password viscount). The administrator is not prompted to change these credentials on initial configuration, and changing the credentials requires many steps. Attackers can use the credentials over the Internet via mesh.webadmin.MESHAdminServlet to gain access to dozens of Canadian and U.S. apartment buildings and obtain building residents' PII. NOTE: the Supplier's perspective is that the \"vulnerable systems are not following manufacturers' recommendations to change the default password.\""
}
],
"metrics": {
"cvssMetricV40": [
{
"source": "[email protected]",
"type": "Secondary",
"cvssData": {
"version": "4.0",
"vectorString": "CVSS:4.0\/AV:N\/AC:L\/AT:N\/PR:N\/UI:N\/VC:H\/VI:H\/VA:N\/SC:N\/SI:N\/SA:N\/E:X\/CR:X\/IR:X\/AR:X\/MAV:X\/MAC:X\/MAT:X\/MPR:X\/MUI:X\/MVC:X\/MVI:X\/MVA:X\/MSC:X\/MSI:S\/MSA:X\/S:P\/AU:X\/R:X\/V:X\/RE:X\/U:X",
"baseScore": 10.0,
"baseSeverity": "CRITICAL",
"attackVector": "NETWORK",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"privilegesRequired": "NONE",
"userInteraction": "NONE",
"vulnerableSystemConfidentiality": "HIGH",
"vulnerableSystemIntegrity": "HIGH",
"vulnerableSystemAvailability": "NONE",
"subsequentSystemConfidentiality": "NONE",
"subsequentSystemIntegrity": "NONE",
"subsequentSystemAvailability": "NONE",
"exploitMaturity": "NOT_DEFINED",
"confidentialityRequirements": "NOT_DEFINED",
"integrityRequirements": "NOT_DEFINED",
"availabilityRequirements": "NOT_DEFINED",
"modifiedAttackVector": "NOT_DEFINED",
"modifiedAttackComplexity": "NOT_DEFINED",
"modifiedAttackRequirements": "NOT_DEFINED",
"modifiedPrivilegesRequired": "NOT_DEFINED",
"modifiedUserInteraction": "NOT_DEFINED",
"modifiedVulnerableSystemConfidentiality": "NOT_DEFINED",
"modifiedVulnerableSystemIntegrity": "NOT_DEFINED",
"modifiedVulnerableSystemAvailability": "NOT_DEFINED",
"modifiedSubsequentSystemConfidentiality": "NOT_DEFINED",
"modifiedSubsequentSystemIntegrity": "SAFETY",
"modifiedSubsequentSystemAvailability": "NOT_DEFINED",
"safety": "PRESENT",
"automatable": "NOT_DEFINED",
"recovery": "NOT_DEFINED",
"valueDensity": "NOT_DEFINED",
"vulnerabilityResponseEffort": "NOT_DEFINED",
"providerUrgency": "NOT_DEFINED"
}
}
]
},
"weaknesses": [
{
"source": "[email protected]",
"type": "Secondary",
"description": [
{
"lang": "en",
"value": "CWE-1393"
}
]
}
],
"references": [
{
"url": "https:\/\/support.identiv.com\/products\/physical-access\/hirsch\/",
"source": "[email protected]"
},
{
"url": "https:\/\/www.ericdaigle.ca\/posts\/breaking-into-dozens-of-apartments-in-five-minutes\/",
"source": "[email protected]"
}
]
}
}
]
}

0 comments on commit 18d9c98

Please sign in to comment.