specification icon indicating copy to clipboard operation
specification copied to clipboard

JSON Schema for vulnerability extension?

Open garethr opened this issue 5 years ago • 16 comments

I see the XML schema has a specific schema extension for describing vulnerability information https://github.com/CycloneDX/specification/blob/master/schema/ext/vulnerability-1.0.xsd

The main page says

The Vulnerability extension provides the ability to represent component vulnerabilities in a BOM. This extension is applicable to CycloneDX v1.1 and higher.

However the ext folder doesn't appear to have the JSON schema https://github.com/CycloneDX/specification/tree/master/schema/ext

Are there any plans to publish a JSON Schema with the vulnerability extension applied?

garethr avatar Aug 22 '20 08:08 garethr

Hi Gareth. Yes, there are plans to port the vulnerability extension to JSON. The vulnerability extension predates CycloneDX v1.2, and therefore JSON support.

The porting of the extension to JSON should be relatively simple. What is much more vague, is how JSON schema supports the validation of two or more schema files when they do not refer to each other. In XML Schema, this is simple to do. I have not seen any examples of this in the JSON Schema world.

So for example, the extensions can refer to the core (if necessary - hopefully not), but the core schema cannot refer to the extensions. It's this type of decoupling that I have not seen in JSON Schema, so I'm not entirely sure how that will impact the design of CycloneDX extensions for JSON, or the validation of them. Thoughts or expertise in this domain are highly welcome.

stevespringett avatar Aug 22 '20 20:08 stevespringett

Looks like the website has a few minor navigation issues i need to look at, but wanted to point you to https://cyclonedx.org/ext/vulnerability/ as well.

stevespringett avatar Aug 22 '20 20:08 stevespringett

Thanks for the info.

I'm not sure a similar extension mechanism exists for JSON Schema unfortunately. My assumption is you'll need to maintain two schemas, one with and one without the extension, or simply indicate the extension properties as optional. So the complexity shifts to some build tooling rather than being a first-class part of the schema.

garethr avatar Aug 23 '20 08:08 garethr

I don't think that's going to scale. There are already 3 extensions. That's a few combinations of extensions+core schema to maintain.

coderpatros avatar Aug 23 '20 12:08 coderpatros

Yup, that's what I mean by probably needing to move the complexity into a build process, and generating the variant schemas. Which would solve the authoring problem at least. Consumption needs context in any case. Not ideal, would be good if JSON Schema does have some in-built extension mechanism.

garethr avatar Aug 23 '20 12:08 garethr

I don't think moving this into a build process is something that would be possible coming from CycloneDX. If today, there are the four extensions available in JSON, and each was only at v1.0, then there would be a lot of permutations. Once additional versions of these become available, the number of permutations will exponentially increase. Add to that future extension that CycloneDX Core Team works on or that are available in various industries, then the number of permutations becomes unmanageable, even with automation.

Spec Current Future...
CycloneDX v1.2 v1.3...
Vulnerability Ext v1.0 v1.1...
Audit Ext v1.0 v1.1...
Formulation Ext v1.0 v1.1...
Hardware Ext v1.0 v1.1...
Future Extensions vx.x v1.1...
Industry Extension vx.x v1.1...

In addition, there is already the published JSON schema which allows any unspecified property to exist and still validate, as well as a strict schema variant which prohibits this behavior. So there's already two different JSON schemas for the core due to bad design choices in JSON Schema itself. So, however many permutations we end up with, there will likely be double.

The inability for JSON Schema to be extensible obviously affects CycloneDX the most. IMO we should likely do the following:

  • Create content on the website that describes the capabilities, limitations, and their impact to adoption for both XML and JSON. This will include how to leverage CycloneDX core and extensions in both XML and JSON.
  • Provide pseudo code example on how this can be achieved in XML and provide high-level build instructions that provide guidance on how to use extensions with JSON.

In other words, I think the CycloneDX project can create and publish JSON extensions, but I don't think we want to be in the business of providing possible permutations. There's going to simply be too many. Adopters of JSON will need to take on that responsibility themselves.

Thoughts?

stevespringett avatar Aug 23 '20 19:08 stevespringett

A slight variant might be for the project to provide two JSON Schema variants - the base (provided now) and one with all official extensions at the latest version. Then push out any other permutation to the adopters. My guess is that would work for the majority of consumers. Advanced users can then dive deeper as needed. But it is just a guess based on thinking about it from a client developers point of view.

garethr avatar Aug 23 '20 21:08 garethr

That may be possible. Two issues I see:

  • The base schema would need to specify the latest version of each extension. It could not specify a specific version. As long as the extensions remain backward compatible, this may not be an issue, but it will be a moving target.
  • Versioned instances of the base schema containing references to all extensions would need to either be mutable or versioned releases change at a different rate than the base schema without the extensions. Neither are ideal.

I remember Bootstrap v3 had the ability to specify what components you wanted included in a custom distribution. It had some checkboxes that allowed users to include or exclude specific parts of Bootstrap. CycloneDX could do something similar. Allow users to choose what (if any) extensions they want, along with the version of the extension they want incorporated into a custom schema. This would obviously only apply to JSON as there would be no need to have such functionality for XML.

stevespringett avatar Aug 25 '20 03:08 stevespringett

@garethr One other possibility for JSON extensions is to perform the validation twice, once for CycloneDX core and once for the extension we want to validate.

This could be done in two ways:

  1. The JSON extension (vulnerability in this case) could be written in such as way as to define its place in the overall BOM (ignoring the details of core) and instead document only the specifics that apply to the extension itself. So if a vulnerabilities array can only appear in the bom object or in a component object, the extension schema could define that + all the details specific to that extension. OR
  2. The JSON extension could be written as a standalone schema, not to be used in conjunction with core. Validation would involve extracting the contents that are not part of the core, identifying what they are, and validating only the relevant character stream.

The first approach can use existing tools. The second approach cannot as it will involve logic to extract and identify prior to the validation step.

In both cases, validation would need to be performed twice however.

Outside of the requirement to validate twice, do you see any issues here with supporting it this way? If not, then do you see any issues with requiring two validation steps?

If we can figure out the details on how to support validation of JSON extensions in a way that does not negatively impact the CycloneDX team, I think creating the JSON vulnerability extension can be achieved in relatively short time. I'd like to get it in your hands to test with (and hopefully provide feedback) prior to release.

stevespringett avatar Sep 24 '20 15:09 stevespringett

I committed an initial version that appears to work. It's a manual port of the existing XML version to JSON. This initial checkin is standalone, meaning that it doesn't take into consideration the rest of the BOM. Once we figure out how to property extend CycloneDX with JSON Schemas, then this work can be modified to meet whatever design choice we choose.

Here's an example of a JSON document that can be validated with the extension. This is the exact same data as used in the XML example https://cyclonedx.org/ext/vulnerability/

{
  "vulnerabilities": [
    {
      "id": "CVE-2018-7489",
      "source": {
        "name": "NVD",
        "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-7489"
      },
      "ratings": [
        {
	  "score": {
	    "base": 9.8,
	    "impact": 5.9,
	    "exploitability": 3.0 
	  },
	  "severity": "Critical",
	  "method": "CVSSv3",
	  "vector": "AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
	},
	{
	  "severity": "Low",
	  "method": "OWASP Risk",
	  "vector": "OWASP/K9:M1:O0:Z2/D1:X1:W1:L3/C2:I1:A1:T1/F1:R1:S2:P3/50"
	}
      ],
      "cwes": [
        184, 502
      ],
      "description": "FasterXML jackson-databind before 2.7.9.3, 2.8.x before 2.8.11.1 and 2.9.x before 2.9.5 allows unauthenticated remote code execution because of an incomplete fix for the CVE-2017-7525 deserialization flaw. This is exploitable by sending maliciously crafted JSON input to the readValue method of the ObjectMapper, bypassing a blacklist that is ineffective if the c3p0 libraries are available in the classpath.",
      "recommendations": [
        "Upgrade"
      ],
      "advisories": [
        "https://github.com/FasterXML/jackson-databind/issues/1931",
        "http://www.securityfocus.com/bid/103203",
        "http://www.securitytracker.com/id/1040693",
        "http://www.securitytracker.com/id/1041890"
      ]
    }
  ]
}

stevespringett avatar Sep 24 '20 21:09 stevespringett

Looking at the JSON schema I see:

"scoreValue": {
  "type": "number",
  "title": "Score",
  "description": "Numerical representation of the vulnerability score. Must be a number between 0 - 10 (maps to lowest severity - highest severity)",
  "multipleOf": 0.1,
  "examples": [7.9, 10.0]
},

https://github.com/CycloneDX/specification/blob/master/schema/ext/vulnerability-1.0-SNAPSHOT.schema.json#L36-L42

But this definition isn't used elsewhere?

~~I'm not familiar enough with the overall schema yet to know where that should be used.~~

Reading the XSD, I don't think this is required in the JSON Schema as the multipleOf is already defined on the three score fields. However the description in the text is not present in the schema. Should look like:

"base": {
  "type": "number",
  "title": "Base Score",
  "description": "The base score of the security vulnerability (Refer CVSS standard for example)",
  "multipleOf": 0.1,
+  "minimum": 0,
+  "maximum": 10,
  "examples": [2.9, 7.2]
},

garethr avatar Oct 13 '20 10:10 garethr

Revisiting this as there's increased demand to support this in the wake of recent supply-chain attacks.

With regard to supporting an unknown number of JSON extensions AND having them validate (see https://github.com/CycloneDX/specification/issues/37#issuecomment-678817145), one approach that did not exist previously, is to use the CycloneDX CLI. This is a newer command line interface, written in .NET Core and is available on a wide variety of platforms as well as Docker. The CLI is a Swiss army knife of sorts as it performs conversion, validation, diff, and other utility functions.

One possibility could be to add an option to the CLI that allows users to create their own custom JSON schema based on the extensions they want to use.

The CLI could:

  • Include the relaxed (default) and strict variant of the JSON schema
  • Include all officially supported JSON schemas (e.g. vulnerability extension)
  • Provide the ability to specify a location or URL to a custom or community-developed extension
  • Ability to merge the schemas and return a single (aggregate) JSON Schema
  • Ability to validate CycloneDX SBOMs from custom JSON Schemas

If the CLI could do these things, it would greatly simplify a lot of things. Not as simple as XML, but I think it would be acceptable.

Thoughts on this approach?

If acceptable, we might have a path forward and should be able to unblock this issue - and any updates to the vulnerability extension.

stevespringett avatar Apr 21 '21 03:04 stevespringett

I also think that JSON extension schemas need a prefix for ALL properties and definitions.

Due to JSON not supporting namespaces, we need a way to avoid current and future collisions in property names and definitions.

Something like ext-vulnerabilities or v-1.0-vulnerabilities. I personally prefer the second one as its more inline with the namespace alias and version that XML uses.

stevespringett avatar Apr 21 '21 03:04 stevespringett

I am +1 on using long, less than likely to collide names, given the other options I know of are JSON-LD, or at worst trying to emulate XML namespaces entirely.

Feedback from here forward is just a bit informed from working on cyclonedx-core-java, so it's a lil bit slanted towards that experience, but figured I'd pop it in here:

Would personally suggest vulnerabilitiesExtensionV10 or vulnerabilities_extension_v10 (Jackson likes camelCase, but can use snake_case). Hyphens are fine but ObjectMappers etc... don't interpret them as easily (you have to annotate a lot). This is more of a general comment though, in the case of the Vulnerabilities extension we already have to do a lot of funky magic :)

Prefixing the properties COULD get messy long term implementation wise, because you'd have to add aliases to pick them up, in the case of something getting absorbed into the main project (or new Models, etc...). Making sure the top level is named in.a non colliding way makes it fairly easy in the case of something it into the main spec to just switch it to a real property and have things keep working (2 cents!)

DarthHater avatar Apr 21 '21 03:04 DarthHater

Another option would be to include all extensions in the dedicated part of the SBOM.

Top level elements consist of:

  • metadata
  • components
  • services
  • dependencies
  • compositions (in v1.3)

It may be possible to add 'extensions' as another top level element and bundle all extensions in there, then simply use bom-ref to refer to the components or services.

This approach may be cleaner than trying to add extensions to existing parts of the SBOM. We wouldn't have to worry as much about collisions of properties, but would still need to worry about collisions of definitions in the JSON Schema.

If extensions are to be a top level element, this needs to be decided on right away as v1.3 is nearly complete.

stevespringett avatar Apr 21 '21 15:04 stevespringett

I am not against that (it probably simplifies some code stuff tbh)

DarthHater avatar Apr 21 '21 18:04 DarthHater