Skip to content

cpeid should constrain values through CPE version and "Part" component of Well-Formed Name #626

@ajnelson-nist

Description

@ajnelson-nist

Background

observable:cpeid is currently (as of UCO 1.3.0) an unconstrained string.

The CPE 2.3 naming specification, NISTIR 7695 provides syntactic constraints for a "Well-Formed Name" (WFN). Some seem appropriate to include in UCO:

  • The version of CPE.
  • The Part (Section 5.3.3.1), which takes one of three values.

Prior versions of the CPE specification(s) are currently available here, but they are not referenced further in this proposal.

Requirements

Requirement 1

UCO must constrain CPEs in cpeid to be specified as Well-Formed-Names of the current version, 2.3.

(Aside: This intentionally excludes URI forms from being used in cpeid.)

Requirement 2

UCO must constrain CPEs for Devices to use an h Part (for hardware devices).

Requirement 3

UCO must constrain CPEs for Software to use an a Part (for applications).

Revision suggested (2024-11-06) after requirements review vote (2024-10-24): Change to:

UCO must constrain CPEs for Application to use an a Part (for applications).
This requirement entails:

  • Application must be a subclass of Software.
  • Application must be disjoint with OperatingSystem.

Requirement 4

UCO must constrain CPEs for OperatingSystem to use an o Part (for operating systems).

Non-Requirements

No further constraints on CPE WFN parts are suggested in this proposal. Handling the entire grammar, including escape sequences, makes even counting the number of fields by colon-delimiting likely too cumbersome for a single regular expression to be beneficial.

Risk / Benefit analysis

Benefits

  • Keeping recorded CPEs consistent between CPE's class hierarchy and UCO's offers improved interoperability potential, e.g., between multiple inventorying systems that have mixes of CPEs and UCO annotations.
  • Constraining the Part attribute will prevent confusion from errant assignments, e.g. designating a tablet device as having an o observable:cpeid value because of conflation from its operating system.
  • Requiring WFNs would prevent errant assignment of URI forms of CPEs (NISTIR 7695 Section 6.1.1).

Risks

  • This proposal requires completion of Devices should have CPEs associable #624.
  • This proposal requires, in spirit, either Restructuring the Software class hierarchy #596 or a reduced proposal of 596 that includes the move of OperatingSystem under Software. However, the implementation does not necessarily need to wait for either of these conditions to be met.
  • Because cpeid does not appear in OperatingSystemFacet, and Issue 596 will make OperatingSystems a subclass of Software, the SHACL spelling for operating system CPEs will necessarily be a bit different from the typical UCO spelling for other property constraints, and this difference will be visible to end users. The accompanying Pull Request targeting 1.4.0 shows the validation results of what seems like the most practical shape.

Competencies demonstrated

Competency 1

Error detection: A tablet device is given an operating system CPE.

{
    "@context": {
        "kb": "http://example.org/kb/",
        "core": "https://ontology.unifiedcyberontology.org/uco/core/",
        "observable": "https://ontology.unifiedcyberontology.org/uco/observable/"
    },
    "@graph": [
        {
            "@id": "kb:Device-3b8fde6f-0f0b-4472-b9c8-31380eb80dc3",
            "@type": "observable:Tablet",
            "core:hasFacet": {
                "@id": "kb:DeviceFacet-4a1cdff8-be81-46e3-8502-0f488d353ca0",
                "@type": "observable:DeviceFacet",
                "observable:cpeid": "cpe:2.3:o:exampleco:exampletabletos:-:*:*:*:*:*:*:*"
            }
        }
    ]
}

Competency Question 1.1

Is this a valid usage of that CPE WFN?

Result 1.1

No.

The WFN having an o value implies the associated item (the observable:Tablet) should be an operating system. But, it is a device (i.e., an instance of an observable:Device subclass).

If that WFN is desired to appear in the graph, the operating system of the device should be modeled as a separate object and tied to the device with an observable:ObservableRelationship.

Solution suggestion

(I am fine with my examples being transcribed and credited.)

  • For DeviceFacet in UCO 1.4.0: Add a dedicated shape, severity sh:Warning, to require a pattern regular expression:
observable:DeviceFacet
	sh:property [
		sh:message "In UCO 2.0.0, cpeid in DeviceFacet will be constrained to be a CPE version 2.3 hardware name."@en ;
		sh:path observable:cpeid ;
		sh:pattern "^cpe:2.3:h:.+" ;
		sh:severity sh:Warning ;
	] ;
	.
  • For DeviceFacet in UCO 2.0.0, cut that property shape, moving the sh:pattern statement into the property shape for observable:cpeid.

  • Do likewise for SoftwareFacet, only its pattern would be ^cpe:2.3:[a,o]:.+.

  • Disallow cpeid from OperatingSystemFacet, guiding users to use SoftwareFacet instead, and change severity from warning to violation for UCO 2.0.0:

observable:OperatingSystemFacet
	sh:property [
		sh:maxCount "0"^^xsd:integer ;
		sh:message "observable:cpeid should appear on a SoftwareFacet instead of an OperatingSystemFacet."@en ;
		sh:path observable:cpeid ;
		sh:severity sh:Warning ;
	] ;
	.
  • For OperatingSystem, constrain CPEs to only use the o Part value. This property shape may sufficiently satisfy this implementation, by using a path through two predicates; however, it avoids qualifying which Facet this applies to.
# NOTE: The PropertyShape is not on a Facet subclass.
observable:OperatingSystem
	sh:property [
		sh:message "In UCO 2.0.0, cpeid in any Facet attached to an OperatingSystem will be constrained to be a CPE version 2.3 operating system name."@en ;
		sh:path (
			core:hasFacet
			observable:cpeid
		) ;
		sh:pattern "^cpe:2.3:o:.+" ;
		sh:severity sh:Warning ;
	] ;
	.

Aside on unpursued option

A "more correct" constraining would instead apply the o pattern only on a SoftwareFacet, which can be done in a few ways. Unfortunately, each is complex to implement without adding additional single-purpose OWL Classes never really meant for a user to explicitly instantiate, or complex spellings of "if P then Q" using sh:or. Any of these solutions is likely to be unnecessarily challenging to parse to any end user who ultimately put an a where an o should have gone.

For example (and it's hopefully clear why this is not in the pull request): In SHACL, spelling "If P, then Q" when custom classes are not an option needs to be done with the Implication-as-Or's spelling, "p → q ≡ ¬p ∨ q". Hence, the option for representing "IF this SoftwareFacet is a facet of an OperatingSystem object, THEN apply the 'o' CPE pattern constraint" is as follows:

observable:SoftwareFacet
	sh:property [
		sh:message "In UCO 2.0.0, cpeid in a SoftwareFacet attached to an OperatingSystem will be constrained to be a CPE version 2.3 operating system name."@en ;
		sh:or (
			[
				sh:not [
					sh:property [
						sh:class observable:OperatingSystem ;
						sh:path (
							sh:inversePath [
								observable:cpeid ;
							]
							sh:inversePath [
								core:hasFacet
							]
						) ;
						# The path starts at the string-literal of the CPE,
						# then goes back to the SoftwareFacet,
						# then goes back to the ObservableObject.
					] ;
				] ;
			]
			[
				sh:pattern "^cpe:2.3:o:.+" ;
			]
		) ;
		sh:path observable:cpeid ;
		sh:severity sh:Warning ;
	] ;
	.

A blanket review of cpeid from observable:OperatingSystem seems more palatable.

Coordination

  • Tracking in Jira ticket OCUCO-321
  • Administrative review completed, proposal announced to Ontology Committees (OCs) on 2024-08-02
  • Requirements to be discussed in OC meeting, 2024-08-20
  • Requirements to be discussed in OC meeting, 2024-10-24
  • Requirements Review vote occurred, passing, on 2024-10-24
  • Requirements development phase completed.
  • Solution includes warning on finding CPE version > 2.3
  • Solution announced to OCs on TODO-date
  • Solutions Approval to be discussed in OC meeting, date TBD
  • Solutions Approval vote has not occurred
  • Solutions development phase completed.
  • Backwards-compatible implementation merged into develop for the next release
  • develop state with backwards-compatible implementation merged into develop-2.0.0
  • Backwards-incompatible implementation merged into develop-2.0.0 (or N/A)
  • Milestone linked
  • Documentation logged in pending release page
  • Prerelease publication: CASE develop branch updated to track UCO's updated develop branch
  • Prerelease publication: CASE develop-2.0.0 branch updated to track UCO's updated develop-2.0.0 branch

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions