mirror of
https://github.com/gocsaf/csaf.git
synced 2025-12-22 18:15:42 +01:00
Merge pull request #7 from csaf-poc/validate-csaf-schema-alt
Validate csaf schema
This commit is contained in:
commit
75bf445c71
10 changed files with 1873 additions and 1 deletions
|
|
@ -27,6 +27,7 @@ type config struct {
|
||||||
OpenPGPURL string `toml:"openpgp_url"`
|
OpenPGPURL string `toml:"openpgp_url"`
|
||||||
Domain string `toml:"domain"`
|
Domain string `toml:"domain"`
|
||||||
NoPassphrase bool `toml:"no_passphrase"`
|
NoPassphrase bool `toml:"no_passphrase"`
|
||||||
|
NoValidation bool `toml:"no_validation"`
|
||||||
DynamicProviderMetaData bool `toml:"dynamic_provider_metadata"`
|
DynamicProviderMetaData bool `toml:"dynamic_provider_metadata"`
|
||||||
Publisher *csaf.Publisher `toml:"publisher"`
|
Publisher *csaf.Publisher `toml:"publisher"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,14 @@ func (c *controller) render(rw http.ResponseWriter, tmpl string, arg interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) failed(rw http.ResponseWriter, tmpl string, err error) {
|
func (c *controller) failed(rw http.ResponseWriter, tmpl string, err error) {
|
||||||
|
rw.Header().Set("Content-type", "text/html; charset=utf-8")
|
||||||
|
result := map[string]interface{}{"Error": []error{err}}
|
||||||
|
if err := c.tmpl.ExecuteTemplate(rw, tmpl, result); err != nil {
|
||||||
|
log.Printf("warn: %v\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *controller) multiFailed(rw http.ResponseWriter, tmpl string, err interface{}) {
|
||||||
rw.Header().Set("Content-type", "text/html; charset=utf-8")
|
rw.Header().Set("Content-type", "text/html; charset=utf-8")
|
||||||
result := map[string]interface{}{"Error": err}
|
result := map[string]interface{}{"Error": err}
|
||||||
if err := c.tmpl.ExecuteTemplate(rw, tmpl, result); err != nil {
|
if err := c.tmpl.ExecuteTemplate(rw, tmpl, result); err != nil {
|
||||||
|
|
@ -188,6 +196,20 @@ func (c *controller) upload(rw http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate againt JSON schema.
|
||||||
|
if !c.cfg.NoValidation {
|
||||||
|
validationErrors, err := csaf.ValidateCSAF(content)
|
||||||
|
if err != nil {
|
||||||
|
c.failed(rw, "upload.html", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(validationErrors) > 0 {
|
||||||
|
c.multiFailed(rw, "upload.html", validationErrors)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ex, err := newExtraction(content)
|
ex, err := newExtraction(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.failed(rw, "upload.html", err)
|
c.failed(rw, "upload.html", err)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,18 @@
|
||||||
<body>
|
<body>
|
||||||
<h1>CSAF-Provider - CSAF uploaded</h1>
|
<h1>CSAF-Provider - CSAF uploaded</h1>
|
||||||
{{ if .Error }}
|
{{ if .Error }}
|
||||||
<strong>Error: <tt>{{ .Error }}.</tt></strong>
|
{{ if eq (len .Error) 1 }}
|
||||||
|
<strong>Error: <tt>{{ index .Error 0 }}.</tt></strong>
|
||||||
|
{{ else }}
|
||||||
|
<p>
|
||||||
|
Errors:
|
||||||
|
<ul>
|
||||||
|
{{ range .Error }}
|
||||||
|
<li>{{ . }}</li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
{{ end }}
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<table>
|
<table>
|
||||||
<tr><td>CSAF file:</td><td><tt>{{ .Name }}</tt></td></tr>
|
<tr><td>CSAF file:</td><td><tt>{{ .Name }}</tt></td></tr>
|
||||||
|
|
|
||||||
1343
csaf/schema/csaf_json_schema.json
Normal file
1343
csaf/schema/csaf_json_schema.json
Normal file
File diff suppressed because it is too large
Load diff
104
csaf/schema/cvss-v2.0.json
Normal file
104
csaf/schema/cvss-v2.0.json
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
{
|
||||||
|
"license": [
|
||||||
|
"Copyright (c) 2017, FIRST.ORG, INC.",
|
||||||
|
"All rights reserved.",
|
||||||
|
"",
|
||||||
|
"Redistribution and use in source and binary forms, with or without modification, are permitted provided that the ",
|
||||||
|
"following conditions are met:",
|
||||||
|
"1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following ",
|
||||||
|
" disclaimer.",
|
||||||
|
"2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the ",
|
||||||
|
" following disclaimer in the documentation and/or other materials provided with the distribution.",
|
||||||
|
"3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote ",
|
||||||
|
" products derived from this software without specific prior written permission.",
|
||||||
|
"",
|
||||||
|
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, ",
|
||||||
|
"INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ",
|
||||||
|
"DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ",
|
||||||
|
"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ",
|
||||||
|
"SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ",
|
||||||
|
"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ",
|
||||||
|
"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
],
|
||||||
|
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
|
"title": "JSON Schema for Common Vulnerability Scoring System version 2.0",
|
||||||
|
"id": "https://www.first.org/cvss/cvss-v2.0.json?20170531",
|
||||||
|
"type": "object",
|
||||||
|
"definitions": {
|
||||||
|
"accessVectorType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NETWORK", "ADJACENT_NETWORK", "LOCAL" ]
|
||||||
|
},
|
||||||
|
"accessComplexityType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "HIGH", "MEDIUM", "LOW" ]
|
||||||
|
},
|
||||||
|
"authenticationType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "MULTIPLE", "SINGLE", "NONE" ]
|
||||||
|
},
|
||||||
|
"ciaType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "PARTIAL", "COMPLETE" ]
|
||||||
|
},
|
||||||
|
"exploitabilityType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "UNPROVEN", "PROOF_OF_CONCEPT", "FUNCTIONAL", "HIGH", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"remediationLevelType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "OFFICIAL_FIX", "TEMPORARY_FIX", "WORKAROUND", "UNAVAILABLE", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"reportConfidenceType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "UNCONFIRMED", "UNCORROBORATED", "CONFIRMED", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"collateralDamagePotentialType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "LOW", "LOW_MEDIUM", "MEDIUM_HIGH", "HIGH", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"targetDistributionType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "LOW", "MEDIUM", "HIGH", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"ciaRequirementType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "LOW", "MEDIUM", "HIGH", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"scoreType": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"version": {
|
||||||
|
"description": "CVSS Version",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "2.0" ]
|
||||||
|
},
|
||||||
|
"vectorString": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^((AV:[NAL]|AC:[LMH]|Au:[MSN]|[CIA]:[NPC]|E:(U|POC|F|H|ND)|RL:(OF|TF|W|U|ND)|RC:(UC|UR|C|ND)|CDP:(N|L|LM|MH|H|ND)|TD:(N|L|M|H|ND)|[CIA]R:(L|M|H|ND))/)*(AV:[NAL]|AC:[LMH]|Au:[MSN]|[CIA]:[NPC]|E:(U|POC|F|H|ND)|RL:(OF|TF|W|U|ND)|RC:(UC|UR|C|ND)|CDP:(N|L|LM|MH|H|ND)|TD:(N|L|M|H|ND)|[CIA]R:(L|M|H|ND))$"
|
||||||
|
},
|
||||||
|
"accessVector": { "$ref": "#/definitions/accessVectorType" },
|
||||||
|
"accessComplexity": { "$ref": "#/definitions/accessComplexityType" },
|
||||||
|
"authentication": { "$ref": "#/definitions/authenticationType" },
|
||||||
|
"confidentialityImpact": { "$ref": "#/definitions/ciaType" },
|
||||||
|
"integrityImpact": { "$ref": "#/definitions/ciaType" },
|
||||||
|
"availabilityImpact": { "$ref": "#/definitions/ciaType" },
|
||||||
|
"baseScore": { "$ref": "#/definitions/scoreType" },
|
||||||
|
"exploitability": { "$ref": "#/definitions/exploitabilityType" },
|
||||||
|
"remediationLevel": { "$ref": "#/definitions/remediationLevelType" },
|
||||||
|
"reportConfidence": { "$ref": "#/definitions/reportConfidenceType" },
|
||||||
|
"temporalScore": { "$ref": "#/definitions/scoreType" },
|
||||||
|
"collateralDamagePotential": { "$ref": "#/definitions/collateralDamagePotentialType" },
|
||||||
|
"targetDistribution": { "$ref": "#/definitions/targetDistributionType" },
|
||||||
|
"confidentialityRequirement": { "$ref": "#/definitions/ciaRequirementType" },
|
||||||
|
"integrityRequirement": { "$ref": "#/definitions/ciaRequirementType" },
|
||||||
|
"availabilityRequirement": { "$ref": "#/definitions/ciaRequirementType" },
|
||||||
|
"environmentalScore": { "$ref": "#/definitions/scoreType" }
|
||||||
|
},
|
||||||
|
"required": [ "version", "vectorString", "baseScore" ]
|
||||||
|
}
|
||||||
143
csaf/schema/cvss-v3.0.json
Normal file
143
csaf/schema/cvss-v3.0.json
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
{
|
||||||
|
"license": [
|
||||||
|
"Copyright (c) 2017, FIRST.ORG, INC.",
|
||||||
|
"All rights reserved.",
|
||||||
|
"",
|
||||||
|
"Redistribution and use in source and binary forms, with or without modification, are permitted provided that the ",
|
||||||
|
"following conditions are met:",
|
||||||
|
"1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following ",
|
||||||
|
" disclaimer.",
|
||||||
|
"2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the ",
|
||||||
|
" following disclaimer in the documentation and/or other materials provided with the distribution.",
|
||||||
|
"3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote ",
|
||||||
|
" products derived from this software without specific prior written permission.",
|
||||||
|
"",
|
||||||
|
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, ",
|
||||||
|
"INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ",
|
||||||
|
"DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ",
|
||||||
|
"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ",
|
||||||
|
"SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ",
|
||||||
|
"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ",
|
||||||
|
"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
],
|
||||||
|
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
|
"title": "JSON Schema for Common Vulnerability Scoring System version 3.0",
|
||||||
|
"id": "https://www.first.org/cvss/cvss-v3.0.json?20170531",
|
||||||
|
"type": "object",
|
||||||
|
"definitions": {
|
||||||
|
"attackVectorType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NETWORK", "ADJACENT_NETWORK", "LOCAL", "PHYSICAL" ]
|
||||||
|
},
|
||||||
|
"modifiedAttackVectorType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NETWORK", "ADJACENT_NETWORK", "LOCAL", "PHYSICAL", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"attackComplexityType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "HIGH", "LOW" ]
|
||||||
|
},
|
||||||
|
"modifiedAttackComplexityType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "HIGH", "LOW", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"privilegesRequiredType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "HIGH", "LOW", "NONE" ]
|
||||||
|
},
|
||||||
|
"modifiedPrivilegesRequiredType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "HIGH", "LOW", "NONE", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"userInteractionType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "REQUIRED" ]
|
||||||
|
},
|
||||||
|
"modifiedUserInteractionType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "REQUIRED", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"scopeType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "UNCHANGED", "CHANGED" ]
|
||||||
|
},
|
||||||
|
"modifiedScopeType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "UNCHANGED", "CHANGED", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"ciaType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "LOW", "HIGH" ]
|
||||||
|
},
|
||||||
|
"modifiedCiaType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "LOW", "HIGH", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"exploitCodeMaturityType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "UNPROVEN", "PROOF_OF_CONCEPT", "FUNCTIONAL", "HIGH", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"remediationLevelType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "OFFICIAL_FIX", "TEMPORARY_FIX", "WORKAROUND", "UNAVAILABLE", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"confidenceType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "UNKNOWN", "REASONABLE", "CONFIRMED", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"ciaRequirementType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "LOW", "MEDIUM", "HIGH", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"scoreType": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 10
|
||||||
|
},
|
||||||
|
"severityType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "LOW", "MEDIUM", "HIGH", "CRITICAL" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"version": {
|
||||||
|
"description": "CVSS Version",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "3.0" ]
|
||||||
|
},
|
||||||
|
"vectorString": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^CVSS:3[.]0/((AV:[NALP]|AC:[LH]|PR:[UNLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XUNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])/)*(AV:[NALP]|AC:[LH]|PR:[UNLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XUNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])$"
|
||||||
|
},
|
||||||
|
"attackVector": { "$ref": "#/definitions/attackVectorType" },
|
||||||
|
"attackComplexity": { "$ref": "#/definitions/attackComplexityType" },
|
||||||
|
"privilegesRequired": { "$ref": "#/definitions/privilegesRequiredType" },
|
||||||
|
"userInteraction": { "$ref": "#/definitions/userInteractionType" },
|
||||||
|
"scope": { "$ref": "#/definitions/scopeType" },
|
||||||
|
"confidentialityImpact": { "$ref": "#/definitions/ciaType" },
|
||||||
|
"integrityImpact": { "$ref": "#/definitions/ciaType" },
|
||||||
|
"availabilityImpact": { "$ref": "#/definitions/ciaType" },
|
||||||
|
"baseScore": { "$ref": "#/definitions/scoreType" },
|
||||||
|
"baseSeverity": { "$ref": "#/definitions/severityType" },
|
||||||
|
"exploitCodeMaturity": { "$ref": "#/definitions/exploitCodeMaturityType" },
|
||||||
|
"remediationLevel": { "$ref": "#/definitions/remediationLevelType" },
|
||||||
|
"reportConfidence": { "$ref": "#/definitions/confidenceType" },
|
||||||
|
"temporalScore": { "$ref": "#/definitions/scoreType" },
|
||||||
|
"temporalSeverity": { "$ref": "#/definitions/severityType" },
|
||||||
|
"confidentialityRequirement": { "$ref": "#/definitions/ciaRequirementType" },
|
||||||
|
"integrityRequirement": { "$ref": "#/definitions/ciaRequirementType" },
|
||||||
|
"availabilityRequirement": { "$ref": "#/definitions/ciaRequirementType" },
|
||||||
|
"modifiedAttackVector": { "$ref": "#/definitions/modifiedAttackVectorType" },
|
||||||
|
"modifiedAttackComplexity": { "$ref": "#/definitions/modifiedAttackComplexityType" },
|
||||||
|
"modifiedPrivilegesRequired": { "$ref": "#/definitions/modifiedPrivilegesRequiredType" },
|
||||||
|
"modifiedUserInteraction": { "$ref": "#/definitions/modifiedUserInteractionType" },
|
||||||
|
"modifiedScope": { "$ref": "#/definitions/modifiedScopeType" },
|
||||||
|
"modifiedConfidentialityImpact": { "$ref": "#/definitions/modifiedCiaType" },
|
||||||
|
"modifiedIntegrityImpact": { "$ref": "#/definitions/modifiedCiaType" },
|
||||||
|
"modifiedAvailabilityImpact": { "$ref": "#/definitions/modifiedCiaType" },
|
||||||
|
"environmentalScore": { "$ref": "#/definitions/scoreType" },
|
||||||
|
"environmentalSeverity": { "$ref": "#/definitions/severityType" }
|
||||||
|
},
|
||||||
|
"required": [ "version", "vectorString", "baseScore", "baseSeverity" ]
|
||||||
|
}
|
||||||
143
csaf/schema/cvss-v3.1.json
Normal file
143
csaf/schema/cvss-v3.1.json
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
{
|
||||||
|
"license": [
|
||||||
|
"Copyright (c) 2021, FIRST.ORG, INC.",
|
||||||
|
"All rights reserved.",
|
||||||
|
"",
|
||||||
|
"Redistribution and use in source and binary forms, with or without modification, are permitted provided that the ",
|
||||||
|
"following conditions are met:",
|
||||||
|
"1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following ",
|
||||||
|
" disclaimer.",
|
||||||
|
"2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the ",
|
||||||
|
" following disclaimer in the documentation and/or other materials provided with the distribution.",
|
||||||
|
"3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote ",
|
||||||
|
" products derived from this software without specific prior written permission.",
|
||||||
|
"",
|
||||||
|
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, ",
|
||||||
|
"INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ",
|
||||||
|
"DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ",
|
||||||
|
"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ",
|
||||||
|
"SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ",
|
||||||
|
"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ",
|
||||||
|
"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
],
|
||||||
|
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"title": "JSON Schema for Common Vulnerability Scoring System version 3.1",
|
||||||
|
"$id": "https://www.first.org/cvss/cvss-v3.1.json?20211103",
|
||||||
|
"type": "object",
|
||||||
|
"definitions": {
|
||||||
|
"attackVectorType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NETWORK", "ADJACENT_NETWORK", "LOCAL", "PHYSICAL" ]
|
||||||
|
},
|
||||||
|
"modifiedAttackVectorType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NETWORK", "ADJACENT_NETWORK", "LOCAL", "PHYSICAL", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"attackComplexityType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "HIGH", "LOW" ]
|
||||||
|
},
|
||||||
|
"modifiedAttackComplexityType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "HIGH", "LOW", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"privilegesRequiredType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "HIGH", "LOW", "NONE" ]
|
||||||
|
},
|
||||||
|
"modifiedPrivilegesRequiredType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "HIGH", "LOW", "NONE", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"userInteractionType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "REQUIRED" ]
|
||||||
|
},
|
||||||
|
"modifiedUserInteractionType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "REQUIRED", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"scopeType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "UNCHANGED", "CHANGED" ]
|
||||||
|
},
|
||||||
|
"modifiedScopeType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "UNCHANGED", "CHANGED", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"ciaType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "LOW", "HIGH" ]
|
||||||
|
},
|
||||||
|
"modifiedCiaType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "LOW", "HIGH", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"exploitCodeMaturityType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "UNPROVEN", "PROOF_OF_CONCEPT", "FUNCTIONAL", "HIGH", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"remediationLevelType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "OFFICIAL_FIX", "TEMPORARY_FIX", "WORKAROUND", "UNAVAILABLE", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"confidenceType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "UNKNOWN", "REASONABLE", "CONFIRMED", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"ciaRequirementType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "LOW", "MEDIUM", "HIGH", "NOT_DEFINED" ]
|
||||||
|
},
|
||||||
|
"scoreType": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 10
|
||||||
|
},
|
||||||
|
"severityType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "NONE", "LOW", "MEDIUM", "HIGH", "CRITICAL" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"version": {
|
||||||
|
"description": "CVSS Version",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "3.1" ]
|
||||||
|
},
|
||||||
|
"vectorString": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^CVSS:3[.]1/((AV:[NALP]|AC:[LH]|PR:[NLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])/)*(AV:[NALP]|AC:[LH]|PR:[NLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])$"
|
||||||
|
},
|
||||||
|
"attackVector": { "$ref": "#/definitions/attackVectorType" },
|
||||||
|
"attackComplexity": { "$ref": "#/definitions/attackComplexityType" },
|
||||||
|
"privilegesRequired": { "$ref": "#/definitions/privilegesRequiredType" },
|
||||||
|
"userInteraction": { "$ref": "#/definitions/userInteractionType" },
|
||||||
|
"scope": { "$ref": "#/definitions/scopeType" },
|
||||||
|
"confidentialityImpact": { "$ref": "#/definitions/ciaType" },
|
||||||
|
"integrityImpact": { "$ref": "#/definitions/ciaType" },
|
||||||
|
"availabilityImpact": { "$ref": "#/definitions/ciaType" },
|
||||||
|
"baseScore": { "$ref": "#/definitions/scoreType" },
|
||||||
|
"baseSeverity": { "$ref": "#/definitions/severityType" },
|
||||||
|
"exploitCodeMaturity": { "$ref": "#/definitions/exploitCodeMaturityType" },
|
||||||
|
"remediationLevel": { "$ref": "#/definitions/remediationLevelType" },
|
||||||
|
"reportConfidence": { "$ref": "#/definitions/confidenceType" },
|
||||||
|
"temporalScore": { "$ref": "#/definitions/scoreType" },
|
||||||
|
"temporalSeverity": { "$ref": "#/definitions/severityType" },
|
||||||
|
"confidentialityRequirement": { "$ref": "#/definitions/ciaRequirementType" },
|
||||||
|
"integrityRequirement": { "$ref": "#/definitions/ciaRequirementType" },
|
||||||
|
"availabilityRequirement": { "$ref": "#/definitions/ciaRequirementType" },
|
||||||
|
"modifiedAttackVector": { "$ref": "#/definitions/modifiedAttackVectorType" },
|
||||||
|
"modifiedAttackComplexity": { "$ref": "#/definitions/modifiedAttackComplexityType" },
|
||||||
|
"modifiedPrivilegesRequired": { "$ref": "#/definitions/modifiedPrivilegesRequiredType" },
|
||||||
|
"modifiedUserInteraction": { "$ref": "#/definitions/modifiedUserInteractionType" },
|
||||||
|
"modifiedScope": { "$ref": "#/definitions/modifiedScopeType" },
|
||||||
|
"modifiedConfidentialityImpact": { "$ref": "#/definitions/modifiedCiaType" },
|
||||||
|
"modifiedIntegrityImpact": { "$ref": "#/definitions/modifiedCiaType" },
|
||||||
|
"modifiedAvailabilityImpact": { "$ref": "#/definitions/modifiedCiaType" },
|
||||||
|
"environmentalScore": { "$ref": "#/definitions/scoreType" },
|
||||||
|
"environmentalSeverity": { "$ref": "#/definitions/severityType" }
|
||||||
|
},
|
||||||
|
"required": [ "version", "vectorString", "baseScore", "baseSeverity" ]
|
||||||
|
}
|
||||||
102
csaf/validation.go
Normal file
102
csaf/validation.go
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
package csaf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
_ "embed" // Used for embedding.
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/santhosh-tekuri/jsonschema/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed schema/csaf_json_schema.json
|
||||||
|
var csafSchema []byte
|
||||||
|
|
||||||
|
//go:embed schema/cvss-v2.0.json
|
||||||
|
var cvss20 []byte
|
||||||
|
|
||||||
|
//go:embed schema/cvss-v3.0.json
|
||||||
|
var cvss30 []byte
|
||||||
|
|
||||||
|
//go:embed schema/cvss-v3.1.json
|
||||||
|
var cvss31 []byte
|
||||||
|
|
||||||
|
var (
|
||||||
|
compileSchemaOnce sync.Once
|
||||||
|
compileError error
|
||||||
|
compiledSchema *jsonschema.Schema
|
||||||
|
)
|
||||||
|
|
||||||
|
func compileSchema() {
|
||||||
|
c := jsonschema.NewCompiler()
|
||||||
|
|
||||||
|
for _, s := range []struct {
|
||||||
|
url string
|
||||||
|
data []byte
|
||||||
|
}{
|
||||||
|
{"https://docs.oasis-open.org/csaf/csaf/v2.0/csaf_json_schema.json", csafSchema},
|
||||||
|
{"https://www.first.org/cvss/cvss-v2.0.json", cvss20},
|
||||||
|
{"https://www.first.org/cvss/cvss-v3.0.json", cvss30},
|
||||||
|
{"https://www.first.org/cvss/cvss-v3.1.json", cvss31},
|
||||||
|
} {
|
||||||
|
if compileError = c.AddResource(s.url, bytes.NewReader(s.data)); compileError != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compiledSchema, compileError = c.Compile(
|
||||||
|
"https://docs.oasis-open.org/csaf/csaf/v2.0/csaf_json_schema.json")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateCSAF validates the document data against the JSON schema
|
||||||
|
// of CSAF.
|
||||||
|
func ValidateCSAF(doc interface{}) ([]string, error) {
|
||||||
|
|
||||||
|
compileSchemaOnce.Do(compileSchema)
|
||||||
|
if compileError != nil {
|
||||||
|
return nil, compileError
|
||||||
|
}
|
||||||
|
|
||||||
|
err := compiledSchema.Validate(doc)
|
||||||
|
if err == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
valErr, ok := err.(*jsonschema.ValidationError)
|
||||||
|
if !ok {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
basic := valErr.BasicOutput()
|
||||||
|
if basic.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
errs := basic.Errors
|
||||||
|
|
||||||
|
sort.Slice(errs, func(i, j int) bool {
|
||||||
|
pi := errs[i].InstanceLocation
|
||||||
|
pj := errs[j].InstanceLocation
|
||||||
|
if strings.HasPrefix(pj, pi) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(pi, pj) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if pi != pj {
|
||||||
|
return pi < pj
|
||||||
|
}
|
||||||
|
return errs[i].Error < errs[j].Error
|
||||||
|
})
|
||||||
|
|
||||||
|
res := make([]string, 0, len(errs))
|
||||||
|
|
||||||
|
for i := range errs {
|
||||||
|
if e := &errs[i]; e.InstanceLocation != "" && e.Error != "" {
|
||||||
|
res = append(res, e.InstanceLocation+": "+e.Error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
1
go.mod
1
go.mod
|
|
@ -7,6 +7,7 @@ require (
|
||||||
github.com/PaesslerAG/gval v1.1.2
|
github.com/PaesslerAG/gval v1.1.2
|
||||||
github.com/PaesslerAG/jsonpath v0.1.1
|
github.com/PaesslerAG/jsonpath v0.1.1
|
||||||
github.com/ProtonMail/gopenpgp/v2 v2.3.0
|
github.com/ProtonMail/gopenpgp/v2 v2.3.0
|
||||||
|
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -22,6 +22,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 h1:TToq11gyfNlrMFZiYujSekIsPd9AmsA2Bj/iv+s4JHE=
|
||||||
|
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
|
||||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue