Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
6 of 17 tasks
ajnelson-nist opened this issue Aug 2, 2024 · 2 comments · May be fixed by #627
Open
6 of 17 tasks

Comments

@ajnelson-nist
Copy link
Contributor

ajnelson-nist commented Aug 2, 2024

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
@ajnelson-nist ajnelson-nist added this to the UCO 1.4.0 milestone Aug 2, 2024
ajnelson-nist added a commit that referenced this issue Aug 2, 2024
A follow-on patch will regenerate Make-managed files.

References:
* #626

Signed-off-by: Alex Nelson <[email protected]>
ajnelson-nist added a commit that referenced this issue Aug 2, 2024
References:
* #626

Signed-off-by: Alex Nelson <[email protected]>
@ajnelson-nist
Copy link
Contributor Author

Implementation of this proposal is blocked on #632 .

@ajnelson-nist
Copy link
Contributor Author

Proposal update, in light of a remark from @sbarnum on Issue 596 (Restructuring the Software class hierarchy):

@sbarnum offered several disjointedness statements for subclasses of Software. Among them was that Application and OperatingSystem are disjoint classes.

This makes me now think that Requirement 3 of this proposal is not quite correct. It is currently spelled:

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

The implementation for this proposal had not gotten to testing interactions with #632 (making OperatingSystem a subclass of Software), but I now suspect once testing this proposal reaches 632's implementation, there would be a conflict. Because OperatingSystem is a subclass of Software, the Software review rule would trigger on an operating system and cause an unsatisfiable condition.

It seems Requirement 3 must be spelled differently - at the very least, like this:

UCO must constrain CPEs for Software to use an a Part (for applications), unless the instance of Software is also an OperatingSystem.

When I was drafting the proposal, I had forgotten that Application is a class in UCO, and further that Issue 596 moves Application under Software as well. (At the moment, Application is just under ObservableObject.)

I think Requirement 3 should be replaced with:

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

I also think this proposal now needs Application's move under Software to finish. As a potential alignment benefit, the disjointedness between Application and OperatingSystem also becomes entailed and consistent with the restriction on CPE "Part".

For further reference, the other disjointedness statements around Application and OperatingSystem worked out to this when their symmetry was checked from Sean's other suggestions. Fortunately, I think there's no further influence on this proposal.

uco-observable:Application
        owl:disjointWith
                drafting:ServicePack ,
                drafting:Task ,
                uco-observable:Library ,
                uco-observable:OperatingSystem ,
                uco-observable:Process ,
                uco-observable:ProcessThread
                ;
        .
uco-observable:OperatingSystem
        owl:disjointWith
                drafting:BuildUtility ,
                drafting:Compiler ,
                drafting:ServicePack ,
                drafting:Task ,
                uco-observable:Application ,
                uco-observable:Library ,
                uco-observable:Process ,
                uco-observable:ProcessThread
                ;
        .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant