├── .gitattributes ├── .travis.yml ├── go.mod ├── go.sum ├── .gitignore ├── .editorconfig ├── .github └── workflows │ ├── vulns.yml │ ├── lint.yml │ └── codeql-analysis.yml ├── v2 └── metric │ ├── misc.go │ ├── metric-av.go │ ├── metric-au.go │ ├── metric-i.go │ ├── severity.go │ ├── metric-ac.go │ ├── metric-a.go │ ├── metric-c.go │ ├── example_test.go │ ├── metrict-rc.go │ ├── metrict-e.go │ ├── metrict-rl.go │ ├── metrice-ir.go │ ├── metrice-td.go │ ├── metrice-ar.go │ ├── metrice-cr.go │ ├── metrice-cdp.go │ └── temporal.go ├── Taskfile.yml ├── sample ├── environmental │ └── sample.go ├── v2 │ ├── base │ │ └── sample.go │ ├── temporal │ │ └── sample.go │ └── environmental │ │ └── sample.go ├── base │ └── sample.go ├── temporal │ └── sample.go └── sample.go ├── v3 ├── report │ ├── names │ │ ├── base.go │ │ ├── temporal.go │ │ ├── environmental.go │ │ ├── names.go │ │ ├── scope.go │ │ ├── attack-complexity.go │ │ ├── user-interaction.go │ │ ├── integrity-impact.go │ │ ├── modified-scope.go │ │ ├── availability-impact.go │ │ ├── privileges-required.go │ │ ├── confidentiality-impact.go │ │ ├── modified-attack-complexity.go │ │ ├── modified-user-interaction.go │ │ ├── attack-vector.go │ │ ├── integrity-requirement.go │ │ ├── report-confidence.go │ │ ├── availability-requirement.go │ │ ├── modified-integrity-impact.go │ │ ├── confidentiality-requirement.go │ │ ├── modified-availability-impact.go │ │ ├── modified-privileges-required.go │ │ ├── modified-confidentiality-impact.go │ │ ├── exploitability.go │ │ ├── severity.go │ │ ├── remediation-level.go │ │ └── modified-attack-vector.go │ ├── options.go │ ├── templete.go │ ├── report-temporal.go │ ├── report-base.go │ └── report-environmental.go ├── metric │ ├── severity.go │ ├── misc.go │ ├── modified-scope.go │ ├── scope_test.go │ ├── scope.go │ ├── report-confidence.go │ ├── exploitability.go │ ├── integrity-requirement.go │ ├── user-interaction_test.go │ ├── attack-complexity_test.go │ ├── remediation-level.go │ ├── version.go │ ├── version_test.go │ ├── example_test.go │ ├── integrity-impact_test.go │ ├── report-confidence_test.go │ ├── availability-requirement.go │ ├── availability-impact_test.go │ ├── attack-vector_test.go │ ├── confidentiality-impact_test.go │ ├── exploitability_test.go │ ├── user-interaction.go │ ├── modified-user-interaction.go │ ├── remediation-level_test.go │ ├── confidentiality-requirement.go │ ├── modified-attack-complexity.go │ ├── integrity-impact.go │ ├── attack-vector.go │ ├── attack-complexity.go │ ├── modified-attack-vector.go │ ├── modified-integrity.go │ ├── availability-impact.go │ ├── modified-availability.go │ ├── confidentiality-impact.go │ ├── modified-confidentiality.go │ ├── privileges-required_test.go │ ├── privileges-required.go │ ├── modified-privileges-required.go │ ├── temporal_test.go │ └── temporal.go └── version │ ├── version_test.go │ └── version.go ├── cvsserr └── errors.go └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | *.go text eol=lf 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - "1.13.x" 5 | 6 | script: 7 | - env GO111MODULE=on go test -v ./... 8 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/goark/go-cvss 2 | 3 | go 1.22 4 | 5 | toolchain go1.22.1 6 | 7 | require ( 8 | github.com/goark/errs v1.3.2 9 | golang.org/x/text v0.14.0 10 | ) 11 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/goark/errs v1.3.2 h1:ifccNe1aK7Xezt4XVYwHUqalmnfhuphnEvh3FshCReQ= 2 | github.com/goark/errs v1.3.2/go.mod h1:ZsQucxaDFVfSB8I99j4bxkDRfNOrlKINwg72QMuRWKw= 3 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 4 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | *.bak 8 | *.old 9 | 10 | # Test binary, build with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # Other files and folders 17 | vendor/ 18 | .task/ 19 | work/ 20 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | charset = utf-8 6 | indent_style = tab 7 | indent_size = 4 8 | trim_trailing_whitespace = false 9 | insert_final_newline = true 10 | 11 | [*.go] 12 | trim_trailing_whitespace = true 13 | 14 | [*.md] 15 | indent_style = space 16 | indent_size = 4 17 | 18 | [*.yml] 19 | indent_style = space 20 | indent_size = 2 21 | trim_trailing_whitespace = true 22 | 23 | [*.toml] 24 | indent_style = space 25 | indent_size = 2 26 | trim_trailing_whitespace = true 27 | -------------------------------------------------------------------------------- /.github/workflows/vulns.yml: -------------------------------------------------------------------------------- 1 | name: vulns 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | jobs: 8 | vulns: 9 | name: Vulnerability scanner 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | - uses: actions/setup-go@v3 14 | with: 15 | go-version-file: 'go.mod' 16 | - name: install depm 17 | run: go install github.com/goark/depm@latest 18 | - name: WriteGoList 19 | run: depm list --json > go.list 20 | - name: Nancy 21 | uses: sonatype-nexus-community/nancy-github-action@main 22 | -------------------------------------------------------------------------------- /v2/metric/misc.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "math" 4 | 5 | func roundTo1Decimal(input float64) float64 { 6 | return math.Round(input*10) / 10 7 | } 8 | 9 | func roundTo2Decimal(input float64) float64 { 10 | return math.Round(input*100) / 100 11 | } 12 | 13 | /* Copyright 2023 Spiegel 14 | * 15 | * Licensed under the Apache License, Version 2.0 (the "License"); 16 | * you may not use this file except in compliance with the License. 17 | * You may obtain a copy of the License at 18 | * 19 | * http://www.apache.org/licenses/LICENSE-2.0 20 | * 21 | * Unless required by applicable law or agreed to in writing, software 22 | * distributed under the License is distributed on an "AS IS" BASIS, 23 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | * See the License for the specific language governing permissions and 25 | * limitations under the License. 26 | */ 27 | -------------------------------------------------------------------------------- /Taskfile.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | tasks: 4 | default: 5 | cmds: 6 | - task: prepare 7 | - task: test 8 | - task: nancy 9 | 10 | test: 11 | desc: Test and lint. 12 | cmds: 13 | - go mod verify 14 | - go test -shuffle on ./... 15 | - docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:latest golangci-lint run --enable gosec --timeout 3m0s ./... 16 | sources: 17 | - ./go.mod 18 | - '**/*.go' 19 | 20 | nancy: 21 | desc: Check vulnerability of external packages with Nancy. 22 | cmds: 23 | - depm list -j | nancy sleuth -n 24 | sources: 25 | - ./go.mod 26 | - '**/*.go' 27 | 28 | prepare: 29 | - go mod tidy -v -go=1.22 30 | 31 | clean: 32 | desc: Initialize module and build cache, and remake go.sum file. 33 | cmds: 34 | - rm -f ./go.sum 35 | - go clean -cache 36 | - go clean -modcache 37 | -------------------------------------------------------------------------------- /sample/environmental/sample.go: -------------------------------------------------------------------------------- 1 | //go:build run 2 | // +build run 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | 10 | "github.com/goark/go-cvss/v3/metric" 11 | ) 12 | 13 | func main() { 14 | em, err := metric.NewEnvironmental().Decode("CVSS:3.1/AV:P/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H/E:F/RL:U/RC:C/CR:M/IR:H/AR:M/MAV:L/MAC:H/MPR:L/MUI:R/MS:U/MC:L/MI:H/MA:L") //Random CVSS Vector 15 | if err != nil { 16 | fmt.Fprintln(os.Stderr, err) 17 | return 18 | } 19 | fmt.Printf("Base Severity: %v (%v)\n", em.BaseMetrics().Severity(), em.BaseMetrics().Score()) 20 | fmt.Printf("Temporal Severity: %v (%v)\n", em.TemporalMetrics().Severity(), em.TemporalMetrics().Score()) 21 | fmt.Printf("Environmental Severity: %v (%v)\n", em.Severity(), em.Score()) 22 | // Output: 23 | // Base Severity: Critical (6.1) 24 | // Temporal Severity: Critical (6) 25 | // Environmental Severity: Critical (6.5) 26 | } 27 | 28 | /* Copyright 2022 thejohnbrown */ 29 | -------------------------------------------------------------------------------- /sample/v2/base/sample.go: -------------------------------------------------------------------------------- 1 | //go:build run 2 | // +build run 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | 10 | "github.com/goark/go-cvss/v2/metric" 11 | ) 12 | 13 | func main() { 14 | bm, err := metric.NewBase().Decode("AV:N/AC:L/Au:N/C:N/I:N/A:C") //CVE-2002-0392 15 | if err != nil { 16 | fmt.Fprintln(os.Stderr, err) 17 | return 18 | } 19 | fmt.Printf("Severity: %v (%v)\n", bm.Severity(), bm.Score()) 20 | // Output: 21 | // Severity: Severity: High (7.8) 22 | } 23 | 24 | /* Copyright 2023 Spiegel 25 | * 26 | * Licensed under the Apache License, Version 2.0 (the "License"); 27 | * you may not use this file except in compliance with the License. 28 | * You may obtain a copy of the License at 29 | * 30 | * http://www.apache.org/licenses/LICENSE-2.0 31 | * 32 | * Unless required by applicable law or agreed to in writing, software 33 | * distributed under the License is distributed on an "AS IS" BASIS, 34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 35 | * See the License for the specific language governing permissions and 36 | * limitations under the License. 37 | */ 38 | -------------------------------------------------------------------------------- /sample/base/sample.go: -------------------------------------------------------------------------------- 1 | //go:build run 2 | // +build run 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | 10 | "github.com/goark/go-cvss/v3/metric" 11 | ) 12 | 13 | func main() { 14 | bm, err := metric.NewBase().Decode("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H") //CVE-2020-1472: ZeroLogon 15 | if err != nil { 16 | fmt.Fprintln(os.Stderr, err) 17 | return 18 | } 19 | fmt.Printf("Severity: %v (%v)\n", bm.Severity(), bm.Score()) 20 | // Output: 21 | // Severity: Critical (10) 22 | } 23 | 24 | /* Copyright 2018-2020 Spiegel 25 | * 26 | * Licensed under the Apache License, Version 2.0 (the "License"); 27 | * you may not use this file except in compliance with the License. 28 | * You may obtain a copy of the License at 29 | * 30 | * http://www.apache.org/licenses/LICENSE-2.0 31 | * 32 | * Unless required by applicable law or agreed to in writing, software 33 | * distributed under the License is distributed on an "AS IS" BASIS, 34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 35 | * See the License for the specific language governing permissions and 36 | * limitations under the License. 37 | */ 38 | -------------------------------------------------------------------------------- /v3/report/names/base.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import "golang.org/x/text/language" 4 | 5 | var baseTitleMap = langNameMap{ 6 | language.English: "Base Metrics", 7 | language.Japanese: "基本評価基準", 8 | } 9 | 10 | //BaseMetrics returns string instance name for display 11 | func BaseMetrics(lang language.Tag) string { 12 | return baseTitleMap.getNameInLang(lang) 13 | } 14 | 15 | //BaseMetricsValueOf returns string instance name for display 16 | func BaseMetricsValueOf(lang language.Tag) string { 17 | return metricVakueMap.getNameInLang(lang) 18 | } 19 | 20 | /* Copyright 2018-2020 Spiegel 21 | * 22 | * Licensed under the Apache License, Version 2.0 (the "License"); 23 | * you may not use this file except in compliance with the License. 24 | * You may obtain a copy of the License at 25 | * 26 | * http://www.apache.org/licenses/LICENSE-2.0 27 | * 28 | * Unless required by applicable law or agreed to in writing, software 29 | * distributed under the License is distributed on an "AS IS" BASIS, 30 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | * See the License for the specific language governing permissions and 32 | * limitations under the License. 33 | */ 34 | -------------------------------------------------------------------------------- /v3/report/names/temporal.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import "golang.org/x/text/language" 4 | 5 | var temporalTitleMap = langNameMap{ 6 | language.English: "Temporal Metrics", 7 | language.Japanese: "現状評価基準", 8 | } 9 | 10 | //TemporalMetrics returns string instance name for display 11 | func TemporalMetrics(lang language.Tag) string { 12 | return temporalTitleMap.getNameInLang(lang) 13 | } 14 | 15 | //TemporalMetricsValueOf returns string instance name for display 16 | func TemporalMetricsValueOf(lang language.Tag) string { 17 | return metricVakueMap.getNameInLang(lang) 18 | } 19 | 20 | /* Copyright 2018-2020 Spiegel 21 | * 22 | * Licensed under the Apache License, Version 2.0 (the "License"); 23 | * you may not use this file except in compliance with the License. 24 | * You may obtain a copy of the License at 25 | * 26 | * http://www.apache.org/licenses/LICENSE-2.0 27 | * 28 | * Unless required by applicable law or agreed to in writing, software 29 | * distributed under the License is distributed on an "AS IS" BASIS, 30 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | * See the License for the specific language governing permissions and 32 | * limitations under the License. 33 | */ 34 | -------------------------------------------------------------------------------- /v3/report/names/environmental.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import "golang.org/x/text/language" 4 | 5 | var environmentalMap = langNameMap{ 6 | language.English: "Environmental Metrics", 7 | language.Japanese: "環境評価基準", 8 | } 9 | 10 | //EnvironmentalMetrics returns string instance name for display 11 | func EnvironmentalMetrics(lang language.Tag) string { 12 | return environmentalMap.getNameInLang(lang) 13 | } 14 | 15 | //EnvironmentalMetricsValueOf returns string instance name for display 16 | func EnvironmentalMetricsValueOf(lang language.Tag) string { 17 | return metricVakueMap.getNameInLang(lang) 18 | } 19 | 20 | /* Copyright 2022 Spiegel 21 | * 22 | * Licensed under the Apache License, Version 2.0 (the "License"); 23 | * you may not use this file except in compliance with the License. 24 | * You may obtain a copy of the License at 25 | * 26 | * http://www.apache.org/licenses/LICENSE-2.0 27 | * 28 | * Unless required by applicable law or agreed to in writing, software 29 | * distributed under the License is distributed on an "AS IS" BASIS, 30 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | * See the License for the specific language governing permissions and 32 | * limitations under the License. 33 | */ 34 | -------------------------------------------------------------------------------- /v3/report/names/names.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import "golang.org/x/text/language" 4 | 5 | var ( 6 | unknownValueNameMap = langNameMap{ 7 | language.English: "Unknown", 8 | language.Japanese: "未定義", 9 | } 10 | metricVakueMap = langNameMap{ 11 | language.English: "Metric Value", 12 | language.Japanese: "評価値", 13 | } 14 | ) 15 | 16 | type langNameMap map[language.Tag]string 17 | 18 | func (ln langNameMap) getNameInLang(lang language.Tag) string { 19 | if s, ok := ln[lang]; ok { 20 | return s 21 | } 22 | if s, ok := ln[language.English]; ok { 23 | return s 24 | } 25 | return "" 26 | } 27 | 28 | /* Copyright 2020 Spiegel 29 | * 30 | * Licensed under the Apache License, Version 2.0 (the "License"); 31 | * you may not use this file except in compliance with the License. 32 | * You may obtain a copy of the License at 33 | * 34 | * http://www.apache.org/licenses/LICENSE-2.0 35 | * 36 | * Unless required by applicable law or agreed to in writing, software 37 | * distributed under the License is distributed on an "AS IS" BASIS, 38 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 39 | * See the License for the specific language governing permissions and 40 | * limitations under the License. 41 | */ 42 | -------------------------------------------------------------------------------- /sample/v2/temporal/sample.go: -------------------------------------------------------------------------------- 1 | //go:build run 2 | // +build run 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | 10 | "github.com/goark/go-cvss/v2/metric" 11 | ) 12 | 13 | func main() { 14 | tm, err := metric.NewTemporal().Decode("AV:N/AC:L/Au:N/C:N/I:N/A:C/E:F/RL:OF/RC:C") //CVE-2002-0392 15 | if err != nil { 16 | fmt.Fprintln(os.Stderr, err) 17 | return 18 | } 19 | fmt.Printf("Severity (Base): %v (%v)\n", tm.Base.Severity(), tm.Base.Score()) 20 | fmt.Printf("Severity (Temporal): %v (%v)\n", tm.Severity(), tm.Score()) 21 | // Output: 22 | // Severity (Base): High (7.8) 23 | // Severity (Temporal): Medium (6.4) 24 | } 25 | 26 | /* Copyright 2023 Spiegel 27 | * 28 | * Licensed under the Apache License, Version 2.0 (the "License"); 29 | * you may not use this file except in compliance with the License. 30 | * You may obtain a copy of the License at 31 | * 32 | * http://www.apache.org/licenses/LICENSE-2.0 33 | * 34 | * Unless required by applicable law or agreed to in writing, software 35 | * distributed under the License is distributed on an "AS IS" BASIS, 36 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 37 | * See the License for the specific language governing permissions and 38 | * limitations under the License. 39 | */ 40 | -------------------------------------------------------------------------------- /v3/metric/severity.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | //Severity is severity for Base Metrics 4 | type Severity int 5 | 6 | //Constant of severity 7 | const ( 8 | SeverityUnknown Severity = iota 9 | SeverityNone 10 | SeverityLow 11 | SeverityMedium 12 | SeverityHigh 13 | SeverityCritical 14 | ) 15 | 16 | var severityMap = map[Severity]string{ 17 | SeverityNone: "None", 18 | SeverityLow: "Low", 19 | SeverityMedium: "Medium", 20 | SeverityHigh: "High", 21 | SeverityCritical: "Critical", 22 | } 23 | 24 | func (sv Severity) String() string { 25 | if s, ok := severityMap[sv]; ok { 26 | return s 27 | } 28 | return "Unknown" 29 | } 30 | 31 | /* Copyright 2018 Spiegel 32 | * 33 | * Licensed under the Apache License, Version 2.0 (the "License"); 34 | * you may not use this file except in compliance with the License. 35 | * You may obtain a copy of the License at 36 | * 37 | * http://www.apache.org/licenses/LICENSE-2.0 38 | * 39 | * Unless required by applicable law or agreed to in writing, software 40 | * distributed under the License is distributed on an "AS IS" BASIS, 41 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 42 | * See the License for the specific language governing permissions and 43 | * limitations under the License. 44 | */ 45 | -------------------------------------------------------------------------------- /v3/version/version_test.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | import "testing" 4 | 5 | func TestVersion(t *testing.T) { 6 | testCases := []struct { 7 | v string 8 | n Num 9 | s string 10 | }{ 11 | {v: "3.0", n: V3_0, s: "3.0"}, 12 | {v: "3.1", n: V3_1, s: "3.1"}, 13 | {v: "1.0", n: Unknown, s: "unknown"}, 14 | {v: "2.0", n: Unknown, s: "unknown"}, 15 | } 16 | for _, tc := range testCases { 17 | n := Get(tc.v) 18 | if n != tc.n { 19 | t.Errorf("Version %v = \"%v\", want \"%v\".", tc.v, n, tc.n) 20 | } 21 | s := n.String() 22 | if s != tc.s { 23 | t.Errorf("Version %v = \"%v\", want \"%v\".", tc.v, s, tc.s) 24 | } 25 | } 26 | } 27 | 28 | /* Copyright 2018-2020 Spiegel 29 | * 30 | * Licensed under the Apache License, Version 2.0 (the "License"); 31 | * you may not use this file except in compliance with the License. 32 | * You may obtain a copy of the License at 33 | * 34 | * http://www.apache.org/licenses/LICENSE-2.0 35 | * 36 | * Unless required by applicable law or agreed to in writing, software 37 | * distributed under the License is distributed on an "AS IS" BASIS, 38 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 39 | * See the License for the specific language governing permissions and 40 | * limitations under the License. 41 | */ 42 | -------------------------------------------------------------------------------- /v3/version/version.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | //Num is error number for CVSS 4 | type Num int 5 | 6 | const ( 7 | Unknown Num = iota //unknown version 8 | V3_0 //v3.0 9 | V3_1 //v3.1 10 | ) 11 | 12 | var verStrings = map[Num]string{ 13 | V3_0: "3.0", 14 | V3_1: "3.1", 15 | } 16 | 17 | //String is Stringer method 18 | func (n Num) String() string { 19 | if s, ok := verStrings[n]; ok { 20 | return s 21 | } 22 | return "unknown" 23 | } 24 | 25 | //Get returns Version number from string 26 | func Get(s string) Num { 27 | for k, v := range verStrings { 28 | if s == v { 29 | return k 30 | } 31 | } 32 | return Unknown 33 | } 34 | 35 | /* Copyright 2018-2020 Spiegel 36 | * 37 | * Licensed under the Apache License, Version 2.0 (the "License"); 38 | * you may not use this file except in compliance with the License. 39 | * You may obtain a copy of the License at 40 | * 41 | * http://www.apache.org/licenses/LICENSE-2.0 42 | * 43 | * Unless required by applicable law or agreed to in writing, software 44 | * distributed under the License is distributed on an "AS IS" BASIS, 45 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 46 | * See the License for the specific language governing permissions and 47 | * limitations under the License. 48 | */ 49 | -------------------------------------------------------------------------------- /sample/temporal/sample.go: -------------------------------------------------------------------------------- 1 | //go:build run 2 | // +build run 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | 10 | "github.com/goark/go-cvss/v3/metric" 11 | ) 12 | 13 | func main() { 14 | tm, err := metric.NewTemporal().Decode("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H/E:F/RL:W/RC:R") //CVE-2020-1472: ZeroLogon 15 | if err != nil { 16 | fmt.Fprintln(os.Stderr, err) 17 | return 18 | } 19 | fmt.Printf("Base Severity: %v (%v)\n", tm.BaseMetrics().Severity(), tm.BaseMetrics().Score()) 20 | fmt.Printf("Temporal Severity: %v (%v)\n", tm.Severity(), tm.Score()) 21 | // Output: 22 | // Base Severity: Critical (10) 23 | // Temporal Severity: Critical (9.1) 24 | } 25 | 26 | /* Copyright 2018-2020 Spiegel 27 | * 28 | * Licensed under the Apache License, Version 2.0 (the "License"); 29 | * you may not use this file except in compliance with the License. 30 | * You may obtain a copy of the License at 31 | * 32 | * http://www.apache.org/licenses/LICENSE-2.0 33 | * 34 | * Unless required by applicable law or agreed to in writing, software 35 | * distributed under the License is distributed on an "AS IS" BASIS, 36 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 37 | * See the License for the specific language governing permissions and 38 | * limitations under the License. 39 | */ 40 | -------------------------------------------------------------------------------- /v3/metric/misc.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "math" 4 | 5 | func roundUp(input float64) float64 { 6 | intInput := math.Round(input * 100000) 7 | 8 | if int(intInput)%10000 == 0 { 9 | return intInput / 100000 10 | } 11 | 12 | return (math.Floor(intInput/10000) + 1) / 10.0 13 | } 14 | 15 | // GetSeverity returns severity by score of Base metrics 16 | func severity(score float64) Severity { 17 | switch true { 18 | case score <= 0: 19 | return SeverityNone 20 | case score > 0 && score < 4.0: 21 | return SeverityLow 22 | case score >= 4.0 && score < 7.0: 23 | return SeverityMedium 24 | case score >= 7.0 && score < 9.0: 25 | return SeverityHigh 26 | case score >= 9.0: 27 | return SeverityCritical 28 | default: 29 | return SeverityUnknown 30 | } 31 | } 32 | 33 | /* Copyright 2018-2020 Spiegel 34 | * 35 | * Licensed under the Apache License, Version 2.0 (the "License"); 36 | * you may not use this file except in compliance with the License. 37 | * You may obtain a copy of the License at 38 | * 39 | * http://www.apache.org/licenses/LICENSE-2.0 40 | * 41 | * Unless required by applicable law or agreed to in writing, software 42 | * distributed under the License is distributed on an "AS IS" BASIS, 43 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 44 | * See the License for the specific language governing permissions and 45 | * limitations under the License. 46 | */ 47 | -------------------------------------------------------------------------------- /v3/metric/modified-scope.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ModifiedScope is metric type for Base Metrics 4 | type ModifiedScope int 5 | 6 | // Constant of ModifiedScope result 7 | const ( 8 | ModifiedScopeInvalid ModifiedScope = iota 9 | ModifiedScopeNotDefined 10 | ModifiedScopeUnchanged 11 | ModifiedScopeChanged 12 | ) 13 | 14 | var ModifiedScopeValueMap = map[ModifiedScope]string{ 15 | ModifiedScopeNotDefined: "X", 16 | ModifiedScopeUnchanged: "U", 17 | ModifiedScopeChanged: "C", 18 | } 19 | 20 | // GetModifiedScope returns result of ModifiedScope metric 21 | func GetModifiedScope(s string) ModifiedScope { 22 | for k, v := range ModifiedScopeValueMap { 23 | if s == v { 24 | return k 25 | } 26 | } 27 | return ModifiedScopeInvalid 28 | } 29 | 30 | // IsChanged returns true if ModifiedScope value is ModifiedScopeChanged. 31 | func (msc ModifiedScope) IsChanged(sc Scope) bool { 32 | if msc == ModifiedScopeNotDefined { 33 | return sc.IsChanged() 34 | } 35 | return msc == ModifiedScopeChanged 36 | } 37 | 38 | func (msc ModifiedScope) String() string { 39 | if s, ok := ModifiedScopeValueMap[msc]; ok { 40 | return s 41 | } 42 | return "" 43 | } 44 | 45 | // IsDefined returns false if undefined result value of metric 46 | func (msc ModifiedScope) IsValid() bool { 47 | _, ok := ModifiedScopeValueMap[msc] 48 | return ok 49 | } 50 | 51 | /* Copyright 2022 thejohnbrown */ 52 | /* Contributed by Spiegel, 2023 */ 53 | -------------------------------------------------------------------------------- /v3/report/options.go: -------------------------------------------------------------------------------- 1 | package report 2 | 3 | import "golang.org/x/text/language" 4 | 5 | type options struct { 6 | lang language.Tag 7 | } 8 | 9 | //ReportOptionsFunc type is self-referential function type for report.newOptions() function. (functional options pattern) 10 | type ReportOptionsFunc func(*options) 11 | 12 | func newOptions(os ...ReportOptionsFunc) *options { 13 | opts := &options{lang: language.English} 14 | for _, o := range os { 15 | o(opts) 16 | } 17 | return opts 18 | } 19 | 20 | //WithOptionsLanguage function returns ReportOptionsFunc function value. 21 | //This function is used in Server.CreateClient method that represents http.Client. 22 | func WithOptionsLanguage(lang language.Tag) ReportOptionsFunc { 23 | return func(opts *options) { 24 | opts.lang = lang 25 | } 26 | } 27 | 28 | /* Copyright 2020 Spiegel 29 | * 30 | * Licensed under the Apache License, Version 2.0 (the "License"); 31 | * you may not use this file except in compliance with the License. 32 | * You may obtain a copy of the License at 33 | * 34 | * http://www.apache.org/licenses/LICENSE-2.0 35 | * 36 | * Unless required by applicable law or agreed to in writing, software 37 | * distributed under the License is distributed on an "AS IS" BASIS, 38 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 39 | * See the License for the specific language governing permissions and 40 | * limitations under the License. 41 | */ 42 | -------------------------------------------------------------------------------- /v2/metric/metric-av.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // AccessVector is metric type for Base Metrics 4 | type AccessVector int 5 | 6 | // Constant of AccessVector result 7 | const ( 8 | AccessVectorUnknown AccessVector = iota 9 | AccessVectorLocal 10 | AccessVectorAdjacent 11 | AccessVectorNetwork 12 | ) 13 | 14 | var accessVectorMap = map[AccessVector]string{ 15 | AccessVectorLocal: "L", 16 | AccessVectorAdjacent: "A", 17 | AccessVectorNetwork: "N", 18 | } 19 | 20 | var accessVectorValueMap = map[AccessVector]float64{ 21 | AccessVectorLocal: 0.395, 22 | AccessVectorAdjacent: 0.646, 23 | AccessVectorNetwork: 1, 24 | } 25 | 26 | // GetAccessVector returns result of AccessVector metric 27 | func GetAccessVector(s string) AccessVector { 28 | for k, v := range accessVectorMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return AccessVectorUnknown 34 | } 35 | 36 | func (av AccessVector) String() string { 37 | if s, ok := accessVectorMap[av]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of AccessVector metric 44 | func (av AccessVector) Value() float64 { 45 | if v, ok := accessVectorValueMap[av]; ok { 46 | return v 47 | } 48 | return 0.0 49 | } 50 | 51 | // IsUnknown returns false if undefined result value of metric 52 | func (av AccessVector) IsUnknown() bool { 53 | return av != AccessVectorUnknown 54 | } 55 | 56 | /* Copyright 2022 luxifer */ 57 | /* Contributed by Spiegel, 2023 */ 58 | -------------------------------------------------------------------------------- /sample/v2/environmental/sample.go: -------------------------------------------------------------------------------- 1 | //go:build run 2 | // +build run 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | 10 | "github.com/goark/go-cvss/v2/metric" 11 | ) 12 | 13 | func main() { 14 | tm, err := metric.NewEnvironmental().Decode("AV:N/AC:L/Au:N/C:N/I:N/A:C/E:F/RL:OF/RC:C/CDP:H/TD:H/CR:M/IR:M/AR:H") //CVE-2002-0392 15 | if err != nil { 16 | fmt.Fprintln(os.Stderr, err) 17 | return 18 | } 19 | fmt.Printf("Severity (Base): %v (%v)\n", tm.Base.Severity(), tm.Base.Score()) 20 | fmt.Printf("Severity (Temporal): %v (%v)\n", tm.Temporal.Severity(), tm.Temporal.Score()) 21 | fmt.Printf("Severity (Environmental): %v (%v)\n", tm.Severity(), tm.Score()) 22 | // Output: 23 | // Severity (Base): High (7.8) 24 | // Severity (Temporal): Medium (6.4) 25 | // Severity (Environmental): High (9.2) 26 | } 27 | 28 | /* Copyright 2023 Spiegel 29 | * 30 | * Licensed under the Apache License, Version 2.0 (the "License"); 31 | * you may not use this file except in compliance with the License. 32 | * You may obtain a copy of the License at 33 | * 34 | * http://www.apache.org/licenses/LICENSE-2.0 35 | * 36 | * Unless required by applicable law or agreed to in writing, software 37 | * distributed under the License is distributed on an "AS IS" BASIS, 38 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 39 | * See the License for the specific language governing permissions and 40 | * limitations under the License. 41 | */ 42 | -------------------------------------------------------------------------------- /cvsserr/errors.go: -------------------------------------------------------------------------------- 1 | package cvsserr 2 | 3 | import "errors" 4 | 5 | var ( 6 | ErrNullPointer = errors.New("Null reference instance") 7 | ErrInvalidVector = errors.New("invalid vector") 8 | ErrNotSupportVer = errors.New("not support version") 9 | ErrNotSupportMetric = errors.New("not support metric") 10 | ErrInvalidTemplate = errors.New("invalid templete string") 11 | ErrSameMetric = errors.New("exist same metric") 12 | ErrInvalidValue = errors.New("invalid value of metric") 13 | ErrNoBaseMetrics = errors.New("no Base metrics") 14 | ErrNoTemporalMetrics = errors.New("no Temporal metrics") 15 | ErrNoEnvironmentalMetrics = errors.New("no Environmental metrics") 16 | ErrMisordered = errors.New("misordered vector string") 17 | ) 18 | 19 | /* Copyright 2018-2023 Spiegel 20 | * 21 | * Licensed under the Apache License, Version 2.0 (the "License"); 22 | * you may not use this file except in compliance with the License. 23 | * You may obtain a copy of the License at 24 | * 25 | * http://www.apache.org/licenses/LICENSE-2.0 26 | * 27 | * Unless required by applicable law or agreed to in writing, software 28 | * distributed under the License is distributed on an "AS IS" BASIS, 29 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 30 | * See the License for the specific language governing permissions and 31 | * limitations under the License. 32 | */ 33 | -------------------------------------------------------------------------------- /v2/metric/metric-au.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // Authentication is metric type for Base Metrics 4 | type Authentication int 5 | 6 | // Constant of Authentication result 7 | const ( 8 | AuthenticationUnknown Authentication = iota 9 | AuthenticationNone 10 | AuthenticationSingle 11 | AuthenticationMultiple 12 | ) 13 | 14 | var authenticationMap = map[Authentication]string{ 15 | AuthenticationNone: "N", 16 | AuthenticationSingle: "S", 17 | AuthenticationMultiple: "M", 18 | } 19 | 20 | var authenticationValueMap = map[Authentication]float64{ 21 | AuthenticationNone: 0.704, 22 | AuthenticationSingle: 0.56, 23 | AuthenticationMultiple: 0.45, 24 | } 25 | 26 | // GetAuthentication returns result of Authentication metric 27 | func GetAuthentication(s string) Authentication { 28 | for k, v := range authenticationMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return AuthenticationUnknown 34 | } 35 | 36 | func (av Authentication) String() string { 37 | if s, ok := authenticationMap[av]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of Authentication metric 44 | func (av Authentication) Value() float64 { 45 | if v, ok := authenticationValueMap[av]; ok { 46 | return v 47 | } 48 | return 0.0 49 | } 50 | 51 | // IsUnknown returns false if undefined result value of metric 52 | func (av Authentication) IsUnknown() bool { 53 | return av != AuthenticationUnknown 54 | } 55 | 56 | /* Copyright 2022 luxifer */ 57 | /* Contributed by Spiegel, 2023 */ 58 | -------------------------------------------------------------------------------- /v2/metric/metric-i.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // IntegrityImpact is metric type for Base Metrics 4 | type IntegrityImpact int 5 | 6 | // Constant of IntegrityImpact result 7 | const ( 8 | IntegrityImpactUnknown IntegrityImpact = iota 9 | IntegrityImpactNone 10 | IntegrityImpactPartial 11 | IntegrityImpactComplete 12 | ) 13 | 14 | var integrityImpactMap = map[IntegrityImpact]string{ 15 | IntegrityImpactNone: "N", 16 | IntegrityImpactPartial: "P", 17 | IntegrityImpactComplete: "C", 18 | } 19 | 20 | var integrityImpactValueMap = map[IntegrityImpact]float64{ 21 | IntegrityImpactNone: 0, 22 | IntegrityImpactPartial: 0.275, 23 | IntegrityImpactComplete: 0.66, 24 | } 25 | 26 | // GetIntegrityImpact returns result of IntegrityImpact metric 27 | func GetIntegrityImpact(s string) IntegrityImpact { 28 | for k, v := range integrityImpactMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return IntegrityImpactUnknown 34 | } 35 | 36 | func (ii IntegrityImpact) String() string { 37 | if s, ok := integrityImpactMap[ii]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of IntegrityImpact metric 44 | func (ii IntegrityImpact) Value() float64 { 45 | if v, ok := integrityImpactValueMap[ii]; ok { 46 | return v 47 | } 48 | return 0.0 49 | } 50 | 51 | // IsUnknown returns false if undefined result value of metric 52 | func (ii IntegrityImpact) IsUnknown() bool { 53 | return ii != IntegrityImpactUnknown 54 | } 55 | 56 | /* Copyright 2022 luxifer */ 57 | /* Contributed by Spiegel, 2023 */ 58 | -------------------------------------------------------------------------------- /v2/metric/severity.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // Severity is severity for Base Metrics 4 | type Severity int 5 | 6 | // Constant of severity 7 | const ( 8 | SeverityUnknown Severity = iota 9 | SeverityLow 10 | SeverityMedium 11 | SeverityHigh 12 | ) 13 | 14 | var severityMap = map[Severity]string{ 15 | SeverityLow: "Low", 16 | SeverityMedium: "Medium", 17 | SeverityHigh: "High", 18 | } 19 | 20 | func (sv Severity) String() string { 21 | if s, ok := severityMap[sv]; ok { 22 | return s 23 | } 24 | return "Unknown" 25 | } 26 | 27 | // GetSeverity returns severity by score of Base metrics 28 | func severity(score float64) Severity { 29 | switch true { 30 | case score >= 0 && score < 4.0: 31 | return SeverityLow 32 | case score >= 4.0 && score < 7.0: 33 | return SeverityMedium 34 | case score >= 7.0: 35 | return SeverityHigh 36 | default: 37 | return SeverityUnknown 38 | } 39 | } 40 | 41 | /* Copyright 2018-2023 Spiegel 42 | * 43 | * Licensed under the Apache License, Version 2.0 (the "License"); 44 | * you may not use this file except in compliance with the License. 45 | * You may obtain a copy of the License at 46 | * 47 | * http://www.apache.org/licenses/LICENSE-2.0 48 | * 49 | * Unless required by applicable law or agreed to in writing, software 50 | * distributed under the License is distributed on an "AS IS" BASIS, 51 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 52 | * See the License for the specific language governing permissions and 53 | * limitations under the License. 54 | */ 55 | -------------------------------------------------------------------------------- /v3/metric/scope_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "testing" 4 | 5 | func TestScope(t *testing.T) { 6 | testCases := []struct { 7 | input string 8 | result Scope 9 | res string 10 | defined bool 11 | }{ 12 | {input: "Z", result: ScopeUnknown, res: "", defined: false}, 13 | {input: "U", result: ScopeUnchanged, res: "U", defined: true}, 14 | {input: "C", result: ScopeChanged, res: "C", defined: true}, 15 | } 16 | 17 | for _, tc := range testCases { 18 | r := GetScope(tc.input) 19 | if r != tc.result { 20 | t.Errorf("GetScope(%v) = %v, want %v.", tc.input, r, tc.result) 21 | } 22 | str := r.String() 23 | if str != tc.res { 24 | t.Errorf("Scope.String(%v) = \"%v\", want \"%v\".", tc.input, str, tc.res) 25 | } 26 | if r.IsUnknown() == tc.defined { 27 | t.Errorf("Scope.IsDefined(%v) = %v, want %v.", tc.input, r.IsUnknown(), tc.defined) 28 | } 29 | } 30 | } 31 | 32 | /* Copyright 2018-2023 Spiegel 33 | * 34 | * Licensed under the Apache License, Version 2.0 (the "License"); 35 | * you may not use this file except in compliance with the License. 36 | * You may obtain a copy of the License at 37 | * 38 | * http://www.apache.org/licenses/LICENSE-2.0 39 | * 40 | * Unless required by applicable law or agreed to in writing, software 41 | * distributed under the License is distributed on an "AS IS" BASIS, 42 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 43 | * See the License for the specific language governing permissions and 44 | * limitations under the License. 45 | */ 46 | -------------------------------------------------------------------------------- /v2/metric/metric-ac.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // AccessComplexity is metric type for Base Metrics 4 | type AccessComplexity int 5 | 6 | // Constant of AccessComplexity result 7 | const ( 8 | AccessComplexityUnknown AccessComplexity = iota 9 | AccessComplexityHigh 10 | AccessComplexityMedium 11 | AccessComplexityLow 12 | ) 13 | 14 | var accessComplexityMap = map[AccessComplexity]string{ 15 | AccessComplexityHigh: "H", 16 | AccessComplexityMedium: "M", 17 | AccessComplexityLow: "L", 18 | } 19 | 20 | var accessComplexityValueMap = map[AccessComplexity]float64{ 21 | AccessComplexityHigh: 0.35, 22 | AccessComplexityMedium: 0.61, 23 | AccessComplexityLow: 0.71, 24 | } 25 | 26 | // GetAccessComplexity returns result of AccessComplexity metric 27 | func GetAccessComplexity(s string) AccessComplexity { 28 | for k, v := range accessComplexityMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return AccessComplexityUnknown 34 | } 35 | 36 | func (ac AccessComplexity) String() string { 37 | if s, ok := accessComplexityMap[ac]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of AccessComplexity metric 44 | func (ac AccessComplexity) Value() float64 { 45 | if v, ok := accessComplexityValueMap[ac]; ok { 46 | return v 47 | } 48 | return 0.0 49 | } 50 | 51 | // IsUnknown returns false if undefined result value of metric 52 | func (ac AccessComplexity) IsUnknown() bool { 53 | return ac != AccessComplexityUnknown 54 | } 55 | 56 | /* Copyright 2022 luxifer */ 57 | /* Contributed by Spiegel, 2023 */ 58 | -------------------------------------------------------------------------------- /v3/metric/scope.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // Scope is metric type for Base Metrics 4 | type Scope int 5 | 6 | // Constant of Scope result 7 | const ( 8 | ScopeUnknown Scope = iota 9 | ScopeUnchanged 10 | ScopeChanged 11 | ) 12 | 13 | var scopeMap = map[Scope]string{ 14 | ScopeUnchanged: "U", 15 | ScopeChanged: "C", 16 | } 17 | 18 | // GetScope returns result of Scope metric 19 | func GetScope(s string) Scope { 20 | for k, v := range scopeMap { 21 | if s == v { 22 | return k 23 | } 24 | } 25 | return ScopeUnknown 26 | } 27 | 28 | // IsChanged returns true if Scope value is ScopeChanged. 29 | func (sc Scope) IsChanged() bool { 30 | return sc == ScopeChanged 31 | } 32 | 33 | func (sc Scope) String() string { 34 | if s, ok := scopeMap[sc]; ok { 35 | return s 36 | } 37 | return "" 38 | } 39 | 40 | // IsUnknown returns false if undefined result value of metric 41 | func (sc Scope) IsUnknown() bool { 42 | return sc == ScopeUnknown 43 | } 44 | 45 | /* Copyright 2018-2023 Spiegel 46 | * 47 | * Licensed under the Apache License, Version 2.0 (the "License"); 48 | * you may not use this file except in compliance with the License. 49 | * You may obtain a copy of the License at 50 | * 51 | * http://www.apache.org/licenses/LICENSE-2.0 52 | * 53 | * Unless required by applicable law or agreed to in writing, software 54 | * distributed under the License is distributed on an "AS IS" BASIS, 55 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 56 | * See the License for the specific language governing permissions and 57 | * limitations under the License. 58 | */ 59 | -------------------------------------------------------------------------------- /v3/report/names/scope.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | sTitleMap = langNameMap{ 10 | language.English: "Scope", 11 | language.Japanese: "スコープ", 12 | } 13 | sNamesMap = map[metric.Scope]langNameMap{ 14 | metric.ScopeUnchanged: { 15 | language.English: "Unchanged", 16 | language.Japanese: "変更なし", 17 | }, 18 | metric.ScopeChanged: { 19 | language.English: "Changed", 20 | language.Japanese: "変更あり", 21 | }, 22 | } 23 | ) 24 | 25 | // Scope returns string instance name for display 26 | func Scope(lang language.Tag) string { 27 | return sTitleMap.getNameInLang(lang) 28 | } 29 | 30 | // SValueOf returns string name of value for display 31 | func SValueOf(s metric.Scope, lang language.Tag) string { 32 | if m, ok := sNamesMap[s]; ok { 33 | return m.getNameInLang(lang) 34 | } 35 | return unknownValueNameMap.getNameInLang(lang) 36 | } 37 | 38 | /* Copyright 2018-2023 Spiegel 39 | * 40 | * Licensed under the Apache License, Version 2.0 (the "License"); 41 | * you may not use this file except in compliance with the License. 42 | * You may obtain a copy of the License at 43 | * 44 | * http://www.apache.org/licenses/LICENSE-2.0 45 | * 46 | * Unless required by applicable law or agreed to in writing, software 47 | * distributed under the License is distributed on an "AS IS" BASIS, 48 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 49 | * See the License for the specific language governing permissions and 50 | * limitations under the License. 51 | */ 52 | -------------------------------------------------------------------------------- /v2/metric/metric-a.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // AvailabilityImpact is metric type for Base Metrics 4 | type AvailabilityImpact int 5 | 6 | // Constant of AvailabilityImpact result 7 | const ( 8 | AvailabilityImpactUnknown AvailabilityImpact = iota 9 | AvailabilityImpactNone 10 | AvailabilityImpactPartial 11 | AvailabilityImpactComplete 12 | ) 13 | 14 | var availabilityImpactMap = map[AvailabilityImpact]string{ 15 | AvailabilityImpactNone: "N", 16 | AvailabilityImpactPartial: "P", 17 | AvailabilityImpactComplete: "C", 18 | } 19 | 20 | var availabilityImpactValueMap = map[AvailabilityImpact]float64{ 21 | AvailabilityImpactNone: 0, 22 | AvailabilityImpactPartial: 0.275, 23 | AvailabilityImpactComplete: 0.66, 24 | } 25 | 26 | // GetAvailabilityImpact returns result of AvailabilityImpact metric 27 | func GetAvailabilityImpact(s string) AvailabilityImpact { 28 | for k, v := range availabilityImpactMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return AvailabilityImpactUnknown 34 | } 35 | 36 | func (ai AvailabilityImpact) String() string { 37 | if s, ok := availabilityImpactMap[ai]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of AvailabilityImpact metric 44 | func (ai AvailabilityImpact) Value() float64 { 45 | if v, ok := availabilityImpactValueMap[ai]; ok { 46 | return v 47 | } 48 | return 0.0 49 | } 50 | 51 | // IsUnknown returns false if undefined result value of metric 52 | func (ai AvailabilityImpact) IsUnknown() bool { 53 | return ai != AvailabilityImpactUnknown 54 | } 55 | 56 | /* Copyright 2022 luxifer */ 57 | /* Contributed by Spiegel, 2023 */ 58 | -------------------------------------------------------------------------------- /v3/report/names/attack-complexity.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | acTitleMap = langNameMap{ 10 | language.English: "Attack Complexity", 11 | language.Japanese: "攻撃条件の複雑さ", 12 | } 13 | acNamesMap = map[metric.AttackComplexity]langNameMap{ 14 | metric.AttackComplexityHigh: { 15 | language.English: "High", 16 | language.Japanese: "高", 17 | }, 18 | metric.AttackComplexityLow: { 19 | language.English: "Low", 20 | language.Japanese: "低", 21 | }, 22 | } 23 | ) 24 | 25 | // AttackComplexity returns string instance name for display 26 | func AttackComplexity(lang language.Tag) string { 27 | return acTitleMap.getNameInLang(lang) 28 | } 29 | 30 | // ACValueOf returns string name of value for display 31 | func ACValueOf(ac metric.AttackComplexity, lang language.Tag) string { 32 | if m, ok := acNamesMap[ac]; ok { 33 | return m.getNameInLang(lang) 34 | } 35 | return unknownValueNameMap.getNameInLang(lang) 36 | } 37 | 38 | /* Copyright 2018-2023 Spiegel 39 | * 40 | * Licensed under the Apache License, Version 2.0 (the "License"); 41 | * you may not use this file except in compliance with the License. 42 | * You may obtain a copy of the License at 43 | * 44 | * http://www.apache.org/licenses/LICENSE-2.0 45 | * 46 | * Unless required by applicable law or agreed to in writing, software 47 | * distributed under the License is distributed on an "AS IS" BASIS, 48 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 49 | * See the License for the specific language governing permissions and 50 | * limitations under the License. 51 | */ 52 | -------------------------------------------------------------------------------- /v3/report/names/user-interaction.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | uiTitleMap = langNameMap{ 10 | language.English: "User Interaction", 11 | language.Japanese: "ユーザ関与レベル", 12 | } 13 | uiNamesMap = map[metric.UserInteraction]langNameMap{ 14 | metric.UserInteractionRequired: { 15 | language.English: "Required", 16 | language.Japanese: "要", 17 | }, 18 | metric.UserInteractionNone: { 19 | language.English: "None", 20 | language.Japanese: "不要", 21 | }, 22 | } 23 | ) 24 | 25 | // UserInteraction returns string instance name for display 26 | func UserInteraction(lang language.Tag) string { 27 | return uiTitleMap.getNameInLang(lang) 28 | } 29 | 30 | // UIValueOf returns string name of value for display 31 | func UIValueOf(ui metric.UserInteraction, lang language.Tag) string { 32 | if m, ok := uiNamesMap[ui]; ok { 33 | return m.getNameInLang(lang) 34 | } 35 | return unknownValueNameMap.getNameInLang(lang) 36 | } 37 | 38 | /* Copyright 2018-2023 Spiegel 39 | * 40 | * Licensed under the Apache License, Version 2.0 (the "License"); 41 | * you may not use this file except in compliance with the License. 42 | * You may obtain a copy of the License at 43 | * 44 | * http://www.apache.org/licenses/LICENSE-2.0 45 | * 46 | * Unless required by applicable law or agreed to in writing, software 47 | * distributed under the License is distributed on an "AS IS" BASIS, 48 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 49 | * See the License for the specific language governing permissions and 50 | * limitations under the License. 51 | */ 52 | -------------------------------------------------------------------------------- /v3/report/templete.go: -------------------------------------------------------------------------------- 1 | package report 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "text/template" 7 | 8 | "github.com/goark/errs" 9 | "github.com/goark/go-cvss/cvsserr" 10 | ) 11 | 12 | func getTempleteString(r io.Reader) (string, error) { 13 | if r == nil { 14 | return "", errs.Wrap(cvsserr.ErrInvalidTemplate) 15 | } 16 | tmpdata := &bytes.Buffer{} 17 | if _, err := io.Copy(tmpdata, r); err != nil { 18 | return "", errs.Wrap(cvsserr.ErrInvalidTemplate, errs.WithCause(err)) 19 | } 20 | return tmpdata.String(), nil 21 | } 22 | 23 | func executeTemplate(data interface{}, tempStr string) (io.Reader, error) { 24 | t, err := template.New("Repost").Parse(tempStr) 25 | if err != nil { 26 | return nil, errs.Wrap(cvsserr.ErrInvalidTemplate, errs.WithCause(err), errs.WithContext("templete", tempStr)) 27 | } 28 | buf := &bytes.Buffer{} 29 | if err := t.Execute(buf, data); err != nil { 30 | return nil, errs.Wrap(cvsserr.ErrInvalidTemplate, errs.WithCause(err), errs.WithContext("templete", tempStr)) 31 | } 32 | return buf, nil 33 | } 34 | 35 | /* Copyright 2018-2020 Spiegel 36 | * 37 | * Licensed under the Apache License, Version 2.0 (the "License"); 38 | * you may not use this file except in compliance with the License. 39 | * You may obtain a copy of the License at 40 | * 41 | * http://www.apache.org/licenses/LICENSE-2.0 42 | * 43 | * Unless required by applicable law or agreed to in writing, software 44 | * distributed under the License is distributed on an "AS IS" BASIS, 45 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 46 | * See the License for the specific language governing permissions and 47 | * limitations under the License. 48 | */ 49 | -------------------------------------------------------------------------------- /v2/metric/metric-c.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ConfidentialityImpact is metric type for Base Metrics 4 | type ConfidentialityImpact int 5 | 6 | // Constant of ConfidentialityImpact result 7 | const ( 8 | ConfidentialityImpactUnknown ConfidentialityImpact = iota 9 | ConfidentialityImpactNone 10 | ConfidentialityImpactPartial 11 | ConfidentialityImpactComplete 12 | ) 13 | 14 | var confidentialityImpactMap = map[ConfidentialityImpact]string{ 15 | ConfidentialityImpactNone: "N", 16 | ConfidentialityImpactPartial: "P", 17 | ConfidentialityImpactComplete: "C", 18 | } 19 | 20 | var confidentialityImpactValueMap = map[ConfidentialityImpact]float64{ 21 | ConfidentialityImpactNone: 0, 22 | ConfidentialityImpactPartial: 0.275, 23 | ConfidentialityImpactComplete: 0.66, 24 | } 25 | 26 | // GetConfidentialityImpact returns result of ConfidentialityImpact metric 27 | func GetConfidentialityImpact(s string) ConfidentialityImpact { 28 | for k, v := range confidentialityImpactMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return ConfidentialityImpactUnknown 34 | } 35 | 36 | func (ci ConfidentialityImpact) String() string { 37 | if s, ok := confidentialityImpactMap[ci]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of ConfidentialityImpact metric 44 | func (ci ConfidentialityImpact) Value() float64 { 45 | if v, ok := confidentialityImpactValueMap[ci]; ok { 46 | return v 47 | } 48 | return 0.0 49 | } 50 | 51 | // IsUnknown returns false if undefined result value of metric 52 | func (ci ConfidentialityImpact) IsUnknown() bool { 53 | return ci != ConfidentialityImpactUnknown 54 | } 55 | 56 | /* Copyright 2022 luxifer */ 57 | /* Contributed by Spiegel, 2023 */ 58 | -------------------------------------------------------------------------------- /v3/metric/report-confidence.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ReportConfidence is metric type for Temporal Metrics 4 | type ReportConfidence int 5 | 6 | // Constant of ReportConfidence result 7 | const ( 8 | ReportConfidenceInvalid ReportConfidence = iota 9 | ReportConfidenceNotDefined 10 | ReportConfidenceUnknown 11 | ReportConfidenceReasonable 12 | ReportConfidenceConfirmed 13 | ) 14 | 15 | var reportConfidenceMap = map[ReportConfidence]string{ 16 | ReportConfidenceNotDefined: "X", 17 | ReportConfidenceUnknown: "U", 18 | ReportConfidenceReasonable: "R", 19 | ReportConfidenceConfirmed: "C", 20 | } 21 | 22 | var reportConfidenceValueMap = map[ReportConfidence]float64{ 23 | ReportConfidenceNotDefined: 1, 24 | ReportConfidenceUnknown: 0.92, 25 | ReportConfidenceReasonable: 0.96, 26 | ReportConfidenceConfirmed: 1, 27 | } 28 | 29 | // GetReportConfidence returns result of ReportConfidence metric 30 | func GetReportConfidence(s string) ReportConfidence { 31 | for k, v := range reportConfidenceMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return ReportConfidenceInvalid 37 | } 38 | 39 | func (rc ReportConfidence) String() string { 40 | if s, ok := reportConfidenceMap[rc]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of ReportConfidence metric 47 | func (rc ReportConfidence) Value() float64 { 48 | if v, ok := reportConfidenceValueMap[rc]; ok { 49 | return v 50 | } 51 | return 1 52 | } 53 | 54 | // IsDefined returns false if undefined result value of metric 55 | func (rc ReportConfidence) IsValid() bool { 56 | _, ok := reportConfidenceValueMap[rc] 57 | return ok 58 | } 59 | 60 | /* Copyright by Florent Viel, 2020 */ 61 | /* Contributed by Spiegel, 2020-2023 */ 62 | -------------------------------------------------------------------------------- /v3/report/names/integrity-impact.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | iTitleMap = langNameMap{ 10 | language.English: "Integrity Impact", 11 | language.Japanese: "完全性への影響", 12 | } 13 | iNamesMap = map[metric.IntegrityImpact]langNameMap{ 14 | metric.IntegrityImpactNone: { 15 | language.English: "None", 16 | language.Japanese: "なし", 17 | }, 18 | metric.IntegrityImpactLow: { 19 | language.English: "Low", 20 | language.Japanese: "低", 21 | }, 22 | metric.IntegrityImpactHigh: { 23 | language.English: "High", 24 | language.Japanese: "高", 25 | }, 26 | } 27 | ) 28 | 29 | // IntegrityImpact returns string instance name for display 30 | func IntegrityImpact(lang language.Tag) string { 31 | return iTitleMap.getNameInLang(lang) 32 | } 33 | 34 | // IValueOf returns string name of value for display 35 | func IValueOf(i metric.IntegrityImpact, lang language.Tag) string { 36 | if m, ok := iNamesMap[i]; ok { 37 | return m.getNameInLang(lang) 38 | } 39 | return unknownValueNameMap.getNameInLang(lang) 40 | } 41 | 42 | /* Copyright 2018-2023 Spiegel 43 | * 44 | * Licensed under the Apache License, Version 2.0 (the "License"); 45 | * you may not use this file except in compliance with the License. 46 | * You may obtain a copy of the License at 47 | * 48 | * http://www.apache.org/licenses/LICENSE-2.0 49 | * 50 | * Unless required by applicable law or agreed to in writing, software 51 | * distributed under the License is distributed on an "AS IS" BASIS, 52 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 53 | * See the License for the specific language governing permissions and 54 | * limitations under the License. 55 | */ 56 | -------------------------------------------------------------------------------- /v2/metric/example_test.go: -------------------------------------------------------------------------------- 1 | package metric_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/goark/go-cvss/v2/metric" 7 | ) 8 | 9 | func ExampleBase_Decode() { 10 | m, err := metric.NewBase().Decode("AV:N/AC:L/Au:N/C:N/I:N/A:C") //CVE-2002-0392 11 | if err != nil { 12 | return 13 | } 14 | fmt.Println("Score =", m.Score()) 15 | fmt.Println("Severity =", m.Severity()) 16 | //Output: 17 | //Score = 7.8 18 | //Severity = High 19 | } 20 | 21 | func ExampleTemporal_Decode() { 22 | m, err := metric.NewTemporal().Decode("AV:N/AC:L/Au:N/C:N/I:N/A:C/E:F/RL:OF/RC:C") //CVE-2002-0392 23 | if err != nil { 24 | return 25 | } 26 | fmt.Println("Score =", m.Score()) 27 | fmt.Println("Severity =", m.Severity()) 28 | //Output: 29 | //Score = 6.4 30 | //Severity = Medium 31 | } 32 | 33 | func ExampleEnvironmental_Decode() { 34 | m, err := metric.NewEnvironmental().Decode("AV:N/AC:L/Au:N/C:N/I:N/A:C/E:F/RL:OF/RC:C/CDP:H/TD:H/CR:M/IR:M/AR:H") //CVE-2002-0392 35 | if err != nil { 36 | return 37 | } 38 | fmt.Println("Score =", m.Score()) 39 | fmt.Println("Severity =", m.Severity()) 40 | //Output: 41 | //Score = 9.2 42 | //Severity = High 43 | } 44 | 45 | /* Copyright 2023 Spiegel 46 | * 47 | * Licensed under the Apache License, Version 2.0 (the "License"); 48 | * you may not use this file except in compliance with the License. 49 | * You may obtain a copy of the License at 50 | * 51 | * http://www.apache.org/licenses/LICENSE-2.0 52 | * 53 | * Unless required by applicable law or agreed to in writing, software 54 | * distributed under the License is distributed on an "AS IS" BASIS, 55 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 56 | * See the License for the specific language governing permissions and 57 | * limitations under the License. 58 | */ 59 | -------------------------------------------------------------------------------- /v3/report/names/modified-scope.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | msTitleMap = langNameMap{ 10 | language.English: "Modified Scope", 11 | language.Japanese: "調整後のスコープ", 12 | } 13 | msNamesMap = map[metric.ModifiedScope]langNameMap{ 14 | metric.ModifiedScopeNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.ModifiedScopeUnchanged: { 19 | language.English: "Unchanged", 20 | language.Japanese: "変更なし", 21 | }, 22 | metric.ModifiedScopeChanged: { 23 | language.English: "Changed", 24 | language.Japanese: "変更あり", 25 | }, 26 | } 27 | ) 28 | 29 | //ModifiedScope returns string instance name for display 30 | func ModifiedScope(lang language.Tag) string { 31 | return msTitleMap.getNameInLang(lang) 32 | } 33 | 34 | //MSValueOf returns string name of value for display 35 | func MSValueOf(ms metric.ModifiedScope, lang language.Tag) string { 36 | if m, ok := msNamesMap[ms]; ok { 37 | return m.getNameInLang(lang) 38 | } 39 | return unknownValueNameMap.getNameInLang(lang) 40 | } 41 | 42 | /* Copyright 2022 Spiegel 43 | * 44 | * Licensed under the Apache License, Version 2.0 (the "License"); 45 | * you may not use this file except in compliance with the License. 46 | * You may obtain a copy of the License at 47 | * 48 | * http://www.apache.org/licenses/LICENSE-2.0 49 | * 50 | * Unless required by applicable law or agreed to in writing, software 51 | * distributed under the License is distributed on an "AS IS" BASIS, 52 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 53 | * See the License for the specific language governing permissions and 54 | * limitations under the License. 55 | */ 56 | -------------------------------------------------------------------------------- /v3/metric/exploitability.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // Exploitability is metric type for Temporal Metrics 4 | type Exploitability int 5 | 6 | // Constant of Exploitability result 7 | const ( 8 | ExploitabilityInvalid Exploitability = iota 9 | ExploitabilityNotDefined 10 | ExploitabilityUnproven 11 | ExploitabilityProofOfConcept 12 | ExploitabilityFunctional 13 | ExploitabilityHigh 14 | ) 15 | 16 | var exploitabilityMap = map[Exploitability]string{ 17 | ExploitabilityNotDefined: "X", 18 | ExploitabilityUnproven: "U", 19 | ExploitabilityProofOfConcept: "P", 20 | ExploitabilityFunctional: "F", 21 | ExploitabilityHigh: "H", 22 | } 23 | 24 | var exploitabilityValueMap = map[Exploitability]float64{ 25 | ExploitabilityNotDefined: 1, 26 | ExploitabilityUnproven: 0.91, 27 | ExploitabilityProofOfConcept: 0.94, 28 | ExploitabilityFunctional: 0.97, 29 | ExploitabilityHigh: 1, 30 | } 31 | 32 | // GetExploitability returns result of Exploitability metric 33 | func GetExploitability(s string) Exploitability { 34 | for k, v := range exploitabilityMap { 35 | if s == v { 36 | return k 37 | } 38 | } 39 | return ExploitabilityInvalid 40 | } 41 | 42 | func (ex Exploitability) String() string { 43 | if s, ok := exploitabilityMap[ex]; ok { 44 | return s 45 | } 46 | return "" 47 | } 48 | 49 | // Value returns value of Exploitability metric 50 | func (ex Exploitability) Value() float64 { 51 | if v, ok := exploitabilityValueMap[ex]; ok { 52 | return v 53 | } 54 | return 1 55 | } 56 | 57 | // IsDefined returns false if undefined result value of metric 58 | func (ex Exploitability) IsValid() bool { 59 | _, ok := exploitabilityValueMap[ex] 60 | return ok 61 | } 62 | 63 | /* Copyright by Florent Viel, 2020 */ 64 | /* Contributed by Spiegel, 2020-2023 */ 65 | -------------------------------------------------------------------------------- /v3/report/names/availability-impact.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | aTitleMap = langNameMap{ 10 | language.English: "Availability Impact", 11 | language.Japanese: "可用性への影響", 12 | } 13 | aNamesMap = map[metric.AvailabilityImpact]langNameMap{ 14 | metric.AvailabilityImpactNone: { 15 | language.English: "None", 16 | language.Japanese: "なし", 17 | }, 18 | metric.AvailabilityImpactLow: { 19 | language.English: "Low", 20 | language.Japanese: "低", 21 | }, 22 | metric.AvailabilityImpactHigh: { 23 | language.English: "High", 24 | language.Japanese: "高", 25 | }, 26 | } 27 | ) 28 | 29 | // AvailabilityImpact returns string instance name for display 30 | func AvailabilityImpact(lang language.Tag) string { 31 | return aTitleMap.getNameInLang(lang) 32 | } 33 | 34 | // AValueOf returns string name of value for display 35 | func AValueOf(a metric.AvailabilityImpact, lang language.Tag) string { 36 | if m, ok := aNamesMap[a]; ok { 37 | return m.getNameInLang(lang) 38 | } 39 | return unknownValueNameMap.getNameInLang(lang) 40 | } 41 | 42 | /* Copyright 2018-2023 Spiegel 43 | * 44 | * Licensed under the Apache License, Version 2.0 (the "License"); 45 | * you may not use this file except in compliance with the License. 46 | * You may obtain a copy of the License at 47 | * 48 | * http://www.apache.org/licenses/LICENSE-2.0 49 | * 50 | * Unless required by applicable law or agreed to in writing, software 51 | * distributed under the License is distributed on an "AS IS" BASIS, 52 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 53 | * See the License for the specific language governing permissions and 54 | * limitations under the License. 55 | */ 56 | -------------------------------------------------------------------------------- /v3/report/names/privileges-required.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | prTitleMap = langNameMap{ 10 | language.English: "Privileges Required", 11 | language.Japanese: "必要な特権レベル", 12 | } 13 | prNamesMap = map[metric.PrivilegesRequired]langNameMap{ 14 | metric.PrivilegesRequiredHigh: { 15 | language.English: "High", 16 | language.Japanese: "高", 17 | }, 18 | metric.PrivilegesRequiredLow: { 19 | language.English: "Low", 20 | language.Japanese: "低", 21 | }, 22 | metric.PrivilegesRequiredNone: { 23 | language.English: "None", 24 | language.Japanese: "不要", 25 | }, 26 | } 27 | ) 28 | 29 | // PrivilegesRequired returns string instance name for display 30 | func PrivilegesRequired(lang language.Tag) string { 31 | return prTitleMap.getNameInLang(lang) 32 | } 33 | 34 | // PRValueOf returns string name of value for display 35 | func PRValueOf(pr metric.PrivilegesRequired, lang language.Tag) string { 36 | if m, ok := prNamesMap[pr]; ok { 37 | return m.getNameInLang(lang) 38 | } 39 | return unknownValueNameMap.getNameInLang(lang) 40 | } 41 | 42 | /* Copyright 2018-2023 Spiegel 43 | * 44 | * Licensed under the Apache License, Version 2.0 (the "License"); 45 | * you may not use this file except in compliance with the License. 46 | * You may obtain a copy of the License at 47 | * 48 | * http://www.apache.org/licenses/LICENSE-2.0 49 | * 50 | * Unless required by applicable law or agreed to in writing, software 51 | * distributed under the License is distributed on an "AS IS" BASIS, 52 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 53 | * See the License for the specific language governing permissions and 54 | * limitations under the License. 55 | */ 56 | -------------------------------------------------------------------------------- /v3/report/names/confidentiality-impact.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | cTileMap = langNameMap{ 10 | language.English: "Confidentiality Impact", 11 | language.Japanese: "機密性への影響", 12 | } 13 | cNamesMap = map[metric.ConfidentialityImpact]langNameMap{ 14 | metric.ConfidentialityImpactNone: { 15 | language.English: "None", 16 | language.Japanese: "なし", 17 | }, 18 | metric.ConfidentialityImpactLow: { 19 | language.English: "Low", 20 | language.Japanese: "低", 21 | }, 22 | metric.ConfidentialityImpactHigh: { 23 | language.English: "High", 24 | language.Japanese: "高", 25 | }, 26 | } 27 | ) 28 | 29 | // ConfidentialityImpact returns string instance name for display 30 | func ConfidentialityImpact(lang language.Tag) string { 31 | return cTileMap.getNameInLang(lang) 32 | } 33 | 34 | // CValueOf returns string name of value for display 35 | func CValueOf(c metric.ConfidentialityImpact, lang language.Tag) string { 36 | if m, ok := cNamesMap[c]; ok { 37 | return m.getNameInLang(lang) 38 | } 39 | return unknownValueNameMap.getNameInLang(lang) 40 | } 41 | 42 | /* Copyright 2018-2023 Spiegel 43 | * 44 | * Licensed under the Apache License, Version 2.0 (the "License"); 45 | * you may not use this file except in compliance with the License. 46 | * You may obtain a copy of the License at 47 | * 48 | * http://www.apache.org/licenses/LICENSE-2.0 49 | * 50 | * Unless required by applicable law or agreed to in writing, software 51 | * distributed under the License is distributed on an "AS IS" BASIS, 52 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 53 | * See the License for the specific language governing permissions and 54 | * limitations under the License. 55 | */ 56 | -------------------------------------------------------------------------------- /v3/metric/integrity-requirement.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // IntegrityRequirement is metric type for Base Metrics 4 | type IntegrityRequirement int 5 | 6 | // Constant of IntegrityRequirement result 7 | const ( 8 | IntegrityRequirementInvalid IntegrityRequirement = iota 9 | IntegrityRequirementNotDefined 10 | IntegrityRequirementLow 11 | IntegrityRequirementMedium 12 | IntegrityRequirementHigh 13 | ) 14 | 15 | var IntegrityRequirementMap = map[IntegrityRequirement]string{ 16 | IntegrityRequirementNotDefined: "X", 17 | IntegrityRequirementLow: "L", 18 | IntegrityRequirementMedium: "M", 19 | IntegrityRequirementHigh: "H", 20 | } 21 | 22 | var IntegrityRequirementValueMap = map[IntegrityRequirement]float64{ 23 | IntegrityRequirementNotDefined: 1, 24 | IntegrityRequirementLow: 0.5, 25 | IntegrityRequirementMedium: 1, 26 | IntegrityRequirementHigh: 1.5, 27 | } 28 | 29 | // GetIntegrityRequirement returns result of ConfidentalityRequirement metric 30 | func GetIntegrityRequirement(s string) IntegrityRequirement { 31 | for k, v := range IntegrityRequirementMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return IntegrityRequirementInvalid 37 | } 38 | 39 | func (ir IntegrityRequirement) String() string { 40 | if s, ok := IntegrityRequirementMap[ir]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of AttackVector metric 47 | func (ir IntegrityRequirement) Value() float64 { 48 | if v, ok := IntegrityRequirementValueMap[ir]; ok { 49 | return v 50 | } 51 | return 0.0 52 | } 53 | 54 | // IsDefined returns false if undefined result value of metric 55 | func (ir IntegrityRequirement) IsValid() bool { 56 | _, ok := IntegrityRequirementValueMap[ir] 57 | return ok 58 | } 59 | 60 | /* Copyright 2022 thejohnbrown */ 61 | /* Contributed by Spiegel, 2023 */ 62 | -------------------------------------------------------------------------------- /v3/metric/user-interaction_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "testing" 4 | 5 | func TestUserInteraction(t *testing.T) { 6 | testCases := []struct { 7 | input string 8 | result UserInteraction 9 | res string 10 | value float64 11 | defined bool 12 | }{ 13 | {input: "Z", result: UserInteractionUnknown, res: "", value: 0.0, defined: false}, 14 | {input: "R", result: UserInteractionRequired, res: "R", value: 0.62, defined: true}, 15 | {input: "N", result: UserInteractionNone, res: "N", value: 0.85, defined: true}, 16 | } 17 | 18 | for _, tc := range testCases { 19 | r := GetUserInteraction(tc.input) 20 | if r != tc.result { 21 | t.Errorf("GetUserInteraction(%v) = %v, want %v.", tc.input, r, tc.result) 22 | } 23 | str := r.String() 24 | if str != tc.res { 25 | t.Errorf("UserInteraction.String(%v) = \"%v\", want \"%v\".", tc.input, str, tc.res) 26 | } 27 | v := r.Value() 28 | if v != tc.value { 29 | t.Errorf("UserInteraction.Value(%v) = %v, want %v.", tc.input, v, tc.value) 30 | } 31 | if r.IsUnknown() == tc.defined { 32 | t.Errorf("UserInteraction.IsDefined(%v) = %v, want %v.", tc.input, r.IsUnknown(), tc.defined) 33 | } 34 | } 35 | } 36 | 37 | /* Copyright 2018-2023 Spiegel 38 | * 39 | * Licensed under the Apache License, Version 2.0 (the "License"); 40 | * you may not use this file except in compliance with the License. 41 | * You may obtain a copy of the License at 42 | * 43 | * http://www.apache.org/licenses/LICENSE-2.0 44 | * 45 | * Unless required by applicable law or agreed to in writing, software 46 | * distributed under the License is distributed on an "AS IS" BASIS, 47 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 48 | * See the License for the specific language governing permissions and 49 | * limitations under the License. 50 | */ 51 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | 8 | permissions: 9 | contents: read 10 | # Optional: allow read access to pull request. Use with `only-new-issues` option. 11 | # pull-requests: read 12 | jobs: 13 | golangci: 14 | name: lint 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v3 18 | - uses: actions/setup-go@v3 19 | with: 20 | go-version-file: 'go.mod' 21 | - name: golangci-lint 22 | uses: golangci/golangci-lint-action@v3 23 | with: 24 | # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version 25 | version: latest 26 | 27 | # Optional: working directory, useful for monorepos 28 | # working-directory: somedir 29 | 30 | # Optional: golangci-lint command line arguments. 31 | args: --enable gosec 32 | 33 | # Optional: show only new issues if it's a pull request. The default value is `false`. 34 | # only-new-issues: true 35 | 36 | # Optional: if set to true then the all caching functionality will be complete disabled, 37 | # takes precedence over all other caching options. 38 | # skip-cache: true 39 | 40 | # Optional: if set to true then the action don't cache or restore ~/go/pkg. 41 | # skip-pkg-cache: true 42 | 43 | # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. 44 | # skip-build-cache: true 45 | - name: testing 46 | run: go test -shuffle on ./... 47 | - name: install govulncheck 48 | run: go install golang.org/x/vuln/cmd/govulncheck@latest 49 | - name: running govulncheck 50 | run: govulncheck ./... 51 | -------------------------------------------------------------------------------- /v3/metric/attack-complexity_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "testing" 4 | 5 | func TestAttackComplexity(t *testing.T) { 6 | testCases := []struct { 7 | input string 8 | result AttackComplexity 9 | res string 10 | value float64 11 | defined bool 12 | }{ 13 | {input: "Z", result: AttackComplexityUnknown, res: "", value: 0.0, defined: false}, 14 | {input: "H", result: AttackComplexityHigh, res: "H", value: 0.44, defined: true}, 15 | {input: "L", result: AttackComplexityLow, res: "L", value: 0.77, defined: true}, 16 | } 17 | 18 | for _, tc := range testCases { 19 | r := GetAttackComplexity(tc.input) 20 | if r != tc.result { 21 | t.Errorf("GetAttackComplexity(%v) = %v, want %v.", tc.input, r, tc.result) 22 | } 23 | str := r.String() 24 | if str != tc.res { 25 | t.Errorf("AttackComplexity.String(%v) = \"%v\", want \"%v\".", tc.input, str, tc.res) 26 | } 27 | v := r.Value() 28 | if v != tc.value { 29 | t.Errorf("AttackComplexity.Value(%v) = %v, want %v.", tc.input, v, tc.value) 30 | } 31 | if r.IsUnknown() == tc.defined { 32 | t.Errorf("AttackComplexity.IsDefined(%v) = %v, want %v.", tc.input, r.IsUnknown(), tc.defined) 33 | } 34 | } 35 | } 36 | 37 | /* Copyright 2018-2023 Spiegel 38 | * 39 | * Licensed under the Apache License, Version 2.0 (the "License"); 40 | * you may not use this file except in compliance with the License. 41 | * You may obtain a copy of the License at 42 | * 43 | * http://www.apache.org/licenses/LICENSE-2.0 44 | * 45 | * Unless required by applicable law or agreed to in writing, software 46 | * distributed under the License is distributed on an "AS IS" BASIS, 47 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 48 | * See the License for the specific language governing permissions and 49 | * limitations under the License. 50 | */ 51 | -------------------------------------------------------------------------------- /v3/metric/remediation-level.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // RemediationLevel is metric type for Temporal Metrics 4 | type RemediationLevel int 5 | 6 | // Constant of RemediationLevel result 7 | const ( 8 | RemediationLevelInvalid RemediationLevel = iota 9 | RemediationLevelNotDefined 10 | RemediationLevelOfficialFix 11 | RemediationLevelTemporaryFix 12 | RemediationLevelWorkaround 13 | RemediationLevelUnavailable 14 | ) 15 | 16 | var remediationLevelMap = map[RemediationLevel]string{ 17 | RemediationLevelNotDefined: "X", 18 | RemediationLevelOfficialFix: "O", 19 | RemediationLevelTemporaryFix: "T", 20 | RemediationLevelWorkaround: "W", 21 | RemediationLevelUnavailable: "U", 22 | } 23 | 24 | var remediationLevelValueMap = map[RemediationLevel]float64{ 25 | RemediationLevelNotDefined: 1, 26 | RemediationLevelOfficialFix: 0.95, 27 | RemediationLevelTemporaryFix: 0.96, 28 | RemediationLevelWorkaround: 0.97, 29 | RemediationLevelUnavailable: 1, 30 | } 31 | 32 | // GetRemediationLevel returns result of RemediationLevel metric 33 | func GetRemediationLevel(s string) RemediationLevel { 34 | for k, v := range remediationLevelMap { 35 | if s == v { 36 | return k 37 | } 38 | } 39 | return RemediationLevelInvalid 40 | } 41 | 42 | func (rl RemediationLevel) String() string { 43 | if s, ok := remediationLevelMap[rl]; ok { 44 | return s 45 | } 46 | return "" 47 | } 48 | 49 | // Value returns value of RemediationLevel metric 50 | func (rl RemediationLevel) Value() float64 { 51 | if v, ok := remediationLevelValueMap[rl]; ok { 52 | return v 53 | } 54 | return 1 55 | } 56 | 57 | // IsDefined returns false if undefined result value of metric 58 | func (rl RemediationLevel) IsValid() bool { 59 | _, ok := remediationLevelValueMap[rl] 60 | return ok 61 | } 62 | 63 | /* Copyright by Florent Viel, 2020 */ 64 | /* Contributed by Spiegel, 2020-2023 */ 65 | -------------------------------------------------------------------------------- /v3/metric/version.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/goark/errs" 7 | "github.com/goark/go-cvss/cvsserr" 8 | ) 9 | 10 | // Version is error number for CVSS 11 | type Version int 12 | 13 | const nameCVSS = "CVSS" 14 | 15 | const ( 16 | VUnknown Version = iota //unknown version 17 | V3_0 //v3.0 18 | V3_1 //v3.1 19 | ) 20 | 21 | var verStrings = map[Version]string{ 22 | V3_0: "3.0", 23 | V3_1: "3.1", 24 | } 25 | 26 | // String is Stringer method 27 | func (n Version) String() string { 28 | if s, ok := verStrings[n]; ok { 29 | return s 30 | } 31 | return "unknown" 32 | } 33 | 34 | // GetVersion returns Version number from string 35 | func GetVersion(vec string) (Version, error) { 36 | v := strings.Split(vec, ":") 37 | if len(v) != 2 { 38 | return VUnknown, errs.Wrap(cvsserr.ErrInvalidVector, errs.WithContext("vector", vec)) 39 | } 40 | if v[0] != nameCVSS { 41 | return VUnknown, errs.Wrap(cvsserr.ErrInvalidVector, errs.WithContext("vector", vec)) 42 | } 43 | return get(v[1]), nil 44 | } 45 | 46 | func get(s string) Version { 47 | for k, v := range verStrings { 48 | if s == v { 49 | return k 50 | } 51 | } 52 | return VUnknown 53 | } 54 | 55 | /* Copyright 2018-2023 Spiegel 56 | * 57 | * Licensed under the Apache License, Version 2.0 (the "License"); 58 | * you may not use this file except in compliance with the License. 59 | * You may obtain a copy of the License at 60 | * 61 | * http://www.apache.org/licenses/LICENSE-2.0 62 | * 63 | * Unless required by applicable law or agreed to in writing, software 64 | * distributed under the License is distributed on an "AS IS" BASIS, 65 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 66 | * See the License for the specific language governing permissions and 67 | * limitations under the License. 68 | */ 69 | -------------------------------------------------------------------------------- /v3/report/names/modified-attack-complexity.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | macTitleMap = langNameMap{ 10 | language.English: "Modified Attack Complexity", 11 | language.Japanese: "調整後の攻撃条件の複雑さ", 12 | } 13 | macNamesMap = map[metric.ModifiedAttackComplexity]langNameMap{ 14 | metric.ModifiedAttackComplexityNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.ModifiedAttackComplexityHigh: { 19 | language.English: "High", 20 | language.Japanese: "高", 21 | }, 22 | metric.ModifiedAttackComplexityLow: { 23 | language.English: "Low", 24 | language.Japanese: "低", 25 | }, 26 | } 27 | ) 28 | 29 | //ModifiedAttackComplexity returns string instance name for display 30 | func ModifiedAttackComplexity(lang language.Tag) string { 31 | return macTitleMap.getNameInLang(lang) 32 | } 33 | 34 | //MACValueOf returns string name of value for display 35 | func MACValueOf(mac metric.ModifiedAttackComplexity, lang language.Tag) string { 36 | if m, ok := macNamesMap[mac]; ok { 37 | return m.getNameInLang(lang) 38 | } 39 | return unknownValueNameMap.getNameInLang(lang) 40 | } 41 | 42 | /* Copyright 2022 Spiegel 43 | * 44 | * Licensed under the Apache License, Version 2.0 (the "License"); 45 | * you may not use this file except in compliance with the License. 46 | * You may obtain a copy of the License at 47 | * 48 | * http://www.apache.org/licenses/LICENSE-2.0 49 | * 50 | * Unless required by applicable law or agreed to in writing, software 51 | * distributed under the License is distributed on an "AS IS" BASIS, 52 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 53 | * See the License for the specific language governing permissions and 54 | * limitations under the License. 55 | */ 56 | -------------------------------------------------------------------------------- /v3/metric/version_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | 7 | "github.com/goark/go-cvss/cvsserr" 8 | ) 9 | 10 | func TestVersion(t *testing.T) { 11 | testCases := []struct { 12 | v string 13 | e error 14 | n Version 15 | s string 16 | }{ 17 | {v: "CVSS", e: cvsserr.ErrInvalidVector, n: VUnknown, s: "unknown"}, 18 | {v: "3.0", e: cvsserr.ErrInvalidVector, n: VUnknown, s: "unknown"}, 19 | {v: "CV:SS:3.0", e: cvsserr.ErrInvalidVector, n: VUnknown, s: "unknown"}, 20 | {v: "CVSSv3:3.0", e: cvsserr.ErrInvalidVector, n: VUnknown, s: "unknown"}, 21 | {v: "CVSS:3.0", e: nil, n: V3_0, s: "3.0"}, 22 | {v: "CVSS:3.1", e: nil, n: V3_1, s: "3.1"}, 23 | {v: "CVSS:1.0", e: nil, n: VUnknown, s: "unknown"}, 24 | {v: "CVSS:2.0", e: nil, n: VUnknown, s: "unknown"}, 25 | } 26 | for _, tc := range testCases { 27 | n, err := GetVersion(tc.v) 28 | if !errors.Is(err, tc.e) { 29 | t.Errorf("Version %v is \"%v\", want nil.", tc.v, err) 30 | } else { 31 | if n != tc.n { 32 | t.Errorf("Version %v = \"%v\", want \"%v\".", tc.v, n, tc.n) 33 | } 34 | s := n.String() 35 | if s != tc.s { 36 | t.Errorf("Version %v = \"%v\", want \"%v\".", tc.v, s, tc.s) 37 | } 38 | } 39 | } 40 | } 41 | 42 | /* Copyright 2018-2020 Spiegel 43 | * 44 | * Licensed under the Apache License, Version 2.0 (the "License"); 45 | * you may not use this file except in compliance with the License. 46 | * You may obtain a copy of the License at 47 | * 48 | * http://www.apache.org/licenses/LICENSE-2.0 49 | * 50 | * Unless required by applicable law or agreed to in writing, software 51 | * distributed under the License is distributed on an "AS IS" BASIS, 52 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 53 | * See the License for the specific language governing permissions and 54 | * limitations under the License. 55 | */ 56 | -------------------------------------------------------------------------------- /v3/report/names/modified-user-interaction.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | muiTitleMap = langNameMap{ 10 | language.English: "Modified User Interaction", 11 | language.Japanese: "調整後のユーザ関与レベル", 12 | } 13 | muiNamesMap = map[metric.ModifiedUserInteraction]langNameMap{ 14 | metric.ModifiedUserInteractionNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.ModifiedUserInteractionRequired: { 19 | language.English: "Required", 20 | language.Japanese: "要", 21 | }, 22 | metric.ModifiedUserInteractionNone: { 23 | language.English: "None", 24 | language.Japanese: "不要", 25 | }, 26 | } 27 | ) 28 | 29 | //ModifiedUserInteraction returns string instance name for display 30 | func ModifiedUserInteraction(lang language.Tag) string { 31 | return muiTitleMap.getNameInLang(lang) 32 | } 33 | 34 | //MUIValueOf returns string name of value for display 35 | func MUIValueOf(mui metric.ModifiedUserInteraction, lang language.Tag) string { 36 | if m, ok := muiNamesMap[mui]; ok { 37 | return m.getNameInLang(lang) 38 | } 39 | return unknownValueNameMap.getNameInLang(lang) 40 | } 41 | 42 | /* Copyright 2022 Spiegel 43 | * 44 | * Licensed under the Apache License, Version 2.0 (the "License"); 45 | * you may not use this file except in compliance with the License. 46 | * You may obtain a copy of the License at 47 | * 48 | * http://www.apache.org/licenses/LICENSE-2.0 49 | * 50 | * Unless required by applicable law or agreed to in writing, software 51 | * distributed under the License is distributed on an "AS IS" BASIS, 52 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 53 | * See the License for the specific language governing permissions and 54 | * limitations under the License. 55 | */ 56 | -------------------------------------------------------------------------------- /v3/metric/example_test.go: -------------------------------------------------------------------------------- 1 | package metric_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/goark/go-cvss/v3/metric" 7 | ) 8 | 9 | func ExampleBase_Decode() { 10 | m, err := metric.NewBase().Decode("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N") //CVE-2015-8252 11 | if err != nil { 12 | return 13 | } 14 | fmt.Println("Score =", m.Score()) 15 | fmt.Println("Severity =", m.Severity()) 16 | //Output: 17 | //Score = 7.5 18 | //Severity = High 19 | } 20 | 21 | func ExampleTemporal_Decode() { 22 | m, err := metric.NewTemporal().Decode("CVSS:3.1/AV:A/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:L/E:P/RL:O/RC:U") 23 | if err != nil { 24 | return 25 | } 26 | fmt.Println("Score =", m.Score()) 27 | fmt.Println("Severity =", m.Severity()) 28 | //Output: 29 | //Score = 5.9 30 | //Severity = Medium 31 | } 32 | 33 | func ExampleEnvironmental_Decode() { 34 | m, err := metric.NewEnvironmental().Decode("CVSS:3.1/AV:A/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:L/E:P/RL:O/RC:U/CR:L/IR:M/AR:L/MAV:P/MAC:L/MPR:L/MUI:R/MS:C/MC:H/MI:H/MA:H") 35 | if err != nil { 36 | return 37 | } 38 | fmt.Println("Score =", m.Score()) 39 | fmt.Println("Severity =", m.Severity()) 40 | //Output: 41 | //Score = 5.5 42 | //Severity = Medium 43 | } 44 | 45 | /* Contributed by Florent Viel, 2020 */ 46 | /* Copyright 2018-2023 Spiegel 47 | * 48 | * Licensed under the Apache License, Version 2.0 (the "License"); 49 | * you may not use this file except in compliance with the License. 50 | * You may obtain a copy of the License at 51 | * 52 | * http://www.apache.org/licenses/LICENSE-2.0 53 | * 54 | * Unless required by applicable law or agreed to in writing, software 55 | * distributed under the License is distributed on an "AS IS" BASIS, 56 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | * See the License for the specific language governing permissions and 58 | * limitations under the License. 59 | */ 60 | -------------------------------------------------------------------------------- /v3/report/names/attack-vector.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | avTitleMap = langNameMap{ 10 | language.English: "Attack Vector", 11 | language.Japanese: "攻撃元区分", 12 | } 13 | avNamesMap = map[metric.AttackVector]langNameMap{ 14 | metric.AttackVectorPhysical: { 15 | language.English: "Physical", 16 | language.Japanese: "物理", 17 | }, 18 | metric.AttackVectorLocal: { 19 | language.English: "Local", 20 | language.Japanese: "ローカル", 21 | }, 22 | metric.AttackVectorAdjacent: { 23 | language.English: "Adjacent", 24 | language.Japanese: "隣接", 25 | }, 26 | metric.AttackVectorNetwork: { 27 | language.English: "Network", 28 | language.Japanese: "ネットワーク", 29 | }, 30 | } 31 | ) 32 | 33 | // AttackVector returns string instance name for display 34 | func AttackVector(lang language.Tag) string { 35 | return avTitleMap.getNameInLang(lang) 36 | } 37 | 38 | // AVValueOf returns string name of value for display 39 | func AVValueOf(av metric.AttackVector, lang language.Tag) string { 40 | if m, ok := avNamesMap[av]; ok { 41 | return m.getNameInLang(lang) 42 | } 43 | return unknownValueNameMap.getNameInLang(lang) 44 | } 45 | 46 | /* Copyright 2018-2023 Spiegel 47 | * 48 | * Licensed under the Apache License, Version 2.0 (the "License"); 49 | * you may not use this file except in compliance with the License. 50 | * You may obtain a copy of the License at 51 | * 52 | * http://www.apache.org/licenses/LICENSE-2.0 53 | * 54 | * Unless required by applicable law or agreed to in writing, software 55 | * distributed under the License is distributed on an "AS IS" BASIS, 56 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | * See the License for the specific language governing permissions and 58 | * limitations under the License. 59 | */ 60 | -------------------------------------------------------------------------------- /v2/metric/metrict-rc.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ReportConfidence is metric type for Temporal Metrics 4 | type ReportConfidence int 5 | 6 | // Constant of ReportConfidence result 7 | const ( 8 | ReportConfidenceInvalid ReportConfidence = iota 9 | ReportConfidenceNotDefined 10 | ReportConfidenceUnconfirmed 11 | ReportConfidenceUncorroborated 12 | ReportConfidenceConfirmed 13 | ) 14 | 15 | var reportConfidenceMap = map[ReportConfidence]string{ 16 | ReportConfidenceNotDefined: "ND", 17 | ReportConfidenceUnconfirmed: "UC", 18 | ReportConfidenceUncorroborated: "UR", 19 | ReportConfidenceConfirmed: "C", 20 | } 21 | 22 | var reportConfidenceValueMap = map[ReportConfidence]float64{ 23 | ReportConfidenceNotDefined: 1, 24 | ReportConfidenceUnconfirmed: 0.9, 25 | ReportConfidenceUncorroborated: 0.95, 26 | ReportConfidenceConfirmed: 1, 27 | } 28 | 29 | // GetReportConfidence returns result of ReportConfidence metric 30 | func GetReportConfidence(s string) ReportConfidence { 31 | for k, v := range reportConfidenceMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return ReportConfidenceInvalid 37 | } 38 | 39 | func (ai ReportConfidence) String() string { 40 | if s, ok := reportConfidenceMap[ai]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of ReportConfidence metric 47 | func (ai ReportConfidence) Value() float64 { 48 | if v, ok := reportConfidenceValueMap[ai]; ok { 49 | return v 50 | } 51 | return 1 52 | } 53 | 54 | // IsValid returns false if invalid result value of metric 55 | func (ai ReportConfidence) IsValid() bool { 56 | return ai != ReportConfidenceInvalid 57 | } 58 | 59 | // IsDefined returns false if undefined result value of metric 60 | func (ai ReportConfidence) IsDefined() bool { 61 | return ai.IsValid() && ai != ReportConfidenceNotDefined 62 | } 63 | 64 | /* Copyright 2022 luxifer */ 65 | /* Contributed by Spiegel, 2023 */ 66 | -------------------------------------------------------------------------------- /v3/metric/integrity-impact_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "testing" 4 | 5 | func TestIntegrityImpact(t *testing.T) { 6 | testCases := []struct { 7 | input string 8 | result IntegrityImpact 9 | res string 10 | value float64 11 | defined bool 12 | }{ 13 | {input: "Z", result: IntegrityImpactUnknown, res: "", value: 0.0, defined: false}, 14 | {input: "N", result: IntegrityImpactNone, res: "N", value: 0.0, defined: true}, 15 | {input: "L", result: IntegrityImpactLow, res: "L", value: 0.22, defined: true}, 16 | {input: "H", result: IntegrityImpactHigh, res: "H", value: 0.56, defined: true}, 17 | } 18 | 19 | for _, tc := range testCases { 20 | r := GetIntegrityImpact(tc.input) 21 | if r != tc.result { 22 | t.Errorf("GetIntegrityImpact(%v) = %v, want %v.", tc.input, r, tc.result) 23 | } 24 | str := r.String() 25 | if str != tc.res { 26 | t.Errorf("IntegrityImpact.String(%v) = \"%v\", want \"%v\".", tc.input, str, tc.res) 27 | } 28 | v := r.Value() 29 | if v != tc.value { 30 | t.Errorf("IntegrityImpact.Value(%v) = %v, want %v.", tc.input, v, tc.value) 31 | } 32 | if r.IsUnknown() == tc.defined { 33 | t.Errorf("IntegrityImpact.IsDefined(%v) = %v, want %v.", tc.input, r.IsUnknown(), tc.defined) 34 | } 35 | } 36 | } 37 | 38 | /* Copyright 2018-2023 Spiegel 39 | * 40 | * Licensed under the Apache License, Version 2.0 (the "License"); 41 | * you may not use this file except in compliance with the License. 42 | * You may obtain a copy of the License at 43 | * 44 | * http://www.apache.org/licenses/LICENSE-2.0 45 | * 46 | * Unless required by applicable law or agreed to in writing, software 47 | * distributed under the License is distributed on an "AS IS" BASIS, 48 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 49 | * See the License for the specific language governing permissions and 50 | * limitations under the License. 51 | */ 52 | -------------------------------------------------------------------------------- /v3/metric/report-confidence_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "testing" 4 | 5 | func TestReportConfidence(t *testing.T) { 6 | testCases := []struct { 7 | input string 8 | result ReportConfidence 9 | res string 10 | value float64 11 | defined bool 12 | }{ 13 | {input: "X", result: ReportConfidenceNotDefined, res: "X", value: 1.0, defined: true}, 14 | {input: "U", result: ReportConfidenceUnknown, res: "U", value: 0.92, defined: true}, 15 | {input: "R", result: ReportConfidenceReasonable, res: "R", value: 0.96, defined: true}, 16 | {input: "C", result: ReportConfidenceConfirmed, res: "C", value: 1.0, defined: true}, 17 | } 18 | 19 | for _, tc := range testCases { 20 | r := GetReportConfidence(tc.input) 21 | if r != tc.result { 22 | t.Errorf("GetReportConfidence(%v) = %v, want %v.", tc.input, r, tc.result) 23 | } 24 | str := r.String() 25 | if str != tc.res { 26 | t.Errorf("ReportConfidence.String(%v) = \"%v\", want \"%v\".", tc.input, str, tc.res) 27 | } 28 | v := r.Value() 29 | if v != tc.value { 30 | t.Errorf("ReportConfidence.Value(%v) = %v, want %v.", tc.input, v, tc.value) 31 | } 32 | if r.IsValid() != tc.defined { 33 | t.Errorf("ReportConfidence.IsDefined(%v) = %v, want %v.", tc.input, r.IsValid(), tc.defined) 34 | } 35 | } 36 | } 37 | 38 | /* Copyright 2020 Spiegel 39 | * 40 | * Licensed under the Apache License, Version 2.0 (the "License"); 41 | * you may not use this file except in compliance with the License. 42 | * You may obtain a copy of the License at 43 | * 44 | * http://www.apache.org/licenses/LICENSE-2.0 45 | * 46 | * Unless required by applicable law or agreed to in writing, software 47 | * distributed under the License is distributed on an "AS IS" BASIS, 48 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 49 | * See the License for the specific language governing permissions and 50 | * limitations under the License. 51 | */ 52 | -------------------------------------------------------------------------------- /v3/metric/availability-requirement.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // AvailabilityRequirement is metric type for Base Metrics 4 | type AvailabilityRequirement int 5 | 6 | // Constant of AvailabilityRequirement result 7 | const ( 8 | AvailabilityRequirementInvalid AvailabilityRequirement = iota 9 | AvailabilityRequirementNotDefined 10 | AvailabilityRequirementLow 11 | AvailabilityRequirementMedium 12 | AvailabilityRequirementHigh 13 | ) 14 | 15 | var AvailabilityRequirementMap = map[AvailabilityRequirement]string{ 16 | AvailabilityRequirementNotDefined: "X", 17 | AvailabilityRequirementLow: "L", 18 | AvailabilityRequirementMedium: "M", 19 | AvailabilityRequirementHigh: "H", 20 | } 21 | 22 | var AvailabilityRequirementValueMap = map[AvailabilityRequirement]float64{ 23 | AvailabilityRequirementNotDefined: 1, 24 | AvailabilityRequirementLow: 0.5, 25 | AvailabilityRequirementMedium: 1, 26 | AvailabilityRequirementHigh: 1.5, 27 | } 28 | 29 | // GetAvailabilityRequirement returns result of AvailabilityRequirement metric 30 | func GetAvailabilityRequirement(s string) AvailabilityRequirement { 31 | for k, v := range AvailabilityRequirementMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return AvailabilityRequirementInvalid 37 | } 38 | 39 | func (ar AvailabilityRequirement) String() string { 40 | if s, ok := AvailabilityRequirementMap[ar]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of AvailabilityRequirement metric 47 | func (ar AvailabilityRequirement) Value() float64 { 48 | if v, ok := AvailabilityRequirementValueMap[ar]; ok { 49 | return v 50 | } 51 | return 0.0 52 | } 53 | 54 | // IsDefined returns false if undefined result value of metric 55 | func (ar AvailabilityRequirement) IsValid() bool { 56 | _, ok := AvailabilityRequirementValueMap[ar] 57 | return ok 58 | } 59 | 60 | /* Copyright 2022 thejohnbrown */ 61 | /* Contributed by Spiegel, 2023 */ 62 | -------------------------------------------------------------------------------- /v2/metric/metrict-e.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // Exploitability is metric type for Temporal Metrics 4 | type Exploitability int 5 | 6 | // Constant of Exploitability result 7 | const ( 8 | ExploitabilityInvalid Exploitability = iota 9 | ExploitabilityNotDefined 10 | ExploitabilityUnproven 11 | ExploitabilityProofOfConcept 12 | ExploitabilityFunctional 13 | ExploitabilityHigh 14 | ) 15 | 16 | var exploitabilityMap = map[Exploitability]string{ 17 | ExploitabilityNotDefined: "ND", 18 | ExploitabilityUnproven: "U", 19 | ExploitabilityProofOfConcept: "POC", 20 | ExploitabilityFunctional: "F", 21 | ExploitabilityHigh: "H", 22 | } 23 | 24 | var exploitabilityValueMap = map[Exploitability]float64{ 25 | ExploitabilityNotDefined: 1, 26 | ExploitabilityUnproven: 0.85, 27 | ExploitabilityProofOfConcept: 0.9, 28 | ExploitabilityFunctional: 0.95, 29 | ExploitabilityHigh: 1, 30 | } 31 | 32 | // GetExploitability returns result of Exploitability metric 33 | func GetExploitability(s string) Exploitability { 34 | for k, v := range exploitabilityMap { 35 | if s == v { 36 | return k 37 | } 38 | } 39 | return ExploitabilityInvalid 40 | } 41 | 42 | func (ai Exploitability) String() string { 43 | if s, ok := exploitabilityMap[ai]; ok { 44 | return s 45 | } 46 | return "" 47 | } 48 | 49 | // Value returns value of Exploitability metric 50 | func (ai Exploitability) Value() float64 { 51 | if v, ok := exploitabilityValueMap[ai]; ok { 52 | return v 53 | } 54 | return 1 55 | } 56 | 57 | // IsValid returns false if invalid result value of metric 58 | func (ai Exploitability) IsValid() bool { 59 | return ai != ExploitabilityInvalid 60 | } 61 | 62 | // IsDefined returns false if undefined result value of metric 63 | func (ai Exploitability) IsDefined() bool { 64 | return ai.IsValid() && ai != ExploitabilityNotDefined 65 | } 66 | 67 | /* Copyright 2022 luxifer */ 68 | /* Contributed by Spiegel, 2023 */ 69 | -------------------------------------------------------------------------------- /v3/metric/availability-impact_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "testing" 4 | 5 | func TestAvailabilityImpact(t *testing.T) { 6 | testCases := []struct { 7 | input string 8 | result AvailabilityImpact 9 | res string 10 | value float64 11 | defined bool 12 | }{ 13 | {input: "Z", result: AvailabilityImpactUnknown, res: "", value: 0.0, defined: false}, 14 | {input: "N", result: AvailabilityImpactNone, res: "N", value: 0.0, defined: true}, 15 | {input: "L", result: AvailabilityImpactLow, res: "L", value: 0.22, defined: true}, 16 | {input: "H", result: AvailabilityImpactHigh, res: "H", value: 0.56, defined: true}, 17 | } 18 | 19 | for _, tc := range testCases { 20 | r := GetAvailabilityImpact(tc.input) 21 | if r != tc.result { 22 | t.Errorf("GetAvailabilityImpact(%v) = %v, want %v.", tc.input, r, tc.result) 23 | } 24 | str := r.String() 25 | if str != tc.res { 26 | t.Errorf("AvailabilityImpact.String(%v) = \"%v\", want \"%v\".", tc.input, str, tc.res) 27 | } 28 | v := r.Value() 29 | if v != tc.value { 30 | t.Errorf("AvailabilityImpact.Value(%v) = %v, want %v.", tc.input, v, tc.value) 31 | } 32 | if r.IsUnknown() == tc.defined { 33 | t.Errorf("AvailabilityImpact.IsDefined(%v) = %v, want %v.", tc.input, r.IsUnknown(), tc.defined) 34 | } 35 | } 36 | } 37 | 38 | /* Copyright 2018-2023 Spiegel 39 | * 40 | * Licensed under the Apache License, Version 2.0 (the "License"); 41 | * you may not use this file except in compliance with the License. 42 | * You may obtain a copy of the License at 43 | * 44 | * http://www.apache.org/licenses/LICENSE-2.0 45 | * 46 | * Unless required by applicable law or agreed to in writing, software 47 | * distributed under the License is distributed on an "AS IS" BASIS, 48 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 49 | * See the License for the specific language governing permissions and 50 | * limitations under the License. 51 | */ 52 | -------------------------------------------------------------------------------- /v3/report/names/integrity-requirement.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | irTitleMap = langNameMap{ 10 | language.English: "Integrity Requirement", 11 | language.Japanese: "完全性の要求度", 12 | } 13 | irNamesMap = map[metric.IntegrityRequirement]langNameMap{ 14 | metric.IntegrityRequirementNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.IntegrityRequirementLow: { 19 | language.English: "Low", 20 | language.Japanese: "低", 21 | }, 22 | metric.IntegrityRequirementMedium: { 23 | language.English: "Medium", 24 | language.Japanese: "中", 25 | }, 26 | metric.IntegrityRequirementHigh: { 27 | language.English: "High", 28 | language.Japanese: "高", 29 | }, 30 | } 31 | ) 32 | 33 | //IntegrityRequirement returns string instance name for display 34 | func IntegrityRequirement(lang language.Tag) string { 35 | return irTitleMap.getNameInLang(lang) 36 | } 37 | 38 | //IRValueOf returns string name of value for display 39 | func IRValueOf(ir metric.IntegrityRequirement, lang language.Tag) string { 40 | if m, ok := irNamesMap[ir]; ok { 41 | return m.getNameInLang(lang) 42 | } 43 | return unknownValueNameMap.getNameInLang(lang) 44 | } 45 | 46 | /* Copyright 2022 Spiegel 47 | * 48 | * Licensed under the Apache License, Version 2.0 (the "License"); 49 | * you may not use this file except in compliance with the License. 50 | * You may obtain a copy of the License at 51 | * 52 | * http://www.apache.org/licenses/LICENSE-2.0 53 | * 54 | * Unless required by applicable law or agreed to in writing, software 55 | * distributed under the License is distributed on an "AS IS" BASIS, 56 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | * See the License for the specific language governing permissions and 58 | * limitations under the License. 59 | */ 60 | -------------------------------------------------------------------------------- /v3/report/names/report-confidence.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | rcTitleMap = langNameMap{ 10 | language.English: "Report Confidence", 11 | language.Japanese: "脆弱性情報の信頼性", 12 | } 13 | rcNamesMap = map[metric.ReportConfidence]langNameMap{ 14 | metric.ReportConfidenceNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.ReportConfidenceUnknown: { 19 | language.English: "Unknown", 20 | language.Japanese: "未確認", 21 | }, 22 | metric.ReportConfidenceReasonable: { 23 | language.English: "Reasonable", 24 | language.Japanese: "未確証", 25 | }, 26 | metric.ReportConfidenceConfirmed: { 27 | language.English: "Confirmed", 28 | language.Japanese: "確認済", 29 | }, 30 | } 31 | ) 32 | 33 | //ReportConfidence returns string instance name for display 34 | func ReportConfidence(lang language.Tag) string { 35 | return rcTitleMap.getNameInLang(lang) 36 | } 37 | 38 | //RCValueOf returns string name of value for display 39 | func RCValueOf(rc metric.ReportConfidence, lang language.Tag) string { 40 | if m, ok := rcNamesMap[rc]; ok { 41 | return m.getNameInLang(lang) 42 | } 43 | return unknownValueNameMap.getNameInLang(lang) 44 | } 45 | 46 | /* Copyright 2020-2022 Spiegel 47 | * 48 | * Licensed under the Apache License, Version 2.0 (the "License"); 49 | * you may not use this file except in compliance with the License. 50 | * You may obtain a copy of the License at 51 | * 52 | * http://www.apache.org/licenses/LICENSE-2.0 53 | * 54 | * Unless required by applicable law or agreed to in writing, software 55 | * distributed under the License is distributed on an "AS IS" BASIS, 56 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | * See the License for the specific language governing permissions and 58 | * limitations under the License. 59 | */ 60 | -------------------------------------------------------------------------------- /v3/metric/attack-vector_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "testing" 4 | 5 | func TestAttackVector(t *testing.T) { 6 | testCases := []struct { 7 | input string 8 | result AttackVector 9 | res string 10 | value float64 11 | defined bool 12 | }{ 13 | {input: "Z", result: AttackVectorUnknown, res: "", value: 0.0, defined: false}, 14 | {input: "P", result: AttackVectorPhysical, res: "P", value: 0.20, defined: true}, 15 | {input: "L", result: AttackVectorLocal, res: "L", value: 0.55, defined: true}, 16 | {input: "A", result: AttackVectorAdjacent, res: "A", value: 0.62, defined: true}, 17 | {input: "N", result: AttackVectorNetwork, res: "N", value: 0.85, defined: true}, 18 | } 19 | 20 | for _, tc := range testCases { 21 | r := GetAttackVector(tc.input) 22 | if r != tc.result { 23 | t.Errorf("GetAttackVector(%v) = %v, want %v.", tc.input, r, tc.result) 24 | } 25 | str := r.String() 26 | if str != tc.res { 27 | t.Errorf("AttackVector.String(%v) = \"%v\", want \"%v\".", tc.input, str, tc.res) 28 | } 29 | v := r.Value() 30 | if v != tc.value { 31 | t.Errorf("AttackVector.Value(%v) = %v, want %v.", tc.input, v, tc.value) 32 | } 33 | if r.IsUnknown() == tc.defined { 34 | t.Errorf("AttackVector.IsDefined(%v) = %v, want %v.", tc.input, r.IsUnknown(), tc.defined) 35 | } 36 | } 37 | } 38 | 39 | /* Copyright 2018-2023 Spiegel 40 | * 41 | * Licensed under the Apache License, Version 2.0 (the "License"); 42 | * you may not use this file except in compliance with the License. 43 | * You may obtain a copy of the License at 44 | * 45 | * http://www.apache.org/licenses/LICENSE-2.0 46 | * 47 | * Unless required by applicable law or agreed to in writing, software 48 | * distributed under the License is distributed on an "AS IS" BASIS, 49 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 50 | * See the License for the specific language governing permissions and 51 | * limitations under the License. 52 | */ 53 | -------------------------------------------------------------------------------- /v3/report/names/availability-requirement.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | arTitleMap = langNameMap{ 10 | language.English: "Availability Requirement", 11 | language.Japanese: "可用性の要求度", 12 | } 13 | arNamesMap = map[metric.AvailabilityRequirement]langNameMap{ 14 | metric.AvailabilityRequirementNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.AvailabilityRequirementLow: { 19 | language.English: "Low", 20 | language.Japanese: "低", 21 | }, 22 | metric.AvailabilityRequirementMedium: { 23 | language.English: "Medium", 24 | language.Japanese: "中", 25 | }, 26 | metric.AvailabilityRequirementHigh: { 27 | language.English: "High", 28 | language.Japanese: "高", 29 | }, 30 | } 31 | ) 32 | 33 | //AvailabilityRequirement returns string instance name for display 34 | func AvailabilityRequirement(lang language.Tag) string { 35 | return arTitleMap.getNameInLang(lang) 36 | } 37 | 38 | //ARValueOf returns string name of value for display 39 | func ARValueOf(ar metric.AvailabilityRequirement, lang language.Tag) string { 40 | if m, ok := arNamesMap[ar]; ok { 41 | return m.getNameInLang(lang) 42 | } 43 | return unknownValueNameMap.getNameInLang(lang) 44 | } 45 | 46 | /* Copyright 2022 Spiegel 47 | * 48 | * Licensed under the Apache License, Version 2.0 (the "License"); 49 | * you may not use this file except in compliance with the License. 50 | * You may obtain a copy of the License at 51 | * 52 | * http://www.apache.org/licenses/LICENSE-2.0 53 | * 54 | * Unless required by applicable law or agreed to in writing, software 55 | * distributed under the License is distributed on an "AS IS" BASIS, 56 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | * See the License for the specific language governing permissions and 58 | * limitations under the License. 59 | */ 60 | -------------------------------------------------------------------------------- /v3/report/names/modified-integrity-impact.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | miTitleMap = langNameMap{ 10 | language.English: "Modified Integrity Impact", 11 | language.Japanese: "調整後の完全性への影響", 12 | } 13 | miNamesMap = map[metric.ModifiedIntegrityImpact]langNameMap{ 14 | metric.ModifiedIntegrityImpactNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.ModifiedIntegrityImpactNone: { 19 | language.English: "None", 20 | language.Japanese: "なし", 21 | }, 22 | metric.ModifiedIntegrityImpactLow: { 23 | language.English: "Low", 24 | language.Japanese: "低", 25 | }, 26 | metric.ModifiedIntegrityImpactHigh: { 27 | language.English: "High", 28 | language.Japanese: "高", 29 | }, 30 | } 31 | ) 32 | 33 | //ModifiedIntegrityImpact returns string instance name for display 34 | func ModifiedIntegrityImpact(lang language.Tag) string { 35 | return miTitleMap.getNameInLang(lang) 36 | } 37 | 38 | //MIValueOf returns string name of value for display 39 | func MIValueOf(i metric.ModifiedIntegrityImpact, lang language.Tag) string { 40 | if m, ok := miNamesMap[i]; ok { 41 | return m.getNameInLang(lang) 42 | } 43 | return unknownValueNameMap.getNameInLang(lang) 44 | } 45 | 46 | /* Copyright 2022 Spiegel 47 | * 48 | * Licensed under the Apache License, Version 2.0 (the "License"); 49 | * you may not use this file except in compliance with the License. 50 | * You may obtain a copy of the License at 51 | * 52 | * http://www.apache.org/licenses/LICENSE-2.0 53 | * 54 | * Unless required by applicable law or agreed to in writing, software 55 | * distributed under the License is distributed on an "AS IS" BASIS, 56 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | * See the License for the specific language governing permissions and 58 | * limitations under the License. 59 | */ 60 | -------------------------------------------------------------------------------- /v3/metric/confidentiality-impact_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "testing" 4 | 5 | func TestConfidentialityImpact(t *testing.T) { 6 | testCases := []struct { 7 | input string 8 | result ConfidentialityImpact 9 | res string 10 | value float64 11 | defined bool 12 | }{ 13 | {input: "Z", result: ConfidentialityImpactUnknown, res: "", value: 0.0, defined: false}, 14 | {input: "N", result: ConfidentialityImpactNone, res: "N", value: 0.0, defined: true}, 15 | {input: "L", result: ConfidentialityImpactLow, res: "L", value: 0.22, defined: true}, 16 | {input: "H", result: ConfidentialityImpactHigh, res: "H", value: 0.56, defined: true}, 17 | } 18 | 19 | for _, tc := range testCases { 20 | r := GetConfidentialityImpact(tc.input) 21 | if r != tc.result { 22 | t.Errorf("GetConfidentialityImpact(%v) = %v, want %v.", tc.input, r, tc.result) 23 | } 24 | str := r.String() 25 | if str != tc.res { 26 | t.Errorf("ConfidentialityImpact.String(%v) = \"%v\", want \"%v\".", tc.input, str, tc.res) 27 | } 28 | v := r.Value() 29 | if v != tc.value { 30 | t.Errorf("ConfidentialityImpact.Value(%v) = %v, want %v.", tc.input, v, tc.value) 31 | } 32 | if r.IsUnknown() == tc.defined { 33 | t.Errorf("ConfidentialityImpact.IsDefined(%v) = %v, want %v.", tc.input, r.IsUnknown(), tc.defined) 34 | } 35 | } 36 | } 37 | 38 | /* Copyright 2018-2023 Spiegel 39 | * 40 | * Licensed under the Apache License, Version 2.0 (the "License"); 41 | * you may not use this file except in compliance with the License. 42 | * You may obtain a copy of the License at 43 | * 44 | * http://www.apache.org/licenses/LICENSE-2.0 45 | * 46 | * Unless required by applicable law or agreed to in writing, software 47 | * distributed under the License is distributed on an "AS IS" BASIS, 48 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 49 | * See the License for the specific language governing permissions and 50 | * limitations under the License. 51 | */ 52 | -------------------------------------------------------------------------------- /v3/metric/exploitability_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "testing" 4 | 5 | func TestExploitability(t *testing.T) { 6 | testCases := []struct { 7 | input string 8 | result Exploitability 9 | res string 10 | value float64 11 | defined bool 12 | }{ 13 | {input: "X", result: ExploitabilityNotDefined, res: "X", value: 1.0, defined: true}, 14 | {input: "U", result: ExploitabilityUnproven, res: "U", value: 0.91, defined: true}, 15 | {input: "P", result: ExploitabilityProofOfConcept, res: "P", value: 0.94, defined: true}, 16 | {input: "F", result: ExploitabilityFunctional, res: "F", value: 0.97, defined: true}, 17 | {input: "H", result: ExploitabilityHigh, res: "H", value: 1.0, defined: true}, 18 | } 19 | 20 | for _, tc := range testCases { 21 | r := GetExploitability(tc.input) 22 | if r != tc.result { 23 | t.Errorf("GetExploitability(%v) = %v, want %v.", tc.input, r, tc.result) 24 | } 25 | str := r.String() 26 | if str != tc.res { 27 | t.Errorf("Exploitability.String(%v) = \"%v\", want \"%v\".", tc.input, str, tc.res) 28 | } 29 | v := r.Value() 30 | if v != tc.value { 31 | t.Errorf("Exploitability.Value(%v) = %v, want %v.", tc.input, v, tc.value) 32 | } 33 | if r.IsValid() != tc.defined { 34 | t.Errorf("Exploitability.IsDefined(%v) = %v, want %v.", tc.input, r.IsValid(), tc.defined) 35 | } 36 | } 37 | } 38 | 39 | /* Copyright 2020 Spiegel 40 | * 41 | * Licensed under the Apache License, Version 2.0 (the "License"); 42 | * you may not use this file except in compliance with the License. 43 | * You may obtain a copy of the License at 44 | * 45 | * http://www.apache.org/licenses/LICENSE-2.0 46 | * 47 | * Unless required by applicable law or agreed to in writing, software 48 | * distributed under the License is distributed on an "AS IS" BASIS, 49 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 50 | * See the License for the specific language governing permissions and 51 | * limitations under the License. 52 | */ 53 | -------------------------------------------------------------------------------- /v3/report/names/confidentiality-requirement.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | crTitleMap = langNameMap{ 10 | language.English: "Confidentiality Requirement", 11 | language.Japanese: "機密性の要求度", 12 | } 13 | crNamesMap = map[metric.ConfidentialityRequirement]langNameMap{ 14 | metric.ConfidentialityRequirementNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.ConfidentialityRequirementLow: { 19 | language.English: "Low", 20 | language.Japanese: "低", 21 | }, 22 | metric.ConfidentialityRequirementMedium: { 23 | language.English: "Medium", 24 | language.Japanese: "中", 25 | }, 26 | metric.ConfidentialityRequirementHigh: { 27 | language.English: "High", 28 | language.Japanese: "高", 29 | }, 30 | } 31 | ) 32 | 33 | //ConfidentialityRequirement returns string instance name for display 34 | func ConfidentialityRequirement(lang language.Tag) string { 35 | return crTitleMap.getNameInLang(lang) 36 | } 37 | 38 | //CRValueOf returns string name of value for display 39 | func CRValueOf(cr metric.ConfidentialityRequirement, lang language.Tag) string { 40 | if m, ok := crNamesMap[cr]; ok { 41 | return m.getNameInLang(lang) 42 | } 43 | return unknownValueNameMap.getNameInLang(lang) 44 | } 45 | 46 | /* Copyright 2022 Spiegel 47 | * 48 | * Licensed under the Apache License, Version 2.0 (the "License"); 49 | * you may not use this file except in compliance with the License. 50 | * You may obtain a copy of the License at 51 | * 52 | * http://www.apache.org/licenses/LICENSE-2.0 53 | * 54 | * Unless required by applicable law or agreed to in writing, software 55 | * distributed under the License is distributed on an "AS IS" BASIS, 56 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | * See the License for the specific language governing permissions and 58 | * limitations under the License. 59 | */ 60 | -------------------------------------------------------------------------------- /v3/report/names/modified-availability-impact.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | maTitleMap = langNameMap{ 10 | language.English: "Modified Availability Impact", 11 | language.Japanese: "調整後の可用性への影響", 12 | } 13 | maNamesMap = map[metric.ModifiedAvailabilityImpact]langNameMap{ 14 | metric.ModifiedAvailabilityImpactNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.ModifiedAvailabilityImpactNone: { 19 | language.English: "None", 20 | language.Japanese: "なし", 21 | }, 22 | metric.ModifiedAvailabilityImpactLow: { 23 | language.English: "Low", 24 | language.Japanese: "低", 25 | }, 26 | metric.ModifiedAvailabilityImpactHigh: { 27 | language.English: "High", 28 | language.Japanese: "高", 29 | }, 30 | } 31 | ) 32 | 33 | //ModifiedAvailabilityImpact returns string instance name for display 34 | func ModifiedAvailabilityImpact(lang language.Tag) string { 35 | return maTitleMap.getNameInLang(lang) 36 | } 37 | 38 | //MAValueOf returns string name of value for display 39 | func MAValueOf(ma metric.ModifiedAvailabilityImpact, lang language.Tag) string { 40 | if m, ok := maNamesMap[ma]; ok { 41 | return m.getNameInLang(lang) 42 | } 43 | return unknownValueNameMap.getNameInLang(lang) 44 | } 45 | 46 | /* Copyright 2022 Spiegel 47 | * 48 | * Licensed under the Apache License, Version 2.0 (the "License"); 49 | * you may not use this file except in compliance with the License. 50 | * You may obtain a copy of the License at 51 | * 52 | * http://www.apache.org/licenses/LICENSE-2.0 53 | * 54 | * Unless required by applicable law or agreed to in writing, software 55 | * distributed under the License is distributed on an "AS IS" BASIS, 56 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | * See the License for the specific language governing permissions and 58 | * limitations under the License. 59 | */ 60 | -------------------------------------------------------------------------------- /v2/metric/metrict-rl.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // RemediationLevel is metric type for Temporal Metrics 4 | type RemediationLevel int 5 | 6 | // Constant of RemediationLevel result 7 | const ( 8 | RemediationLevelInvalid RemediationLevel = iota 9 | RemediationLevelNotDefined 10 | RemediationLevelOfficialFix 11 | RemediationLevelTemporaryFix 12 | RemediationLevelWorkaround 13 | RemediationLevelUnavailable 14 | ) 15 | 16 | var remediationLevelMap = map[RemediationLevel]string{ 17 | RemediationLevelNotDefined: "ND", 18 | RemediationLevelOfficialFix: "OF", 19 | RemediationLevelTemporaryFix: "TF", 20 | RemediationLevelWorkaround: "W", 21 | RemediationLevelUnavailable: "U", 22 | } 23 | 24 | var remediationLevelValueMap = map[RemediationLevel]float64{ 25 | RemediationLevelNotDefined: 1, 26 | RemediationLevelOfficialFix: 0.87, 27 | RemediationLevelTemporaryFix: 0.9, 28 | RemediationLevelWorkaround: 0.95, 29 | RemediationLevelUnavailable: 1, 30 | } 31 | 32 | // GetRemediationLevel returns result of RemediationLevel metric 33 | func GetRemediationLevel(s string) RemediationLevel { 34 | for k, v := range remediationLevelMap { 35 | if s == v { 36 | return k 37 | } 38 | } 39 | return RemediationLevelInvalid 40 | } 41 | 42 | func (ai RemediationLevel) String() string { 43 | if s, ok := remediationLevelMap[ai]; ok { 44 | return s 45 | } 46 | return "" 47 | } 48 | 49 | // Value returns value of RemediationLevel metric 50 | func (ai RemediationLevel) Value() float64 { 51 | if v, ok := remediationLevelValueMap[ai]; ok { 52 | return v 53 | } 54 | return 1 55 | } 56 | 57 | // IsValid returns false if invalid result value of metric 58 | func (ai RemediationLevel) IsValid() bool { 59 | return ai != RemediationLevelInvalid 60 | } 61 | 62 | // IsDefined returns false if undefined result value of metric 63 | func (ai RemediationLevel) IsDefined() bool { 64 | return ai.IsValid() && ai != RemediationLevelNotDefined 65 | } 66 | 67 | /* Copyright 2022 luxifer */ 68 | /* Contributed by Spiegel, 2023 */ 69 | -------------------------------------------------------------------------------- /v3/metric/user-interaction.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // UserInteraction is metric type for Base Metrics 4 | type UserInteraction int 5 | 6 | // Constant of UserInteraction result 7 | const ( 8 | UserInteractionUnknown UserInteraction = iota 9 | UserInteractionRequired 10 | UserInteractionNone 11 | ) 12 | 13 | var userInteractionMap = map[UserInteraction]string{ 14 | UserInteractionRequired: "R", 15 | UserInteractionNone: "N", 16 | } 17 | 18 | var userInteractionValueMap = map[UserInteraction]float64{ 19 | UserInteractionRequired: 0.62, 20 | UserInteractionNone: 0.85, 21 | } 22 | 23 | // GetUserInteraction returns result of UserInteraction metric 24 | func GetUserInteraction(s string) UserInteraction { 25 | for k, v := range userInteractionMap { 26 | if s == v { 27 | return k 28 | } 29 | } 30 | return UserInteractionUnknown 31 | } 32 | 33 | func (ui UserInteraction) String() string { 34 | if s, ok := userInteractionMap[ui]; ok { 35 | return s 36 | } 37 | return "" 38 | } 39 | 40 | // Value returns value of UserInteraction metric 41 | func (ui UserInteraction) Value() float64 { 42 | if v, ok := userInteractionValueMap[ui]; ok { 43 | return v 44 | } 45 | return 0.0 46 | } 47 | 48 | // IsUnknown returns false if undefined result value of metric 49 | func (ui UserInteraction) IsUnknown() bool { 50 | return ui == UserInteractionUnknown 51 | } 52 | 53 | /* Copyright 2018-2023 Spiegel 54 | * 55 | * Licensed under the Apache License, Version 2.0 (the "License"); 56 | * you may not use this file except in compliance with the License. 57 | * You may obtain a copy of the License at 58 | * 59 | * http://www.apache.org/licenses/LICENSE-2.0 60 | * 61 | * Unless required by applicable law or agreed to in writing, software 62 | * distributed under the License is distributed on an "AS IS" BASIS, 63 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 64 | * See the License for the specific language governing permissions and 65 | * limitations under the License. 66 | */ 67 | -------------------------------------------------------------------------------- /v3/metric/modified-user-interaction.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ModifiedUserInteraction is metric type for Base Metrics 4 | type ModifiedUserInteraction int 5 | 6 | // Constant of ModifiedUserInteraction result 7 | const ( 8 | ModifiedUserInteractionInvalid ModifiedUserInteraction = iota 9 | ModifiedUserInteractionNotDefined 10 | ModifiedUserInteractionRequired 11 | ModifiedUserInteractionNone 12 | ) 13 | 14 | var ModifiedUserInteractionMap = map[ModifiedUserInteraction]string{ 15 | ModifiedUserInteractionNotDefined: "X", 16 | ModifiedUserInteractionRequired: "R", 17 | ModifiedUserInteractionNone: "N", 18 | } 19 | 20 | var ModifiedUserInteractionValueMap = map[ModifiedUserInteraction]float64{ 21 | ModifiedUserInteractionNotDefined: 0, 22 | ModifiedUserInteractionRequired: 0.62, 23 | ModifiedUserInteractionNone: 0.85, 24 | } 25 | 26 | // GetModifiedUserInteraction returns result of ModifiedUserInteraction metric 27 | func GetModifiedUserInteraction(s string) ModifiedUserInteraction { 28 | for k, v := range ModifiedUserInteractionMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return ModifiedUserInteractionInvalid 34 | } 35 | 36 | func (mui ModifiedUserInteraction) String() string { 37 | if s, ok := ModifiedUserInteractionMap[mui]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of ModifiedUserInteraction metric 44 | func (mui ModifiedUserInteraction) Value(ui UserInteraction) float64 { 45 | if mui == ModifiedUserInteractionNotDefined { 46 | if v, ok := userInteractionValueMap[ui]; ok { 47 | return v 48 | } 49 | return 0.0 50 | } else { 51 | if v, ok := ModifiedUserInteractionValueMap[mui]; ok { 52 | return v 53 | } 54 | return 0.0 55 | } 56 | } 57 | 58 | // IsDefined returns false if undefined result value of metric 59 | func (mui ModifiedUserInteraction) IsValid() bool { 60 | _, ok := ModifiedUserInteractionValueMap[mui] 61 | return ok 62 | } 63 | 64 | /* Copyright 2022 thejohnbrown */ 65 | /* Contributed by Spiegel, 2023 */ 66 | -------------------------------------------------------------------------------- /v3/report/names/modified-privileges-required.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | mprTitleMap = langNameMap{ 10 | language.English: "Modified Privileges Required", 11 | language.Japanese: "調整後の必要な特権レベル", 12 | } 13 | mprNamesMap = map[metric.ModifiedPrivilegesRequired]langNameMap{ 14 | metric.ModifiedPrivilegesRequiredNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.ModifiedPrivilegesRequiredHigh: { 19 | language.English: "High", 20 | language.Japanese: "高", 21 | }, 22 | metric.ModifiedPrivilegesRequiredLow: { 23 | language.English: "Low", 24 | language.Japanese: "低", 25 | }, 26 | metric.ModifiedPrivilegesRequiredNone: { 27 | language.English: "None", 28 | language.Japanese: "不要", 29 | }, 30 | } 31 | ) 32 | 33 | //ModifiedPrivilegesRequired returns string instance name for display 34 | func ModifiedPrivilegesRequired(lang language.Tag) string { 35 | return mprTitleMap.getNameInLang(lang) 36 | } 37 | 38 | //MPRValueOf returns string name of value for display 39 | func MPRValueOf(mpr metric.ModifiedPrivilegesRequired, lang language.Tag) string { 40 | if m, ok := mprNamesMap[mpr]; ok { 41 | return m.getNameInLang(lang) 42 | } 43 | return unknownValueNameMap.getNameInLang(lang) 44 | } 45 | 46 | /* Copyright 2022 Spiegel 47 | * 48 | * Licensed under the Apache License, Version 2.0 (the "License"); 49 | * you may not use this file except in compliance with the License. 50 | * You may obtain a copy of the License at 51 | * 52 | * http://www.apache.org/licenses/LICENSE-2.0 53 | * 54 | * Unless required by applicable law or agreed to in writing, software 55 | * distributed under the License is distributed on an "AS IS" BASIS, 56 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | * See the License for the specific language governing permissions and 58 | * limitations under the License. 59 | */ 60 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | name: "CodeQL" 7 | 8 | on: 9 | push: 10 | branches: [master] 11 | pull_request: 12 | # The branches below must be a subset of the branches above 13 | branches: [master] 14 | schedule: 15 | - cron: '0 20 * * 0' 16 | 17 | jobs: 18 | CodeQL-Build: 19 | # CodeQL runs on ubuntu-latest, windows-latest, and macos-latest 20 | runs-on: ubuntu-latest 21 | 22 | permissions: 23 | # required for all workflows 24 | security-events: write 25 | 26 | # only required for workflows in private repositories 27 | actions: read 28 | contents: read 29 | 30 | steps: 31 | - name: Checkout repository 32 | uses: actions/checkout@v3 33 | 34 | # Initializes the CodeQL tools for scanning. 35 | - name: Initialize CodeQL 36 | uses: github/codeql-action/init@v2 37 | # Override language selection by uncommenting this and choosing your languages 38 | with: 39 | languages: go 40 | 41 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 42 | # If this step fails, then you should remove it and run the build manually (see below). 43 | - name: Autobuild 44 | uses: github/codeql-action/autobuild@v2 45 | 46 | # ℹ️ Command-line programs to run using the OS shell. 47 | # 📚 https://git.io/JvXDl 48 | 49 | # ✏️ If the Autobuild fails above, remove it and uncomment the following 50 | # three lines and modify them (or add more) to build your code if your 51 | # project uses a compiled language 52 | 53 | #- run: | 54 | # make bootstrap 55 | # make release 56 | 57 | - name: Perform CodeQL Analysis 58 | uses: github/codeql-action/analyze@v2 59 | -------------------------------------------------------------------------------- /v3/metric/remediation-level_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "testing" 4 | 5 | func TestRemediationLevel(t *testing.T) { 6 | testCases := []struct { 7 | input string 8 | result RemediationLevel 9 | res string 10 | value float64 11 | defined bool 12 | }{ 13 | {input: "X", result: RemediationLevelNotDefined, res: "X", value: 1.0, defined: true}, 14 | {input: "O", result: RemediationLevelOfficialFix, res: "O", value: 0.95, defined: true}, 15 | {input: "T", result: RemediationLevelTemporaryFix, res: "T", value: 0.96, defined: true}, 16 | {input: "W", result: RemediationLevelWorkaround, res: "W", value: 0.97, defined: true}, 17 | {input: "U", result: RemediationLevelUnavailable, res: "U", value: 1.0, defined: true}, 18 | } 19 | 20 | for _, tc := range testCases { 21 | r := GetRemediationLevel(tc.input) 22 | if r != tc.result { 23 | t.Errorf("GetExploitability(%v) = %v, want %v.", tc.input, r, tc.result) 24 | } 25 | str := r.String() 26 | if str != tc.res { 27 | t.Errorf("RemediationLevel.String(%v) = \"%v\", want \"%v\".", tc.input, str, tc.res) 28 | } 29 | v := r.Value() 30 | if v != tc.value { 31 | t.Errorf("RemediationLevel.Value(%v) = %v, want %v.", tc.input, v, tc.value) 32 | } 33 | if r.IsValid() != tc.defined { 34 | t.Errorf("RemediationLevel.IsDefined(%v) = %v, want %v.", tc.input, r.IsValid(), tc.defined) 35 | } 36 | } 37 | } 38 | 39 | /* Copyright 2020 Spiegel 40 | * 41 | * Licensed under the Apache License, Version 2.0 (the "License"); 42 | * you may not use this file except in compliance with the License. 43 | * You may obtain a copy of the License at 44 | * 45 | * http://www.apache.org/licenses/LICENSE-2.0 46 | * 47 | * Unless required by applicable law or agreed to in writing, software 48 | * distributed under the License is distributed on an "AS IS" BASIS, 49 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 50 | * See the License for the specific language governing permissions and 51 | * limitations under the License. 52 | */ 53 | -------------------------------------------------------------------------------- /v3/report/names/modified-confidentiality-impact.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | mcTileMap = langNameMap{ 10 | language.English: "Modified Confidentiality Impact", 11 | language.Japanese: "調整後の機密性への影響", 12 | } 13 | mcNamesMap = map[metric.ModifiedConfidentialityImpact]langNameMap{ 14 | metric.ModifiedConfidentialityImpactNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.ModifiedConfidentialityImpactNone: { 19 | language.English: "None", 20 | language.Japanese: "なし", 21 | }, 22 | metric.ModifiedConfidentialityImpactLow: { 23 | language.English: "Low", 24 | language.Japanese: "低", 25 | }, 26 | metric.ModifiedConfidentialityImpactHigh: { 27 | language.English: "High", 28 | language.Japanese: "高", 29 | }, 30 | } 31 | ) 32 | 33 | //ModifiedConfidentialityImpact returns string instance name for display 34 | func ModifiedConfidentialityImpact(lang language.Tag) string { 35 | return mcTileMap.getNameInLang(lang) 36 | } 37 | 38 | //MCValueOf returns string name of value for display 39 | func MCValueOf(mc metric.ModifiedConfidentialityImpact, lang language.Tag) string { 40 | if m, ok := mcNamesMap[mc]; ok { 41 | return m.getNameInLang(lang) 42 | } 43 | return unknownValueNameMap.getNameInLang(lang) 44 | } 45 | 46 | /* Copyright 2022 Spiegel 47 | * 48 | * Licensed under the Apache License, Version 2.0 (the "License"); 49 | * you may not use this file except in compliance with the License. 50 | * You may obtain a copy of the License at 51 | * 52 | * http://www.apache.org/licenses/LICENSE-2.0 53 | * 54 | * Unless required by applicable law or agreed to in writing, software 55 | * distributed under the License is distributed on an "AS IS" BASIS, 56 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | * See the License for the specific language governing permissions and 58 | * limitations under the License. 59 | */ 60 | -------------------------------------------------------------------------------- /v3/metric/confidentiality-requirement.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ConfidentialityRequirement is metric type for Base Metrics 4 | type ConfidentialityRequirement int 5 | 6 | // Constant of ConfidentialityRequirement result 7 | const ( 8 | ConfidentialityRequirementInvalid ConfidentialityRequirement = iota 9 | ConfidentialityRequirementNotDefined 10 | ConfidentialityRequirementLow 11 | ConfidentialityRequirementMedium 12 | ConfidentialityRequirementHigh 13 | ) 14 | 15 | var ConfidentialityRequirementMap = map[ConfidentialityRequirement]string{ 16 | ConfidentialityRequirementNotDefined: "X", 17 | ConfidentialityRequirementLow: "L", 18 | ConfidentialityRequirementMedium: "M", 19 | ConfidentialityRequirementHigh: "H", 20 | } 21 | 22 | var ConfidentialityRequirementValueMap = map[ConfidentialityRequirement]float64{ 23 | ConfidentialityRequirementNotDefined: 1, 24 | ConfidentialityRequirementLow: 0.5, 25 | ConfidentialityRequirementMedium: 1, 26 | ConfidentialityRequirementHigh: 1.5, 27 | } 28 | 29 | // GetConfidentialityRequirement returns result of ConfidentalityRequirement metric 30 | func GetConfidentialityRequirement(s string) ConfidentialityRequirement { 31 | for k, v := range ConfidentialityRequirementMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return ConfidentialityRequirementInvalid 37 | } 38 | 39 | func (cr ConfidentialityRequirement) String() string { 40 | if s, ok := ConfidentialityRequirementMap[cr]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of ConfidentialityRequirement metric 47 | func (cr ConfidentialityRequirement) Value() float64 { 48 | if v, ok := ConfidentialityRequirementValueMap[cr]; ok { 49 | return v 50 | } 51 | return 0.0 52 | } 53 | 54 | // IsDefined returns false if undefined result value of metric 55 | func (cr ConfidentialityRequirement) IsValid() bool { 56 | _, ok := ConfidentialityRequirementValueMap[cr] 57 | return ok 58 | } 59 | 60 | /* Copyright 2022 thejohnbrown */ 61 | /* Contributed by Spiegel, 2023 */ 62 | -------------------------------------------------------------------------------- /v3/metric/modified-attack-complexity.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ModifiedAttackComplexity is metric type for Base Metrics 4 | type ModifiedAttackComplexity int 5 | 6 | // Constant of ModifiedAttackComplexity result 7 | const ( 8 | ModifiedAttackComplexityInvalid ModifiedAttackComplexity = iota 9 | ModifiedAttackComplexityNotDefined 10 | ModifiedAttackComplexityHigh 11 | ModifiedAttackComplexityLow 12 | ) 13 | 14 | var ModifiedAttackComplexityMap = map[ModifiedAttackComplexity]string{ 15 | ModifiedAttackComplexityNotDefined: "X", 16 | ModifiedAttackComplexityHigh: "H", 17 | ModifiedAttackComplexityLow: "L", 18 | } 19 | 20 | var ModifiedAttackComplexityValueMap = map[ModifiedAttackComplexity]float64{ 21 | ModifiedAttackComplexityNotDefined: 0, 22 | ModifiedAttackComplexityHigh: 0.44, 23 | ModifiedAttackComplexityLow: 0.77, 24 | } 25 | 26 | // GetModifiedAttackComplexity returns result of ModifiedAttackComplexity metric 27 | func GetModifiedAttackComplexity(s string) ModifiedAttackComplexity { 28 | for k, v := range ModifiedAttackComplexityMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return ModifiedAttackComplexityInvalid 34 | } 35 | 36 | func (mac ModifiedAttackComplexity) String() string { 37 | if s, ok := ModifiedAttackComplexityMap[mac]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of ModifiedAttackComplexity metric 44 | func (mac ModifiedAttackComplexity) Value(ac AttackComplexity) float64 { 45 | if mac == ModifiedAttackComplexityNotDefined { 46 | if v, ok := attackComplexityValueMap[ac]; ok { 47 | return v 48 | } 49 | return 0.0 50 | } else { 51 | if v, ok := ModifiedAttackComplexityValueMap[mac]; ok { 52 | return v 53 | } 54 | return 0.0 55 | } 56 | } 57 | 58 | // IsDefined returns false if undefined result value of metric 59 | func (mac ModifiedAttackComplexity) IsValid() bool { 60 | _, ok := ModifiedAttackComplexityValueMap[mac] 61 | return ok 62 | } 63 | 64 | /* Copyright 2022 thejohnbrown */ 65 | /* Contributed by Spiegel, 2023 */ 66 | -------------------------------------------------------------------------------- /v3/report/names/exploitability.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | eTitleMap = langNameMap{ 10 | language.English: "Exploit Code Maturity", 11 | language.Japanese: "攻撃される可能性", 12 | } 13 | eNamesMap = map[metric.Exploitability]langNameMap{ 14 | metric.ExploitabilityNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.ExploitabilityUnproven: { 19 | language.English: "Unproven", 20 | language.Japanese: "未実証", 21 | }, 22 | metric.ExploitabilityProofOfConcept: { 23 | language.English: "Proof-of-Concept", 24 | language.Japanese: "実証可能", 25 | }, 26 | metric.ExploitabilityFunctional: { 27 | language.English: "Functional", 28 | language.Japanese: "攻撃可能", 29 | }, 30 | metric.ExploitabilityHigh: { 31 | language.English: "High", 32 | language.Japanese: "容易に攻撃可能", 33 | }, 34 | } 35 | ) 36 | 37 | //Exploitability returns string instance name for display 38 | func Exploitability(lang language.Tag) string { 39 | return eTitleMap.getNameInLang(lang) 40 | } 41 | 42 | //EValueOf returns string name of value for display 43 | func EValueOf(e metric.Exploitability, lang language.Tag) string { 44 | if m, ok := eNamesMap[e]; ok { 45 | return m.getNameInLang(lang) 46 | } 47 | return unknownValueNameMap.getNameInLang(lang) 48 | } 49 | 50 | /* Copyright 2020-2022 Spiegel 51 | * 52 | * Licensed under the Apache License, Version 2.0 (the "License"); 53 | * you may not use this file except in compliance with the License. 54 | * You may obtain a copy of the License at 55 | * 56 | * http://www.apache.org/licenses/LICENSE-2.0 57 | * 58 | * Unless required by applicable law or agreed to in writing, software 59 | * distributed under the License is distributed on an "AS IS" BASIS, 60 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 61 | * See the License for the specific language governing permissions and 62 | * limitations under the License. 63 | */ 64 | -------------------------------------------------------------------------------- /v3/report/names/severity.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | severityTitleMap = langNameMap{ 10 | language.English: "Severity", 11 | language.Japanese: "深刻度", 12 | } 13 | severityNamesMap = map[metric.Severity]langNameMap{ 14 | metric.SeverityNone: { 15 | language.English: metric.SeverityNone.String(), 16 | language.Japanese: "なし", 17 | }, 18 | metric.SeverityLow: { 19 | language.English: metric.SeverityLow.String(), 20 | language.Japanese: "注意", 21 | }, 22 | metric.SeverityMedium: { 23 | language.English: metric.SeverityMedium.String(), 24 | language.Japanese: "警告", 25 | }, 26 | metric.SeverityHigh: { 27 | language.English: metric.SeverityHigh.String(), 28 | language.Japanese: "重要", 29 | }, 30 | metric.SeverityCritical: { 31 | language.English: metric.SeverityCritical.String(), 32 | language.Japanese: "緊急", 33 | }, 34 | } 35 | ) 36 | 37 | //Severity returns string of Severity 38 | func Severity(lang language.Tag) string { 39 | return severityTitleMap.getNameInLang(lang) 40 | } 41 | 42 | //SeverityValueOf returns string name of value for display 43 | func SeverityValueOf(sv metric.Severity, lang language.Tag) string { 44 | if m, ok := severityNamesMap[sv]; ok { 45 | return m.getNameInLang(lang) 46 | } 47 | return unknownValueNameMap.getNameInLang(lang) 48 | } 49 | 50 | /* Copyright 2018-2022 Spiegel 51 | * 52 | * Licensed under the Apache License, Version 2.0 (the "License"); 53 | * you may not use this file except in compliance with the License. 54 | * You may obtain a copy of the License at 55 | * 56 | * http://www.apache.org/licenses/LICENSE-2.0 57 | * 58 | * Unless required by applicable law or agreed to in writing, software 59 | * distributed under the License is distributed on an "AS IS" BASIS, 60 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 61 | * See the License for the specific language governing permissions and 62 | * limitations under the License. 63 | */ 64 | -------------------------------------------------------------------------------- /v3/metric/integrity-impact.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // IntegrityImpact is metric type for Base Metrics 4 | type IntegrityImpact int 5 | 6 | // Constant of IntegrityImpact result 7 | const ( 8 | IntegrityImpactUnknown IntegrityImpact = iota 9 | IntegrityImpactNone 10 | IntegrityImpactLow 11 | IntegrityImpactHigh 12 | ) 13 | 14 | var integrityImpactMap = map[IntegrityImpact]string{ 15 | IntegrityImpactNone: "N", 16 | IntegrityImpactLow: "L", 17 | IntegrityImpactHigh: "H", 18 | } 19 | 20 | var integrityImpactValueMap = map[IntegrityImpact]float64{ 21 | IntegrityImpactNone: 0.00, 22 | IntegrityImpactLow: 0.22, 23 | IntegrityImpactHigh: 0.56, 24 | } 25 | 26 | // GetIntegrityImpact returns result of IntegrityImpact metric 27 | func GetIntegrityImpact(s string) IntegrityImpact { 28 | for k, v := range integrityImpactMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return IntegrityImpactUnknown 34 | } 35 | 36 | func (ii IntegrityImpact) String() string { 37 | if s, ok := integrityImpactMap[ii]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of IntegrityImpact metric 44 | func (ii IntegrityImpact) Value() float64 { 45 | if v, ok := integrityImpactValueMap[ii]; ok { 46 | return v 47 | } 48 | return 0.0 49 | } 50 | 51 | // IsUnKnown returns false if undefined result value of metric 52 | func (ii IntegrityImpact) IsUnknown() bool { 53 | return ii == IntegrityImpactUnknown 54 | } 55 | 56 | /* Copyright 2018-2023 Spiegel 57 | * 58 | * Licensed under the Apache License, Version 2.0 (the "License"); 59 | * you may not use this file except in compliance with the License. 60 | * You may obtain a copy of the License at 61 | * 62 | * http://www.apache.org/licenses/LICENSE-2.0 63 | * 64 | * Unless required by applicable law or agreed to in writing, software 65 | * distributed under the License is distributed on an "AS IS" BASIS, 66 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 67 | * See the License for the specific language governing permissions and 68 | * limitations under the License. 69 | */ 70 | -------------------------------------------------------------------------------- /v3/report/names/remediation-level.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | rlTitleMap = langNameMap{ 10 | language.English: "Remediation Level", 11 | language.Japanese: "利用可能な対策のレベル", 12 | } 13 | rlNamesMap = map[metric.RemediationLevel]langNameMap{ 14 | metric.RemediationLevelNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.RemediationLevelOfficialFix: { 19 | language.English: "Official Fix", 20 | language.Japanese: "正式", 21 | }, 22 | metric.RemediationLevelTemporaryFix: { 23 | language.English: "Temporary Fix", 24 | language.Japanese: "暫定", 25 | }, 26 | metric.RemediationLevelWorkaround: { 27 | language.English: "Workaround", 28 | language.Japanese: "非公式", 29 | }, 30 | metric.RemediationLevelUnavailable: { 31 | language.English: "Unavailable", 32 | language.Japanese: "なし", 33 | }, 34 | } 35 | ) 36 | 37 | //RemediationLevel returns string instance name for display 38 | func RemediationLevel(lang language.Tag) string { 39 | return rlTitleMap.getNameInLang(lang) 40 | } 41 | 42 | //RLValueOf returns string name of value for display 43 | func RLValueOf(rl metric.RemediationLevel, lang language.Tag) string { 44 | if m, ok := rlNamesMap[rl]; ok { 45 | return m.getNameInLang(lang) 46 | } 47 | return unknownValueNameMap.getNameInLang(lang) 48 | } 49 | 50 | /* Copyright 2020-2022 Spiegel 51 | * 52 | * Licensed under the Apache License, Version 2.0 (the "License"); 53 | * you may not use this file except in compliance with the License. 54 | * You may obtain a copy of the License at 55 | * 56 | * http://www.apache.org/licenses/LICENSE-2.0 57 | * 58 | * Unless required by applicable law or agreed to in writing, software 59 | * distributed under the License is distributed on an "AS IS" BASIS, 60 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 61 | * See the License for the specific language governing permissions and 62 | * limitations under the License. 63 | */ 64 | -------------------------------------------------------------------------------- /v3/report/names/modified-attack-vector.go: -------------------------------------------------------------------------------- 1 | package names 2 | 3 | import ( 4 | "github.com/goark/go-cvss/v3/metric" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | var ( 9 | mavTitleMap = langNameMap{ 10 | language.English: "Modified Attack Vector", 11 | language.Japanese: "調整後の攻撃元区分", 12 | } 13 | mavNamesMap = map[metric.ModifiedAttackVector]langNameMap{ 14 | metric.ModifiedAttackVectorNotDefined: { 15 | language.English: "Not Defined", 16 | language.Japanese: "未評価", 17 | }, 18 | metric.ModifiedAttackVectorPhysical: { 19 | language.English: "Physical", 20 | language.Japanese: "物理", 21 | }, 22 | metric.ModifiedAttackVectorLocal: { 23 | language.English: "Local", 24 | language.Japanese: "ローカル", 25 | }, 26 | metric.ModifiedAttackVectorAdjacent: { 27 | language.English: "Adjacent", 28 | language.Japanese: "隣接", 29 | }, 30 | metric.ModifiedAttackVectorNetwork: { 31 | language.English: "Network", 32 | language.Japanese: "ネットワーク", 33 | }, 34 | } 35 | ) 36 | 37 | //ModifiedAttackVector returns string instance name for display 38 | func ModifiedAttackVector(lang language.Tag) string { 39 | return mavTitleMap.getNameInLang(lang) 40 | } 41 | 42 | //MAVValueOf returns string name of value for display 43 | func MAVValueOf(mav metric.ModifiedAttackVector, lang language.Tag) string { 44 | if m, ok := mavNamesMap[mav]; ok { 45 | return m.getNameInLang(lang) 46 | } 47 | return unknownValueNameMap.getNameInLang(lang) 48 | } 49 | 50 | /* Copyright 2022 Spiegel 51 | * 52 | * Licensed under the Apache License, Version 2.0 (the "License"); 53 | * you may not use this file except in compliance with the License. 54 | * You may obtain a copy of the License at 55 | * 56 | * http://www.apache.org/licenses/LICENSE-2.0 57 | * 58 | * Unless required by applicable law or agreed to in writing, software 59 | * distributed under the License is distributed on an "AS IS" BASIS, 60 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 61 | * See the License for the specific language governing permissions and 62 | * limitations under the License. 63 | */ 64 | -------------------------------------------------------------------------------- /v3/metric/attack-vector.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // AttackVector is metric type for Base Metrics 4 | type AttackVector int 5 | 6 | // Constant of AttackVector result 7 | const ( 8 | AttackVectorUnknown AttackVector = iota 9 | AttackVectorPhysical 10 | AttackVectorLocal 11 | AttackVectorAdjacent 12 | AttackVectorNetwork 13 | ) 14 | 15 | var attackVectorMap = map[AttackVector]string{ 16 | AttackVectorPhysical: "P", 17 | AttackVectorLocal: "L", 18 | AttackVectorAdjacent: "A", 19 | AttackVectorNetwork: "N", 20 | } 21 | 22 | var attackVectorValueMap = map[AttackVector]float64{ 23 | AttackVectorPhysical: 0.20, 24 | AttackVectorLocal: 0.55, 25 | AttackVectorAdjacent: 0.62, 26 | AttackVectorNetwork: 0.85, 27 | } 28 | 29 | // GetAttackVector returns result of AttackVector metric 30 | func GetAttackVector(s string) AttackVector { 31 | for k, v := range attackVectorMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return AttackVectorUnknown 37 | } 38 | 39 | func (av AttackVector) String() string { 40 | if s, ok := attackVectorMap[av]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of AttackVector metric 47 | func (av AttackVector) Value() float64 { 48 | if v, ok := attackVectorValueMap[av]; ok { 49 | return v 50 | } 51 | return 0.0 52 | } 53 | 54 | // IsUnknown returns false if unknouwn result value of metric 55 | func (av AttackVector) IsUnknown() bool { 56 | return av == AttackVectorUnknown 57 | } 58 | 59 | /* Copyright 2018-2023 Spiegel 60 | * 61 | * Licensed under the Apache License, Version 2.0 (the "License"); 62 | * you may not use this file except in compliance with the License. 63 | * You may obtain a copy of the License at 64 | * 65 | * http://www.apache.org/licenses/LICENSE-2.0 66 | * 67 | * Unless required by applicable law or agreed to in writing, software 68 | * distributed under the License is distributed on an "AS IS" BASIS, 69 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 70 | * See the License for the specific language governing permissions and 71 | * limitations under the License. 72 | */ 73 | -------------------------------------------------------------------------------- /v3/metric/attack-complexity.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // AttackComplexity is metric type for Base Metrics 4 | type AttackComplexity int 5 | 6 | // Constant of AttackComplexity result 7 | const ( 8 | AttackComplexityUnknown AttackComplexity = iota 9 | // AttackComplexityNotDefined 10 | AttackComplexityHigh 11 | AttackComplexityLow 12 | ) 13 | 14 | var attackComplexityMap = map[AttackComplexity]string{ 15 | // AttackComplexityNotDefined: "X", 16 | AttackComplexityHigh: "H", 17 | AttackComplexityLow: "L", 18 | } 19 | 20 | var attackComplexityValueMap = map[AttackComplexity]float64{ 21 | // AttackComplexityNotDefined: 0, 22 | AttackComplexityHigh: 0.44, 23 | AttackComplexityLow: 0.77, 24 | } 25 | 26 | // GetAttackComplexity returns result of AttackComplexity metric 27 | func GetAttackComplexity(s string) AttackComplexity { 28 | for k, v := range attackComplexityMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return AttackComplexityUnknown 34 | } 35 | 36 | func (ac AttackComplexity) String() string { 37 | if s, ok := attackComplexityMap[ac]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of AttackComplexity metric 44 | func (ac AttackComplexity) Value() float64 { 45 | if v, ok := attackComplexityValueMap[ac]; ok { 46 | return v 47 | } 48 | return 0.0 49 | } 50 | 51 | // IsUnknown returns false if unknown result value of metric 52 | func (ac AttackComplexity) IsUnknown() bool { 53 | return ac == AttackComplexityUnknown 54 | } 55 | 56 | /* Copyright 2018-2023 Spiegel 57 | * 58 | * Licensed under the Apache License, Version 2.0 (the "License"); 59 | * you may not use this file except in compliance with the License. 60 | * You may obtain a copy of the License at 61 | * 62 | * http://www.apache.org/licenses/LICENSE-2.0 63 | * 64 | * Unless required by applicable law or agreed to in writing, software 65 | * distributed under the License is distributed on an "AS IS" BASIS, 66 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 67 | * See the License for the specific language governing permissions and 68 | * limitations under the License. 69 | */ 70 | -------------------------------------------------------------------------------- /v3/metric/modified-attack-vector.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ModifiedAttackVector is metric type for Base Metrics 4 | type ModifiedAttackVector int 5 | 6 | // Constant of ModifiedAttackVector result 7 | const ( 8 | ModifiedAttackVectorInvalid ModifiedAttackVector = iota 9 | ModifiedAttackVectorNotDefined 10 | ModifiedAttackVectorPhysical 11 | ModifiedAttackVectorLocal 12 | ModifiedAttackVectorAdjacent 13 | ModifiedAttackVectorNetwork 14 | ) 15 | 16 | var ModifiedAttackVectorMap = map[ModifiedAttackVector]string{ 17 | ModifiedAttackVectorNotDefined: "X", 18 | ModifiedAttackVectorPhysical: "P", 19 | ModifiedAttackVectorLocal: "L", 20 | ModifiedAttackVectorAdjacent: "A", 21 | ModifiedAttackVectorNetwork: "N", 22 | } 23 | 24 | var ModifiedAttackVectorValueMap = map[ModifiedAttackVector]float64{ 25 | ModifiedAttackVectorNotDefined: 0, 26 | ModifiedAttackVectorPhysical: 0.20, 27 | ModifiedAttackVectorLocal: 0.55, 28 | ModifiedAttackVectorAdjacent: 0.62, 29 | ModifiedAttackVectorNetwork: 0.85, 30 | } 31 | 32 | // GetModifiedAttackVector returns result of ModifiedAttackVector metric 33 | func GetModifiedAttackVector(s string) ModifiedAttackVector { 34 | for k, v := range ModifiedAttackVectorMap { 35 | if s == v { 36 | return k 37 | } 38 | } 39 | return ModifiedAttackVectorInvalid 40 | } 41 | 42 | func (mav ModifiedAttackVector) String() string { 43 | if s, ok := ModifiedAttackVectorMap[mav]; ok { 44 | return s 45 | } 46 | return "" 47 | } 48 | 49 | // Value returns value of ModifiedAttackVector metric 50 | func (mav ModifiedAttackVector) Value(av AttackVector) float64 { 51 | if mav == ModifiedAttackVectorNotDefined { 52 | if v, ok := attackVectorValueMap[av]; ok { 53 | return v 54 | } 55 | return 0.0 56 | } else { 57 | if v, ok := ModifiedAttackVectorValueMap[mav]; ok { 58 | return v 59 | } 60 | return 0.0 61 | } 62 | } 63 | 64 | // IsDefined returns false if undefined result value of metric 65 | func (mav ModifiedAttackVector) IsValid() bool { 66 | _, ok := ModifiedAttackVectorValueMap[mav] 67 | return ok 68 | } 69 | 70 | /* Copyright 2022 thejohnbrown */ 71 | /* Contributed by Spiegel, 2023 */ 72 | -------------------------------------------------------------------------------- /v3/metric/modified-integrity.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ModifiedIntegrityImpact is metric type for Base Metrics 4 | type ModifiedIntegrityImpact int 5 | 6 | // Constant of ModifiedIntegrityImpact result 7 | const ( 8 | ModifiedIntegrityImpactInvalid ModifiedIntegrityImpact = iota 9 | ModifiedIntegrityImpactNotDefined 10 | ModifiedIntegrityImpactNone 11 | ModifiedIntegrityImpactLow 12 | ModifiedIntegrityImpactHigh 13 | ) 14 | 15 | var ModifiedIntegrityImpactMap = map[ModifiedIntegrityImpact]string{ 16 | ModifiedIntegrityImpactNotDefined: "X", 17 | ModifiedIntegrityImpactNone: "N", 18 | ModifiedIntegrityImpactLow: "L", 19 | ModifiedIntegrityImpactHigh: "H", 20 | } 21 | 22 | var ModifiedIntegrityImpactValueMap = map[ModifiedIntegrityImpact]float64{ 23 | ModifiedIntegrityImpactNotDefined: 0.00, 24 | ModifiedIntegrityImpactNone: 0.00, 25 | ModifiedIntegrityImpactLow: 0.22, 26 | ModifiedIntegrityImpactHigh: 0.56, 27 | } 28 | 29 | // GetModifiedIntegrityImpact returns result of ModifiedIntegrityImpact metric 30 | func GetModifiedIntegrityImpact(s string) ModifiedIntegrityImpact { 31 | for k, v := range ModifiedIntegrityImpactMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return ModifiedIntegrityImpactInvalid 37 | } 38 | 39 | func (mii ModifiedIntegrityImpact) String() string { 40 | if s, ok := ModifiedIntegrityImpactMap[mii]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of ModifiedIntegrityImpact metric 47 | func (mii ModifiedIntegrityImpact) Value(ii IntegrityImpact) float64 { 48 | if mii.String() == ModifiedAttackComplexityNotDefined.String() { 49 | if v, ok := integrityImpactValueMap[ii]; ok { 50 | return v 51 | } 52 | return 0.0 53 | } else { 54 | if v, ok := ModifiedIntegrityImpactValueMap[mii]; ok { 55 | return v 56 | } 57 | return 0.0 58 | } 59 | } 60 | 61 | // IsDefined returns false if undefined result value of metric 62 | func (mii ModifiedIntegrityImpact) IsValid() bool { 63 | _, ok := ModifiedIntegrityImpactValueMap[mii] 64 | return ok 65 | } 66 | 67 | /* Copyright 2022 thejohnbrown */ 68 | /* Contributed by Spiegel, 2023 */ 69 | -------------------------------------------------------------------------------- /v3/metric/availability-impact.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // AvailabilityImpact is metric type for Base Metrics 4 | type AvailabilityImpact int 5 | 6 | // Constant of AvailabilityImpact result 7 | const ( 8 | AvailabilityImpactUnknown AvailabilityImpact = iota 9 | AvailabilityImpactNone 10 | AvailabilityImpactLow 11 | AvailabilityImpactHigh 12 | ) 13 | 14 | var availabilityImpactMap = map[AvailabilityImpact]string{ 15 | AvailabilityImpactNone: "N", 16 | AvailabilityImpactLow: "L", 17 | AvailabilityImpactHigh: "H", 18 | } 19 | 20 | var availabilityImpactValueMap = map[AvailabilityImpact]float64{ 21 | AvailabilityImpactNone: 0.00, 22 | AvailabilityImpactLow: 0.22, 23 | AvailabilityImpactHigh: 0.56, 24 | } 25 | 26 | // GetAvailabilityImpact returns result of AvailabilityImpact metric 27 | func GetAvailabilityImpact(s string) AvailabilityImpact { 28 | for k, v := range availabilityImpactMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return AvailabilityImpactUnknown 34 | } 35 | 36 | func (ai AvailabilityImpact) String() string { 37 | if s, ok := availabilityImpactMap[ai]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of AvailabilityImpact metric 44 | func (ai AvailabilityImpact) Value() float64 { 45 | if v, ok := availabilityImpactValueMap[ai]; ok { 46 | return v 47 | } 48 | return 0.0 49 | } 50 | 51 | // IsUnknown returns false if undefined result value of metric 52 | func (ai AvailabilityImpact) IsUnknown() bool { 53 | return ai == AvailabilityImpactUnknown 54 | } 55 | 56 | /* Copyright 2018-2023 Spiegel 57 | * 58 | * Licensed under the Apache License, Version 2.0 (the "License"); 59 | * you may not use this file except in compliance with the License. 60 | * You may obtain a copy of the License at 61 | * 62 | * http://www.apache.org/licenses/LICENSE-2.0 63 | * 64 | * Unless required by applicable law or agreed to in writing, software 65 | * distributed under the License is distributed on an "AS IS" BASIS, 66 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 67 | * See the License for the specific language governing permissions and 68 | * limitations under the License. 69 | */ 70 | -------------------------------------------------------------------------------- /v3/metric/modified-availability.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ModifiedAvailabilityImpact is metric type for Base Metrics 4 | type ModifiedAvailabilityImpact int 5 | 6 | // Constant of ModifiedAvailabilityImpact result 7 | const ( 8 | ModifiedAvailabilityInvalid ModifiedAvailabilityImpact = iota 9 | ModifiedAvailabilityImpactNotDefined 10 | ModifiedAvailabilityImpactNone 11 | ModifiedAvailabilityImpactLow 12 | ModifiedAvailabilityImpactHigh 13 | ) 14 | 15 | var ModifiedAvailabilityImpactMap = map[ModifiedAvailabilityImpact]string{ 16 | ModifiedAvailabilityImpactNotDefined: "X", 17 | ModifiedAvailabilityImpactNone: "N", 18 | ModifiedAvailabilityImpactLow: "L", 19 | ModifiedAvailabilityImpactHigh: "H", 20 | } 21 | 22 | var ModifiedAvailabilityImpactValueMap = map[ModifiedAvailabilityImpact]float64{ 23 | ModifiedAvailabilityImpactNotDefined: 0.00, 24 | ModifiedAvailabilityImpactNone: 0.00, 25 | ModifiedAvailabilityImpactLow: 0.22, 26 | ModifiedAvailabilityImpactHigh: 0.56, 27 | } 28 | 29 | // GetModifiedAvailabilityImpact returns result of ModifiedAvailabilityImpact metric 30 | func GetModifiedAvailabilityImpact(s string) ModifiedAvailabilityImpact { 31 | for k, v := range ModifiedAvailabilityImpactMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return ModifiedAvailabilityInvalid 37 | } 38 | 39 | func (mai ModifiedAvailabilityImpact) String() string { 40 | if s, ok := ModifiedAvailabilityImpactMap[mai]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of ModifiedAvailabilityImpact metric 47 | func (mai ModifiedAvailabilityImpact) Value(ai AvailabilityImpact) float64 { 48 | if mai.String() == ModifiedAvailabilityImpactNotDefined.String() { 49 | if v, ok := availabilityImpactValueMap[ai]; ok { 50 | return v 51 | } 52 | return 0.0 53 | } else { 54 | if v, ok := ModifiedAvailabilityImpactValueMap[mai]; ok { 55 | return v 56 | } 57 | return 0.0 58 | } 59 | } 60 | 61 | // IsDefined returns false if undefined result value of metric 62 | func (mai ModifiedAvailabilityImpact) IsValid() bool { 63 | _, ok := ModifiedAvailabilityImpactValueMap[mai] 64 | return ok 65 | } 66 | 67 | /* Copyright 2022 thejohnbrown */ 68 | /* Contributed by Spiegel, 2023 */ 69 | -------------------------------------------------------------------------------- /v3/metric/confidentiality-impact.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ConfidentialityImpact is metric type for Base Metrics 4 | type ConfidentialityImpact int 5 | 6 | // Constant of ConfidentialityImpact result 7 | const ( 8 | ConfidentialityImpactUnknown ConfidentialityImpact = iota 9 | ConfidentialityImpactNone 10 | ConfidentialityImpactLow 11 | ConfidentialityImpactHigh 12 | ) 13 | 14 | var confidentialityImpactMap = map[ConfidentialityImpact]string{ 15 | ConfidentialityImpactNone: "N", 16 | ConfidentialityImpactLow: "L", 17 | ConfidentialityImpactHigh: "H", 18 | } 19 | 20 | var confidentialityImpactValueMap = map[ConfidentialityImpact]float64{ 21 | ConfidentialityImpactNone: 0.00, 22 | ConfidentialityImpactLow: 0.22, 23 | ConfidentialityImpactHigh: 0.56, 24 | } 25 | 26 | // GetConfidentialityImpact returns result of ConfidentialityImpact metric 27 | func GetConfidentialityImpact(s string) ConfidentialityImpact { 28 | for k, v := range confidentialityImpactMap { 29 | if s == v { 30 | return k 31 | } 32 | } 33 | return ConfidentialityImpactUnknown 34 | } 35 | 36 | func (ci ConfidentialityImpact) String() string { 37 | if s, ok := confidentialityImpactMap[ci]; ok { 38 | return s 39 | } 40 | return "" 41 | } 42 | 43 | // Value returns value of ConfidentialityImpact metric 44 | func (ci ConfidentialityImpact) Value() float64 { 45 | if v, ok := confidentialityImpactValueMap[ci]; ok { 46 | return v 47 | } 48 | return 0.0 49 | } 50 | 51 | // IsUnknown returns false if undefined result value of metric 52 | func (ci ConfidentialityImpact) IsUnknown() bool { 53 | return ci == ConfidentialityImpactUnknown 54 | } 55 | 56 | /* Copyright 2018-2023 Spiegel 57 | * 58 | * Licensed under the Apache License, Version 2.0 (the "License"); 59 | * you may not use this file except in compliance with the License. 60 | * You may obtain a copy of the License at 61 | * 62 | * http://www.apache.org/licenses/LICENSE-2.0 63 | * 64 | * Unless required by applicable law or agreed to in writing, software 65 | * distributed under the License is distributed on an "AS IS" BASIS, 66 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 67 | * See the License for the specific language governing permissions and 68 | * limitations under the License. 69 | */ 70 | -------------------------------------------------------------------------------- /v3/metric/modified-confidentiality.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ModifiedConfidentialityImpact is metric type for Base Metrics 4 | type ModifiedConfidentialityImpact int 5 | 6 | // Constant of ModifiedConfidentialityImpact result 7 | const ( 8 | ModifiedConfidentialityImpactInvalid ModifiedConfidentialityImpact = iota 9 | ModifiedConfidentialityImpactNotDefined 10 | ModifiedConfidentialityImpactNone 11 | ModifiedConfidentialityImpactLow 12 | ModifiedConfidentialityImpactHigh 13 | ) 14 | 15 | var ModifiedConfidentialityImpactMap = map[ModifiedConfidentialityImpact]string{ 16 | ModifiedConfidentialityImpactNotDefined: "X", 17 | ModifiedConfidentialityImpactNone: "N", 18 | ModifiedConfidentialityImpactLow: "L", 19 | ModifiedConfidentialityImpactHigh: "H", 20 | } 21 | 22 | var ModifiedConfidentialityImpactValueMap = map[ModifiedConfidentialityImpact]float64{ 23 | ModifiedConfidentialityImpactNotDefined: 0.00, 24 | ModifiedConfidentialityImpactNone: 0.00, 25 | ModifiedConfidentialityImpactLow: 0.22, 26 | ModifiedConfidentialityImpactHigh: 0.56, 27 | } 28 | 29 | // GetModifiedConfidentialityImpact returns result of ModifiedConfidentialityImpact metric 30 | func GetModifiedConfidentialityImpact(s string) ModifiedConfidentialityImpact { 31 | for k, v := range ModifiedConfidentialityImpactMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return ModifiedConfidentialityImpactInvalid 37 | } 38 | 39 | func (mci ModifiedConfidentialityImpact) String() string { 40 | if s, ok := ModifiedConfidentialityImpactMap[mci]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of ModifiedConfidentialityImpact metric 47 | func (mci ModifiedConfidentialityImpact) Value(ci ConfidentialityImpact) float64 { 48 | if mci.String() == ModifiedAttackComplexityNotDefined.String() { 49 | if v, ok := confidentialityImpactValueMap[ci]; ok { 50 | return v 51 | } 52 | return 0.0 53 | } else { 54 | if v, ok := ModifiedConfidentialityImpactValueMap[mci]; ok { 55 | return v 56 | } 57 | return 0.0 58 | } 59 | 60 | } 61 | 62 | // IsDefined returns false if undefined result value of metric 63 | func (mci ModifiedConfidentialityImpact) IsValid() bool { 64 | _, ok := ModifiedConfidentialityImpactValueMap[mci] 65 | return ok 66 | } 67 | 68 | /* Copyright 2022 thejohnbrown */ 69 | /* Contributed by Spiegel, 2023 */ 70 | -------------------------------------------------------------------------------- /v3/metric/privileges-required_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import "testing" 4 | 5 | func TestPrivilegesRequired(t *testing.T) { 6 | testCases := []struct { 7 | input string 8 | result PrivilegesRequired 9 | sc Scope 10 | res string 11 | value float64 12 | defined bool 13 | }{ 14 | {input: "Z", result: PrivilegesRequiredUnknown, sc: ScopeUnchanged, res: "", value: 0.0, defined: false}, 15 | {input: "Z", result: PrivilegesRequiredUnknown, sc: ScopeChanged, res: "", value: 0.0, defined: false}, 16 | {input: "H", result: PrivilegesRequiredHigh, sc: ScopeUnchanged, res: "H", value: 0.27, defined: true}, 17 | {input: "H", result: PrivilegesRequiredHigh, sc: ScopeChanged, res: "H", value: 0.50, defined: true}, 18 | {input: "L", result: PrivilegesRequiredLow, sc: ScopeUnchanged, res: "L", value: 0.62, defined: true}, 19 | {input: "L", result: PrivilegesRequiredLow, sc: ScopeChanged, res: "L", value: 0.68, defined: true}, 20 | {input: "N", result: PrivilegesRequiredNone, sc: ScopeUnchanged, res: "N", value: 0.85, defined: true}, 21 | {input: "N", result: PrivilegesRequiredNone, sc: ScopeChanged, res: "N", value: 0.85, defined: true}, 22 | } 23 | 24 | for _, tc := range testCases { 25 | r := GetPrivilegesRequired(tc.input) 26 | if r != tc.result { 27 | t.Errorf("GetPrivilegesRequired(%v) = %v, want %v.", tc.input, r, tc.result) 28 | } 29 | str := r.String() 30 | if str != tc.res { 31 | t.Errorf("PrivilegesRequired.String(%v) = \"%v\", want \"%v\".", tc.input, str, tc.res) 32 | } 33 | v := r.Value(tc.sc) 34 | if v != tc.value { 35 | t.Errorf("PrivilegesRequired.Value(%v, %v) = %v, want %v.", tc.input, tc.sc, v, tc.value) 36 | } 37 | if r.IsUnknown() == tc.defined { 38 | t.Errorf("PrivilegesRequired.IsDefined(%v) = %v, want %v.", tc.input, r.IsUnknown(), tc.defined) 39 | } 40 | } 41 | } 42 | 43 | /* Copyright 2018-2020 Spiegel 44 | * 45 | * Licensed under the Apache License, Version 2.0 (the "License"); 46 | * you may not use this file except in compliance with the License. 47 | * You may obtain a copy of the License at 48 | * 49 | * http://www.apache.org/licenses/LICENSE-2.0 50 | * 51 | * Unless required by applicable law or agreed to in writing, software 52 | * distributed under the License is distributed on an "AS IS" BASIS, 53 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 54 | * See the License for the specific language governing permissions and 55 | * limitations under the License. 56 | */ 57 | -------------------------------------------------------------------------------- /v2/metric/metrice-ir.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // IntegrityRequirement is metric type for Temporal Metrics 4 | type IntegrityRequirement int 5 | 6 | // Constant of IntegrityRequirement result 7 | const ( 8 | IntegrityRequirementInvalid IntegrityRequirement = iota 9 | IntegrityRequirementNotDefined 10 | IntegrityRequirementLow 11 | IntegrityRequirementMedium 12 | IntegrityRequirementHigh 13 | ) 14 | 15 | var integrityRequirementMap = map[IntegrityRequirement]string{ 16 | IntegrityRequirementNotDefined: "ND", 17 | IntegrityRequirementLow: "L", 18 | IntegrityRequirementMedium: "M", 19 | IntegrityRequirementHigh: "H", 20 | } 21 | 22 | var integrityRequirementValueMap = map[IntegrityRequirement]float64{ 23 | IntegrityRequirementNotDefined: 1.0, 24 | IntegrityRequirementLow: 0.5, 25 | IntegrityRequirementMedium: 1.0, 26 | IntegrityRequirementHigh: 1.51, 27 | } 28 | 29 | // GetIntegrityRequirement returns result of IntegrityRequirement metric 30 | func GetIntegrityRequirement(s string) IntegrityRequirement { 31 | for k, v := range integrityRequirementMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return IntegrityRequirementInvalid 37 | } 38 | 39 | func (ir IntegrityRequirement) String() string { 40 | if s, ok := integrityRequirementMap[ir]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of IntegrityRequirement metric 47 | func (ir IntegrityRequirement) Value() float64 { 48 | if v, ok := integrityRequirementValueMap[ir]; ok { 49 | return v 50 | } 51 | return 0 52 | } 53 | 54 | // IsValid returns false if invalid result value of metric 55 | func (ir IntegrityRequirement) IsValid() bool { 56 | return ir != IntegrityRequirementInvalid 57 | } 58 | 59 | // IsDefined returns false if undefined result value of metric 60 | func (ir IntegrityRequirement) IsDefined() bool { 61 | return ir.IsValid() && ir != IntegrityRequirementNotDefined 62 | } 63 | 64 | /* Copyright 2023 Spiegel 65 | * 66 | * Licensed under the Apache License, Version 2.0 (the "License"); 67 | * you may not use this file except in compliance with the License. 68 | * You may obtain a copy of the License at 69 | * 70 | * http://www.apache.org/licenses/LICENSE-2.0 71 | * 72 | * Unless required by applicable law or agreed to in writing, software 73 | * distributed under the License is distributed on an "AS IS" BASIS, 74 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 75 | * See the License for the specific language governing permissions and 76 | * limitations under the License. 77 | */ 78 | -------------------------------------------------------------------------------- /v3/metric/privileges-required.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // PrivilegesRequired is metric type for Base Metrics 4 | type PrivilegesRequired int 5 | 6 | // Constant of PrivilegesRequired result 7 | const ( 8 | PrivilegesRequiredUnknown PrivilegesRequired = iota 9 | PrivilegesRequiredHigh 10 | PrivilegesRequiredLow 11 | PrivilegesRequiredNone 12 | ) 13 | 14 | var privilegesRequiredMap = map[PrivilegesRequired]string{ 15 | PrivilegesRequiredHigh: "H", 16 | PrivilegesRequiredLow: "L", 17 | PrivilegesRequiredNone: "N", 18 | } 19 | 20 | var privilegesRequiredWithUValueMap = map[PrivilegesRequired]float64{ 21 | PrivilegesRequiredHigh: 0.27, 22 | PrivilegesRequiredLow: 0.62, 23 | PrivilegesRequiredNone: 0.85, 24 | } 25 | var privilegesRequiredWithCValueMap = map[PrivilegesRequired]float64{ 26 | PrivilegesRequiredHigh: 0.50, 27 | PrivilegesRequiredLow: 0.68, 28 | PrivilegesRequiredNone: 0.85, 29 | } 30 | 31 | // GetPrivilegesRequired returns result of PrivilegesRequired metric 32 | func GetPrivilegesRequired(s string) PrivilegesRequired { 33 | for k, v := range privilegesRequiredMap { 34 | if s == v { 35 | return k 36 | } 37 | } 38 | return PrivilegesRequiredUnknown 39 | } 40 | 41 | func (pr PrivilegesRequired) String() string { 42 | if s, ok := privilegesRequiredMap[pr]; ok { 43 | return s 44 | } 45 | return "" 46 | } 47 | 48 | // Value returns value of PrivilegesRequired metric 49 | func (pr PrivilegesRequired) Value(s Scope) float64 { 50 | var m map[PrivilegesRequired]float64 51 | switch s { 52 | case ScopeUnchanged: 53 | m = privilegesRequiredWithUValueMap 54 | case ScopeChanged: 55 | m = privilegesRequiredWithCValueMap 56 | default: 57 | return 0.0 58 | } 59 | if v, ok := m[pr]; ok { 60 | return v 61 | } 62 | return 0.0 63 | } 64 | 65 | // IsUnknown returns false if undefined result value of metric 66 | func (pr PrivilegesRequired) IsUnknown() bool { 67 | return pr == PrivilegesRequiredUnknown 68 | } 69 | 70 | /* Copyright 2018-2023 Spiegel 71 | * 72 | * Licensed under the Apache License, Version 2.0 (the "License"); 73 | * you may not use this file except in compliance with the License. 74 | * You may obtain a copy of the License at 75 | * 76 | * http://www.apache.org/licenses/LICENSE-2.0 77 | * 78 | * Unless required by applicable law or agreed to in writing, software 79 | * distributed under the License is distributed on an "AS IS" BASIS, 80 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 81 | * See the License for the specific language governing permissions and 82 | * limitations under the License. 83 | */ 84 | -------------------------------------------------------------------------------- /v2/metric/metrice-td.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // TargetDistribution is metric type for Temporal Metrics 4 | type TargetDistribution int 5 | 6 | // Constant of TargetDistribution result 7 | const ( 8 | TargetDistributionInvalid TargetDistribution = iota 9 | TargetDistributionNotDefined 10 | TargetDistributionNon 11 | TargetDistributionLow 12 | TargetDistributionMedium 13 | TargetDistributionHigh 14 | ) 15 | 16 | var targetDistributionMap = map[TargetDistribution]string{ 17 | TargetDistributionNotDefined: "ND", 18 | TargetDistributionNon: "N", 19 | TargetDistributionLow: "L", 20 | TargetDistributionMedium: "M", 21 | TargetDistributionHigh: "H", 22 | } 23 | 24 | var targetDistributionValueMap = map[TargetDistribution]float64{ 25 | TargetDistributionNotDefined: 1.00, 26 | TargetDistributionNon: 0, 27 | TargetDistributionLow: 0.25, 28 | TargetDistributionMedium: 0.75, 29 | TargetDistributionHigh: 1.00, 30 | } 31 | 32 | // GetTargetDistribution returns result of TargetDistribution metric 33 | func GetTargetDistribution(s string) TargetDistribution { 34 | for k, v := range targetDistributionMap { 35 | if s == v { 36 | return k 37 | } 38 | } 39 | return TargetDistributionInvalid 40 | } 41 | 42 | func (td TargetDistribution) String() string { 43 | if s, ok := targetDistributionMap[td]; ok { 44 | return s 45 | } 46 | return "" 47 | } 48 | 49 | // Value returns value of TargetDistribution metric 50 | func (td TargetDistribution) Value() float64 { 51 | if v, ok := targetDistributionValueMap[td]; ok { 52 | return v 53 | } 54 | return 0 55 | } 56 | 57 | // IsValid returns false if invalid result value of metric 58 | func (td TargetDistribution) IsValid() bool { 59 | return td != TargetDistributionInvalid 60 | } 61 | 62 | // IsDefined returns false if undefined result value of metric 63 | func (td TargetDistribution) IsDefined() bool { 64 | return td.IsValid() && td != TargetDistributionNotDefined 65 | } 66 | 67 | /* Copyright 2023 Spiegel 68 | * 69 | * Licensed under the Apache License, Version 2.0 (the "License"); 70 | * you may not use this file except in compliance with the License. 71 | * You may obtain a copy of the License at 72 | * 73 | * http://www.apache.org/licenses/LICENSE-2.0 74 | * 75 | * Unless required by applicable law or agreed to in writing, software 76 | * distributed under the License is distributed on an "AS IS" BASIS, 77 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 78 | * See the License for the specific language governing permissions and 79 | * limitations under the License. 80 | */ 81 | -------------------------------------------------------------------------------- /v2/metric/metrice-ar.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // AvailabilityRequirement is metric type for Temporal Metrics 4 | type AvailabilityRequirement int 5 | 6 | // Constant of AvailabilityRequirement result 7 | const ( 8 | AvailabilityRequirementInvalid AvailabilityRequirement = iota 9 | AvailabilityRequirementNotDefined 10 | AvailabilityRequirementLow 11 | AvailabilityRequirementMedium 12 | AvailabilityRequirementHigh 13 | ) 14 | 15 | var availabilityRequirementMap = map[AvailabilityRequirement]string{ 16 | AvailabilityRequirementNotDefined: "ND", 17 | AvailabilityRequirementLow: "L", 18 | AvailabilityRequirementMedium: "M", 19 | AvailabilityRequirementHigh: "H", 20 | } 21 | 22 | var availabilityRequirementValueMap = map[AvailabilityRequirement]float64{ 23 | AvailabilityRequirementNotDefined: 1.0, 24 | AvailabilityRequirementLow: 0.5, 25 | AvailabilityRequirementMedium: 1.0, 26 | AvailabilityRequirementHigh: 1.51, 27 | } 28 | 29 | // GetAvailabilityRequirement returns result of AvailabilityRequirement metric 30 | func GetAvailabilityRequirement(s string) AvailabilityRequirement { 31 | for k, v := range availabilityRequirementMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return AvailabilityRequirementInvalid 37 | } 38 | 39 | func (ar AvailabilityRequirement) String() string { 40 | if s, ok := availabilityRequirementMap[ar]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of AvailabilityRequirement metric 47 | func (ar AvailabilityRequirement) Value() float64 { 48 | if v, ok := availabilityRequirementValueMap[ar]; ok { 49 | return v 50 | } 51 | return 0 52 | } 53 | 54 | // IsValid returns false if invalid result value of metric 55 | func (ar AvailabilityRequirement) IsValid() bool { 56 | return ar != AvailabilityRequirementInvalid 57 | } 58 | 59 | // IsDefined returns false if undefined result value of metric 60 | func (ar AvailabilityRequirement) IsDefined() bool { 61 | return ar.IsValid() && ar != AvailabilityRequirementNotDefined 62 | } 63 | 64 | /* Copyright 2023 Spiegel 65 | * 66 | * Licensed under the Apache License, Version 2.0 (the "License"); 67 | * you may not use this file except in compliance with the License. 68 | * You may obtain a copy of the License at 69 | * 70 | * http://www.apache.org/licenses/LICENSE-2.0 71 | * 72 | * Unless required by applicable law or agreed to in writing, software 73 | * distributed under the License is distributed on an "AS IS" BASIS, 74 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 75 | * See the License for the specific language governing permissions and 76 | * limitations under the License. 77 | */ 78 | -------------------------------------------------------------------------------- /v3/metric/modified-privileges-required.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ModifiedPrivilegesRequired is metric type for Base Metrics 4 | type ModifiedPrivilegesRequired int 5 | 6 | // Constant of ModifiedPrivilegesRequired result 7 | const ( 8 | ModifiedPrivilegesRequiredInvalid ModifiedPrivilegesRequired = iota 9 | ModifiedPrivilegesRequiredNotDefined 10 | ModifiedPrivilegesRequiredHigh 11 | ModifiedPrivilegesRequiredLow 12 | ModifiedPrivilegesRequiredNone 13 | ) 14 | 15 | var ModifiedPrivilegesRequiredMap = map[ModifiedPrivilegesRequired]string{ 16 | ModifiedPrivilegesRequiredNotDefined: "X", 17 | ModifiedPrivilegesRequiredHigh: "H", 18 | ModifiedPrivilegesRequiredLow: "L", 19 | ModifiedPrivilegesRequiredNone: "N", 20 | } 21 | 22 | var ModifiedPrivilegesRequiredWithUValueMap = map[ModifiedPrivilegesRequired]float64{ 23 | ModifiedPrivilegesRequiredNotDefined: 0, 24 | ModifiedPrivilegesRequiredHigh: 0.27, 25 | ModifiedPrivilegesRequiredLow: 0.62, 26 | ModifiedPrivilegesRequiredNone: 0.85, 27 | } 28 | var ModifiedPrivilegesRequiredWithCValueMap = map[ModifiedPrivilegesRequired]float64{ 29 | ModifiedPrivilegesRequiredNotDefined: 0, 30 | ModifiedPrivilegesRequiredHigh: 0.50, 31 | ModifiedPrivilegesRequiredLow: 0.68, 32 | ModifiedPrivilegesRequiredNone: 0.85, 33 | } 34 | 35 | // GetModifiedPrivilegesRequired returns result of ModifiedPrivilegesRequired metric 36 | func GetModifiedPrivilegesRequired(s string) ModifiedPrivilegesRequired { 37 | for k, v := range ModifiedPrivilegesRequiredMap { 38 | if s == v { 39 | return k 40 | } 41 | } 42 | return ModifiedPrivilegesRequiredInvalid 43 | } 44 | 45 | func (mpr ModifiedPrivilegesRequired) String() string { 46 | if s, ok := ModifiedPrivilegesRequiredMap[mpr]; ok { 47 | return s 48 | } 49 | return "" 50 | } 51 | 52 | // Value returns value of ModifiedPrivilegesRequired metric 53 | func (mpr ModifiedPrivilegesRequired) Value(ms ModifiedScope, s Scope, pr PrivilegesRequired) float64 { 54 | if mpr == ModifiedPrivilegesRequiredNotDefined { 55 | if ms.IsChanged(s) { 56 | s = ScopeChanged 57 | } else { 58 | s = ScopeUnchanged 59 | } 60 | return pr.Value(s) 61 | } else { 62 | var m map[ModifiedPrivilegesRequired]float64 63 | if ms.IsChanged(s) { 64 | m = ModifiedPrivilegesRequiredWithCValueMap 65 | } else { 66 | m = ModifiedPrivilegesRequiredWithUValueMap 67 | } 68 | if v, ok := m[mpr]; ok { 69 | return v 70 | } 71 | } 72 | return 0.0 73 | } 74 | 75 | // IsDefined returns false if undefined result value of metric 76 | func (mpr ModifiedPrivilegesRequired) IsValid() bool { 77 | _, ok := ModifiedPrivilegesRequiredWithCValueMap[mpr] 78 | return ok 79 | } 80 | 81 | /* Copyright 2022 thejohnbrown */ 82 | /* Contributed by Spiegel, 2023 */ 83 | -------------------------------------------------------------------------------- /v2/metric/metrice-cr.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // ConfidentialityRequirement is metric type for Temporal Metrics 4 | type ConfidentialityRequirement int 5 | 6 | // Constant of ConfidentialityRequirement result 7 | const ( 8 | ConfidentialityRequirementInvalid ConfidentialityRequirement = iota 9 | ConfidentialityRequirementNotDefined 10 | ConfidentialityRequirementLow 11 | ConfidentialityRequirementMedium 12 | ConfidentialityRequirementHigh 13 | ) 14 | 15 | var confidentialityRequirementMap = map[ConfidentialityRequirement]string{ 16 | ConfidentialityRequirementNotDefined: "ND", 17 | ConfidentialityRequirementLow: "L", 18 | ConfidentialityRequirementMedium: "M", 19 | ConfidentialityRequirementHigh: "H", 20 | } 21 | 22 | var confidentialityRequirementValueMap = map[ConfidentialityRequirement]float64{ 23 | ConfidentialityRequirementNotDefined: 1.0, 24 | ConfidentialityRequirementLow: 0.5, 25 | ConfidentialityRequirementMedium: 1.0, 26 | ConfidentialityRequirementHigh: 1.51, 27 | } 28 | 29 | // GetConfidentialityRequirement returns result of ConfidentialityRequirement metric 30 | func GetConfidentialityRequirement(s string) ConfidentialityRequirement { 31 | for k, v := range confidentialityRequirementMap { 32 | if s == v { 33 | return k 34 | } 35 | } 36 | return ConfidentialityRequirementInvalid 37 | } 38 | 39 | func (cr ConfidentialityRequirement) String() string { 40 | if s, ok := confidentialityRequirementMap[cr]; ok { 41 | return s 42 | } 43 | return "" 44 | } 45 | 46 | // Value returns value of ConfidentialityRequirement metric 47 | func (cr ConfidentialityRequirement) Value() float64 { 48 | if v, ok := confidentialityRequirementValueMap[cr]; ok { 49 | return v 50 | } 51 | return 0 52 | } 53 | 54 | // IsValid returns false if invalid result value of metric 55 | func (cr ConfidentialityRequirement) IsValid() bool { 56 | return cr != ConfidentialityRequirementInvalid 57 | } 58 | 59 | // IsDefined returns false if undefined result value of metric 60 | func (cr ConfidentialityRequirement) IsDefined() bool { 61 | return cr.IsValid() && cr != ConfidentialityRequirementNotDefined 62 | } 63 | 64 | /* Copyright 2023 Spiegel 65 | * 66 | * Licensed under the Apache License, Version 2.0 (the "License"); 67 | * you may not use this file except in compliance with the License. 68 | * You may obtain a copy of the License at 69 | * 70 | * http://www.apache.org/licenses/LICENSE-2.0 71 | * 72 | * Unless required by applicable law or agreed to in writing, software 73 | * distributed under the License is distributed on an "AS IS" BASIS, 74 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 75 | * See the License for the specific language governing permissions and 76 | * limitations under the License. 77 | */ 78 | -------------------------------------------------------------------------------- /v2/metric/metrice-cdp.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | // CollateralDamagePotential is metric type for Temporal Metrics 4 | type CollateralDamagePotential int 5 | 6 | // Constant of CollateralDamagePotential result 7 | const ( 8 | CollateralDamagePotentialInvalid CollateralDamagePotential = iota 9 | CollateralDamagePotentialNotDefined 10 | CollateralDamagePotentialNon 11 | CollateralDamagePotentialLow 12 | CollateralDamagePotentialLowMedium 13 | CollateralDamagePotentialMediumHigh 14 | CollateralDamagePotentialHigh 15 | ) 16 | 17 | var collateralDamagePotentialMap = map[CollateralDamagePotential]string{ 18 | CollateralDamagePotentialNotDefined: "ND", 19 | CollateralDamagePotentialNon: "N", 20 | CollateralDamagePotentialLow: "L", 21 | CollateralDamagePotentialLowMedium: "LM", 22 | CollateralDamagePotentialMediumHigh: "MH", 23 | CollateralDamagePotentialHigh: "H", 24 | } 25 | 26 | var collateralDamagePotentialValueMap = map[CollateralDamagePotential]float64{ 27 | CollateralDamagePotentialNotDefined: 0, 28 | CollateralDamagePotentialNon: 0, 29 | CollateralDamagePotentialLow: 0.1, 30 | CollateralDamagePotentialLowMedium: 0.3, 31 | CollateralDamagePotentialMediumHigh: 0.4, 32 | CollateralDamagePotentialHigh: 0.5, 33 | } 34 | 35 | // GetCollateralDamagePotential returns result of CollateralDamagePotential metric 36 | func GetCollateralDamagePotential(s string) CollateralDamagePotential { 37 | for k, v := range collateralDamagePotentialMap { 38 | if s == v { 39 | return k 40 | } 41 | } 42 | return CollateralDamagePotentialInvalid 43 | } 44 | 45 | func (cdp CollateralDamagePotential) String() string { 46 | if s, ok := collateralDamagePotentialMap[cdp]; ok { 47 | return s 48 | } 49 | return "" 50 | } 51 | 52 | // Value returns value of CollateralDamagePotential metric 53 | func (cdp CollateralDamagePotential) Value() float64 { 54 | if v, ok := collateralDamagePotentialValueMap[cdp]; ok { 55 | return v 56 | } 57 | return 0 58 | } 59 | 60 | // IsValid returns false if invalid result value of metric 61 | func (cdp CollateralDamagePotential) IsValid() bool { 62 | return cdp != CollateralDamagePotentialInvalid 63 | } 64 | 65 | // IsDefined returns false if undefined result value of metric 66 | func (cdp CollateralDamagePotential) IsDefined() bool { 67 | return cdp.IsValid() && cdp != CollateralDamagePotentialNotDefined 68 | } 69 | 70 | /* Copyright 2023 Spiegel 71 | * 72 | * Licensed under the Apache License, Version 2.0 (the "License"); 73 | * you may not use this file except in compliance with the License. 74 | * You may obtain a copy of the License at 75 | * 76 | * http://www.apache.org/licenses/LICENSE-2.0 77 | * 78 | * Unless required by applicable law or agreed to in writing, software 79 | * distributed under the License is distributed on an "AS IS" BASIS, 80 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 81 | * See the License for the specific language governing permissions and 82 | * limitations under the License. 83 | */ 84 | -------------------------------------------------------------------------------- /v3/report/report-temporal.go: -------------------------------------------------------------------------------- 1 | package report 2 | 3 | import ( 4 | "io" 5 | "strconv" 6 | 7 | "github.com/goark/errs" 8 | "github.com/goark/go-cvss/cvsserr" 9 | "github.com/goark/go-cvss/v3/metric" 10 | "github.com/goark/go-cvss/v3/report/names" 11 | ) 12 | 13 | //CVSSReport is dataset for CVSS report 14 | type TemporalReport struct { 15 | *BaseReport //Report of Base metrics 16 | Vector string //CVSS vector string 17 | TemporalMetrics, TemporalMetricValue string //titles 18 | EName, EValue string //Exploitability 19 | RLName, RLValue string //RemediationLevel 20 | RCName, RCValue string //ReportConfidence 21 | TemporalScore string //Temporal Score 22 | SeverityName, SeverityValue string //Severity 23 | } 24 | 25 | //NewtBase function reterns new CVSSReport instance 26 | func NewTemporal(temporal *metric.Temporal, os ...ReportOptionsFunc) *TemporalReport { 27 | opts := newOptions(os...) 28 | vec, _ := temporal.Encode() 29 | return &TemporalReport{ 30 | BaseReport: NewBase(temporal.BaseMetrics(), os...), 31 | Vector: vec, 32 | TemporalMetrics: names.TemporalMetrics(opts.lang), 33 | TemporalMetricValue: names.TemporalMetricsValueOf(opts.lang), 34 | EName: names.Exploitability(opts.lang), 35 | EValue: names.EValueOf(temporal.E, opts.lang), 36 | RLName: names.RemediationLevel(opts.lang), 37 | RLValue: names.RLValueOf(temporal.RL, opts.lang), 38 | RCName: names.ReportConfidence(opts.lang), 39 | RCValue: names.RCValueOf(temporal.RC, opts.lang), 40 | TemporalScore: strconv.FormatFloat(temporal.Score(), 'f', -1, 64), 41 | SeverityName: names.Severity(opts.lang), 42 | SeverityValue: names.SeverityValueOf(temporal.Severity(), opts.lang), 43 | } 44 | } 45 | 46 | //ExportWithTemplate returns string of CVSS report 47 | func (rep *TemporalReport) ExportWith(r io.Reader) (io.Reader, error) { 48 | str, err := getTempleteString(r) 49 | if err != nil { 50 | return nil, errs.Wrap(err) 51 | } 52 | return rep.ExportWithString(str) 53 | } 54 | 55 | //ExportWithTemplate returns string of CVSS report 56 | func (rep *TemporalReport) ExportWithString(str string) (io.Reader, error) { 57 | if rep == nil { 58 | return nil, errs.Wrap(cvsserr.ErrNullPointer) 59 | } 60 | return executeTemplate(rep, str) 61 | } 62 | 63 | /* Copyright 2018-2020 Spiegel 64 | * 65 | * Licensed under the Apache License, Version 2.0 (the "License"); 66 | * you may not use this file except in compliance with the License. 67 | * You may obtain a copy of the License at 68 | * 69 | * http://www.apache.org/licenses/LICENSE-2.0 70 | * 71 | * Unless required by applicable law or agreed to in writing, software 72 | * distributed under the License is distributed on an "AS IS" BASIS, 73 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 74 | * See the License for the specific language governing permissions and 75 | * limitations under the License. 76 | */ 77 | -------------------------------------------------------------------------------- /v3/report/report-base.go: -------------------------------------------------------------------------------- 1 | package report 2 | 3 | import ( 4 | "io" 5 | "strconv" 6 | 7 | "github.com/goark/errs" 8 | "github.com/goark/go-cvss/cvsserr" 9 | "github.com/goark/go-cvss/v3/metric" 10 | "github.com/goark/go-cvss/v3/report/names" 11 | ) 12 | 13 | //CVSSReport is dataset for CVSS report 14 | type BaseReport struct { 15 | Version string //CVSS version 16 | Vector string //CVSS vector string 17 | BaseMetrics, BaseMetricValue string //titles 18 | AVName, AVValue string //AttackVector 19 | ACName, ACValue string //AttackComplexity 20 | PRName, PRValue string //PrivilegesRequired 21 | UIName, UIValue string //UserInteraction 22 | SName, SValue string //Scope 23 | CName, CValue string //ConfidentialityImpact 24 | IName, IValue string //IntegrityImpact 25 | AName, AValue string //AvailabilityImpact 26 | BaseScore string //Base Score 27 | SeverityName, SeverityValue string //Severity 28 | } 29 | 30 | //NewtBase function reterns new CVSSReport instance 31 | func NewBase(base *metric.Base, os ...ReportOptionsFunc) *BaseReport { 32 | opts := newOptions(os...) 33 | vec, _ := base.Encode() 34 | return &BaseReport{ 35 | Version: base.Ver.String(), 36 | Vector: vec, 37 | BaseMetrics: names.BaseMetrics(opts.lang), 38 | BaseMetricValue: names.BaseMetricsValueOf(opts.lang), 39 | AVName: names.AttackVector(opts.lang), 40 | AVValue: names.AVValueOf(base.AV, opts.lang), 41 | ACName: names.AttackComplexity(opts.lang), 42 | ACValue: names.ACValueOf(base.AC, opts.lang), 43 | PRName: names.PrivilegesRequired(opts.lang), 44 | PRValue: names.PRValueOf(base.PR, opts.lang), 45 | UIName: names.UserInteraction(opts.lang), 46 | UIValue: names.UIValueOf(base.UI, opts.lang), 47 | SName: names.Scope(opts.lang), 48 | SValue: names.SValueOf(base.S, opts.lang), 49 | CName: names.ConfidentialityImpact(opts.lang), 50 | CValue: names.CValueOf(base.C, opts.lang), 51 | IName: names.IntegrityImpact(opts.lang), 52 | IValue: names.IValueOf(base.I, opts.lang), 53 | AName: names.AvailabilityImpact(opts.lang), 54 | AValue: names.AValueOf(base.A, opts.lang), 55 | BaseScore: strconv.FormatFloat(base.Score(), 'f', -1, 64), 56 | SeverityName: names.Severity(opts.lang), 57 | SeverityValue: names.SeverityValueOf(base.Severity(), opts.lang), 58 | } 59 | } 60 | 61 | //ExportWithTemplate returns string of CVSS report 62 | func (rep *BaseReport) ExportWith(r io.Reader) (io.Reader, error) { 63 | str, err := getTempleteString(r) 64 | if err != nil { 65 | return nil, errs.Wrap(err) 66 | } 67 | return rep.ExportWithString(str) 68 | } 69 | 70 | //ExportWithTemplate returns string of CVSS report 71 | func (rep *BaseReport) ExportWithString(str string) (io.Reader, error) { 72 | if rep == nil { 73 | return nil, errs.Wrap(cvsserr.ErrNullPointer) 74 | } 75 | return executeTemplate(rep, str) 76 | } 77 | 78 | /* Copyright 2018-2020 Spiegel 79 | * 80 | * Licensed under the Apache License, Version 2.0 (the "License"); 81 | * you may not use this file except in compliance with the License. 82 | * You may obtain a copy of the License at 83 | * 84 | * http://www.apache.org/licenses/LICENSE-2.0 85 | * 86 | * Unless required by applicable law or agreed to in writing, software 87 | * distributed under the License is distributed on an "AS IS" BASIS, 88 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 89 | * See the License for the specific language governing permissions and 90 | * limitations under the License. 91 | */ 92 | -------------------------------------------------------------------------------- /sample/sample.go: -------------------------------------------------------------------------------- 1 | //go:build run 2 | // +build run 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "io" 9 | "os" 10 | "strings" 11 | 12 | "github.com/goark/go-cvss/v3/metric" 13 | "github.com/goark/go-cvss/v3/report" 14 | ) 15 | 16 | var template = `- CVSS Version {{ .Version }} 17 | - Vector: {{ .Vector }} 18 | 19 | ## Base Metrics 20 | 21 | - Base Score: {{ .BaseScore }} 22 | 23 | | {{ .BaseMetrics }} | {{ .BaseMetricValue }} | 24 | |--------|-------| 25 | | {{ .AVName }} | {{ .AVValue }} | 26 | | {{ .ACName }} | {{ .ACValue }} | 27 | | {{ .PRName }} | {{ .PRValue }} | 28 | | {{ .UIName }} | {{ .UIValue }} | 29 | | {{ .SName }} | {{ .SValue }} | 30 | | {{ .CName }} | {{ .CValue }} | 31 | | {{ .IName }} | {{ .IValue }} | 32 | | {{ .AName }} | {{ .AValue }} | 33 | 34 | ## Temporal Metrics 35 | 36 | - Temporal Score: {{ .TemporalScore }} 37 | - {{ .SeverityName }}: {{ .SeverityValue }} 38 | 39 | | {{ .TemporalMetrics }} | {{ .TemporalMetricValue }} | 40 | |--------|-------| 41 | | {{ .EName }} | {{ .EValue }} | 42 | | {{ .RLName }} | {{ .RLValue }} | 43 | | {{ .RCName }} | {{ .RCValue }} | 44 | 45 | ## Environmental Metrics 46 | 47 | - {{ .SeverityName }}: {{ .SeverityValue }} ({{ .EnvironmentalScore }}) 48 | 49 | | {{ .EnvironmentalMetrics }} | {{ .EnvironmentalMetricValue }} | 50 | |--------|-------| 51 | | {{ .CRName }} | {{ .CRValue }} | 52 | | {{ .IRName }} | {{ .IRValue }} | 53 | | {{ .ARName }} | {{ .ARValue }} | 54 | | {{ .MAVName }} | {{ .MAVValue }} | 55 | | {{ .MACName }} | {{ .MACValue }} | 56 | | {{ .MPRName }} | {{ .MPRValue }} | 57 | | {{ .MUIName }} | {{ .MUIValue }} | 58 | | {{ .MSName }} | {{ .MSValue }} | 59 | | {{ .MCName }} | {{ .MCValue }} | 60 | | {{ .MIName }} | {{ .MIValue }} | 61 | | {{ .MAName }} | {{ .MAValue }} | 62 | ` 63 | 64 | func main() { 65 | em, err := metric.NewEnvironmental().Decode("CVSS:3.1/AV:P/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H/E:F/RL:U/RC:C/CR:M/IR:H/AR:M/MAV:L/MAC:H/MPR:L/MUI:R/MS:U/MC:L/MI:H/MA:L") //Random CVSS Vector 66 | if err != nil { 67 | fmt.Fprintln(os.Stderr, err) 68 | return 69 | } 70 | r, err := report.NewEnvironmental(em).ExportWith(strings.NewReader(template)) 71 | if err != nil { 72 | fmt.Fprintln(os.Stderr, err) 73 | return 74 | } 75 | if _, err := io.Copy(os.Stdout, r); err != nil { 76 | fmt.Fprintln(os.Stderr, err) 77 | } 78 | // Output: 79 | // - CVSS Version 3.1 80 | // - Vector: CVSS:3.1/AV:P/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H/CR:M/IR:H/AR:M/MAV:L/MAC:H/MPR:L/MUI:R/MS:U/MC:L/MI:H/MA:L 81 | // 82 | // ## Base Metrics 83 | // 84 | // - Base Score: 6.1 85 | // 86 | // | Base Metrics | Metric Value | 87 | // |--------|-------| 88 | // | Attack Vector | Physical | 89 | // | Attack Complexity | High | 90 | // | Privileges Required | High | 91 | // | User Interaction | None | 92 | // | Scope | Unchanged | 93 | // | Confidentiality Impact | High | 94 | // | Integrity Impact | High | 95 | // | Availability Impact | High | 96 | // 97 | // ## Temporal Metrics 98 | // 99 | // - Temporal Score: 6 100 | // - Severity: Medium 101 | // 102 | // | Temporal Metrics | Metric Value | 103 | // |--------|-------| 104 | // | Exploit Code Maturity | Functional | 105 | // | Remediation Level | Unavailable | 106 | // | Report Confidence | Confirmed | 107 | // 108 | // ## Environmental Metrics 109 | // 110 | // - Severity: Medium (6.5) 111 | // 112 | // | Environmental Metrics | Metric Value | 113 | // |--------|-------| 114 | // | Confidentiality Requirement | Medium | 115 | // | Integrity Requirement | High | 116 | // | Availability Requirement | Medium | 117 | // | Modified Attack Vector | Local | 118 | // | Modified Attack Complexity | High | 119 | // | Modified Privileges Required | Low | 120 | // | Modified User Interaction | Required | 121 | // | Modified Scope | Unchanged | 122 | // | Modified Confidentiality Impact | Low | 123 | // | Modified Integrity Impact | High | 124 | // | Modified Availability Impact | Low | 125 | } 126 | 127 | /* Copyright 2018-2020 Spiegel 128 | * 129 | * Licensed under the Apache License, Version 2.0 (the "License"); 130 | * you may not use this file except in compliance with the License. 131 | * You may obtain a copy of the License at 132 | * 133 | * http://www.apache.org/licenses/LICENSE-2.0 134 | * 135 | * Unless required by applicable law or agreed to in writing, software 136 | * distributed under the License is distributed on an "AS IS" BASIS, 137 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138 | * See the License for the specific language governing permissions and 139 | * limitations under the License. 140 | */ 141 | -------------------------------------------------------------------------------- /v3/metric/temporal_test.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | 7 | "github.com/goark/go-cvss/cvsserr" 8 | ) 9 | 10 | func TestTemporalScore(t *testing.T) { 11 | testCases := []struct { 12 | vector string 13 | err error 14 | score float64 15 | sav Severity 16 | }{ 17 | {vector: "XXXX:1.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: cvsserr.ErrInvalidVector, score: 0, sav: SeverityNone}, 18 | {vector: "CVSS:1.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: cvsserr.ErrNotSupportVer, score: 0, sav: SeverityNone}, 19 | {vector: "CVSS:3.0/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: cvsserr.ErrNoBaseMetrics, score: 0, sav: SeverityNone}, 20 | {vector: "CVSS:3.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/X:N", err: cvsserr.ErrNotSupportMetric, score: 0, sav: SeverityNone}, 21 | {vector: "CVSS:3.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/RC:", err: cvsserr.ErrInvalidVector, score: 0, sav: SeverityNone}, 22 | {vector: "CVSS:3.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/:X", err: cvsserr.ErrInvalidVector, score: 0, sav: SeverityNone}, 23 | {vector: "CVSS:3.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/:", err: cvsserr.ErrInvalidVector, score: 0, sav: SeverityNone}, 24 | {vector: "CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N/E:F/RL:W/RC:R/RC:R", err: cvsserr.ErrSameMetric, score: 0, sav: SeverityNone}, 25 | {vector: "CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N/E:F/RL:W/RC:0", err: cvsserr.ErrInvalidValue, score: 0, sav: SeverityNone}, 26 | {vector: "CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N/E:F/RL:W/RC:r", err: cvsserr.ErrInvalidValue, score: 0, sav: SeverityNone}, 27 | {vector: "CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N/E:F/RL:0/RC:R", err: cvsserr.ErrInvalidValue, score: 0, sav: SeverityNone}, 28 | {vector: "CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N/E:F/RL:w/RC:R", err: cvsserr.ErrInvalidValue, score: 0, sav: SeverityNone}, 29 | {vector: "CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N/E:0/RL:W/RC:R", err: cvsserr.ErrInvalidValue, score: 0, sav: SeverityNone}, 30 | {vector: "CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N/E:f/RL:W/RC:R", err: cvsserr.ErrInvalidValue, score: 0, sav: SeverityNone}, 31 | {vector: "CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N/e:f/rl:w/rc:r", err: cvsserr.ErrNotSupportMetric, score: 0, sav: SeverityNone}, 32 | {vector: "CVSS:3.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: nil, score: 3.8, sav: SeverityLow}, 33 | {vector: "CVSS:3.1/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: nil, score: 3.8, sav: SeverityLow}, 34 | {vector: "CVSS:3.1/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N/E:F", err: nil, score: 3.7, sav: SeverityLow}, 35 | {vector: "CVSS:3.1/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N/E:F/RL:X", err: nil, score: 3.7, sav: SeverityLow}, 36 | {vector: "CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N/E:F/RL:W/RC:R", err: nil, score: 5.6, sav: SeverityMedium}, 37 | } 38 | 39 | for _, tc := range testCases { 40 | m, err := NewTemporal().Decode(tc.vector) 41 | if !errors.Is(err, tc.err) { 42 | t.Errorf("Decode(%s) = \"%+v\", want \"%v\".", tc.vector, err, tc.err) 43 | } 44 | if err == nil { 45 | score := m.Score() 46 | if score != tc.score { 47 | t.Errorf("Score(%s) = %v, want %v.", tc.vector, score, tc.score) 48 | } 49 | sav := m.Severity() 50 | if sav != tc.sav { 51 | t.Errorf("Severity(%s) = %v, want %v.", tc.vector, sav, tc.sav) 52 | } 53 | } 54 | } 55 | } 56 | 57 | func TestTemporalDecodeEncode(t *testing.T) { 58 | testCases := []struct { 59 | vector string 60 | err error 61 | }{ 62 | {vector: "CVSS:3.1/AV:A/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:L/E:P/RL:O/RC:U", err: nil}, 63 | } 64 | 65 | for _, tc := range testCases { 66 | m, err := NewTemporal().Decode(tc.vector) 67 | if !errors.Is(err, tc.err) { 68 | t.Errorf("Decode(%s) = \"%+v\", want \"%v\".", tc.vector, err, tc.err) 69 | } 70 | if err == nil { 71 | v, err := m.Encode() 72 | if err != nil { 73 | t.Errorf("Encode() = \"%+v\", want .", err) 74 | } 75 | if v != tc.vector { 76 | t.Errorf("Encode() = \"%v\", want \"%v\".", v, tc.vector) 77 | } 78 | if m.String() != tc.vector { 79 | t.Errorf("String() = \"%v\", want \"%v\".", m.String(), tc.vector) 80 | } 81 | } 82 | } 83 | } 84 | 85 | /* Contributed by Florent Viel, 2020 */ 86 | /* Copyright 2018-2023 Spiegel 87 | * 88 | * Licensed under the Apache License, Version 2.0 (the "License"); 89 | * you may not use this file except in compliance with the License. 90 | * You may obtain a copy of the License at 91 | * 92 | * http://www.apache.org/licenses/LICENSE-2.0 93 | * 94 | * Unless required by applicable law or agreed to in writing, software 95 | * distributed under the License is distributed on an "AS IS" BASIS, 96 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 97 | * See the License for the specific language governing permissions and 98 | * limitations under the License. 99 | */ 100 | -------------------------------------------------------------------------------- /v3/metric/temporal.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/goark/errs" 8 | "github.com/goark/go-cvss/cvsserr" 9 | ) 10 | 11 | const ( 12 | metricE = "E" 13 | metricRL = "RL" 14 | metricRC = "RC" 15 | ) 16 | 17 | // Base is Temporal Metrics for CVSSv3 18 | type Temporal struct { 19 | *Base 20 | E Exploitability 21 | RL RemediationLevel 22 | RC ReportConfidence 23 | names map[string]bool 24 | } 25 | 26 | // NewTemporal returns Temporal Metrics instance 27 | func NewTemporal() *Temporal { 28 | return &Temporal{ 29 | Base: NewBase(), 30 | E: ExploitabilityNotDefined, 31 | RL: RemediationLevelNotDefined, 32 | RC: ReportConfidenceNotDefined, 33 | names: map[string]bool{}, 34 | } 35 | } 36 | 37 | func (tm *Temporal) Decode(vector string) (*Temporal, error) { 38 | if tm == nil { 39 | tm = NewTemporal() 40 | } 41 | values := strings.Split(vector, "/") 42 | //CVSS version 43 | ver, err := GetVersion(values[0]) 44 | if err != nil { 45 | return nil, errs.Wrap(err, errs.WithContext("vector", vector)) 46 | } 47 | if ver == VUnknown { 48 | return nil, errs.Wrap(cvsserr.ErrNotSupportVer, errs.WithContext("vector", vector)) 49 | } 50 | tm.Ver = ver 51 | //parse vector 52 | var lastErr error 53 | for _, value := range values[1:] { 54 | if err := tm.decodeOne(value); err != nil { 55 | if !errs.Is(err, cvsserr.ErrNotSupportMetric) { 56 | return nil, errs.Wrap(err, errs.WithContext("vector", vector)) 57 | } 58 | lastErr = err 59 | } 60 | } 61 | if lastErr != nil { 62 | return nil, lastErr 63 | } 64 | if err := tm.GetError(); err != nil { 65 | return nil, err 66 | } 67 | return tm, nil 68 | } 69 | func (tm *Temporal) decodeOne(str string) error { 70 | if err := tm.Base.decodeOne(str); err != nil { 71 | if !errs.Is(err, cvsserr.ErrNotSupportMetric) { 72 | return errs.Wrap(err, errs.WithContext("metric", str)) 73 | } 74 | } else { 75 | return nil 76 | } 77 | m := strings.Split(str, ":") 78 | if len(m) != 2 || len(m[0]) == 0 || len(m[1]) == 0 { 79 | return errs.Wrap(cvsserr.ErrInvalidVector, errs.WithContext("metric", str)) 80 | } 81 | name := m[0] 82 | if tm.names[name] { 83 | return errs.Wrap(cvsserr.ErrSameMetric, errs.WithContext("metric", str)) 84 | } 85 | switch name { 86 | case metricE: //Exploitability 87 | tm.E = GetExploitability(m[1]) 88 | if tm.E == ExploitabilityInvalid { 89 | return errs.Wrap(cvsserr.ErrInvalidValue, errs.WithContext("metric", str)) 90 | } 91 | case metricRL: //RemediationLevel 92 | tm.RL = GetRemediationLevel(m[1]) 93 | if tm.RL == RemediationLevelInvalid { 94 | return errs.Wrap(cvsserr.ErrInvalidValue, errs.WithContext("metric", str)) 95 | } 96 | case metricRC: //RemediationLevel 97 | tm.RC = GetReportConfidence(m[1]) 98 | if tm.RC == ReportConfidenceInvalid { 99 | return errs.Wrap(cvsserr.ErrInvalidValue, errs.WithContext("metric", str)) 100 | } 101 | default: 102 | return errs.Wrap(cvsserr.ErrNotSupportMetric, errs.WithContext("metric", str)) 103 | } 104 | tm.names[name] = true 105 | return nil 106 | } 107 | 108 | // GetError returns error instance if undefined metric 109 | func (tm *Temporal) GetError() error { 110 | if tm == nil { 111 | return errs.Wrap(cvsserr.ErrNoTemporalMetrics) 112 | } 113 | if err := tm.Base.GetError(); err != nil { 114 | return errs.Wrap(err) 115 | } 116 | switch true { 117 | case !tm.E.IsValid(), !tm.RL.IsValid(), !tm.RC.IsValid(): 118 | return errs.Wrap(cvsserr.ErrInvalidValue) 119 | default: 120 | return nil 121 | } 122 | } 123 | 124 | // Encode returns CVSSv3 vector string 125 | func (tm *Temporal) Encode() (string, error) { 126 | if tm == nil { 127 | return "", errs.Wrap(cvsserr.ErrNoTemporalMetrics) 128 | } 129 | bs, _ := tm.Base.Encode() 130 | r := &strings.Builder{} 131 | r.WriteString(bs) //Vector of Base metrics 132 | r.WriteString(fmt.Sprintf("/%v:%v", metricE, tm.E)) //Exploitability 133 | r.WriteString(fmt.Sprintf("/%v:%v", metricRL, tm.RL)) //Remediation Level 134 | r.WriteString(fmt.Sprintf("/%v:%v", metricRC, tm.RC)) //Report Confidence 135 | return r.String(), tm.GetError() 136 | } 137 | 138 | // String is stringer method. 139 | func (tm *Temporal) String() string { 140 | s, _ := tm.Encode() 141 | return s 142 | } 143 | 144 | // Score returns score of Temporal metrics 145 | func (tm *Temporal) Score() float64 { 146 | if err := tm.GetError(); err != nil { 147 | return 0.0 148 | } 149 | return roundUp(tm.Base.Score() * tm.E.Value() * tm.RL.Value() * tm.RC.Value()) 150 | } 151 | 152 | // Severity returns severity by score of Temporal metrics 153 | func (tm *Temporal) Severity() Severity { 154 | return severity(tm.Score()) 155 | } 156 | 157 | // BaseMetrics returns Base metrics in Temporal metrics instance 158 | func (tm *Temporal) BaseMetrics() *Base { 159 | if tm == nil { 160 | return nil 161 | } 162 | return tm.Base 163 | } 164 | 165 | /* Copyright by Florent Viel, 2020 */ 166 | /* Contributed by Spiegel, 2020-2023 */ 167 | -------------------------------------------------------------------------------- /v3/report/report-environmental.go: -------------------------------------------------------------------------------- 1 | package report 2 | 3 | import ( 4 | "io" 5 | "strconv" 6 | 7 | "github.com/goark/errs" 8 | "github.com/goark/go-cvss/cvsserr" 9 | "github.com/goark/go-cvss/v3/metric" 10 | "github.com/goark/go-cvss/v3/report/names" 11 | ) 12 | 13 | //CVSSReport is dataset for CVSS report 14 | type EnvironmentalReport struct { 15 | *TemporalReport //Report of Temporal metrics 16 | Vector string //CVSS vector string 17 | EnvironmentalMetrics, EnvironmentalMetricValue string //titles 18 | CRName, CRValue string //Confidentiality Requirement 19 | IRName, IRValue string //Integrity Requirement 20 | ARName, ARValue string //Integrity Requirement 21 | MAVName, MAVValue string //Modified Attack Vector 22 | MACName, MACValue string //Modified Attack Complexity 23 | MPRName, MPRValue string //Modified Privileges Required 24 | MUIName, MUIValue string //Modified User Interaction 25 | MSName, MSValue string //Modified Scope 26 | MCName, MCValue string //Modified Confidentiality Impact 27 | MIName, MIValue string //Modified Integrity Impact 28 | MAName, MAValue string //Modified Availability Impact 29 | EnvironmentalScore string //Environmental Score 30 | SeverityName, SeverityValue string //Severity 31 | } 32 | 33 | //NewEnvironmental function reterns new CVSSReport instance 34 | func NewEnvironmental(environmental *metric.Environmental, os ...ReportOptionsFunc) *EnvironmentalReport { 35 | opts := newOptions(os...) 36 | vec, _ := environmental.Encode() 37 | return &EnvironmentalReport{ 38 | TemporalReport: NewTemporal(environmental.TemporalMetrics(), os...), 39 | Vector: vec, 40 | EnvironmentalMetrics: names.EnvironmentalMetrics(opts.lang), 41 | EnvironmentalMetricValue: names.EnvironmentalMetricsValueOf(opts.lang), 42 | CRName: names.ConfidentialityRequirement(opts.lang), 43 | CRValue: names.CRValueOf(environmental.CR, opts.lang), 44 | IRName: names.IntegrityRequirement(opts.lang), 45 | IRValue: names.IRValueOf(environmental.IR, opts.lang), 46 | ARName: names.AvailabilityRequirement(opts.lang), 47 | ARValue: names.ARValueOf(environmental.AR, opts.lang), 48 | MAVName: names.ModifiedAttackVector(opts.lang), 49 | MAVValue: names.MAVValueOf(environmental.MAV, opts.lang), 50 | MACName: names.ModifiedAttackComplexity(opts.lang), 51 | MACValue: names.MACValueOf(environmental.MAC, opts.lang), 52 | MPRName: names.ModifiedPrivilegesRequired(opts.lang), 53 | MPRValue: names.MPRValueOf(environmental.MPR, opts.lang), 54 | MUIName: names.ModifiedUserInteraction(opts.lang), 55 | MUIValue: names.MUIValueOf(environmental.MUI, opts.lang), 56 | MSName: names.ModifiedScope(opts.lang), 57 | MSValue: names.MSValueOf(environmental.MS, opts.lang), 58 | MCName: names.ModifiedConfidentialityImpact(opts.lang), 59 | MCValue: names.MCValueOf(environmental.MC, opts.lang), 60 | MIName: names.ModifiedIntegrityImpact(opts.lang), 61 | MIValue: names.MIValueOf(environmental.MI, opts.lang), 62 | MAName: names.ModifiedAvailabilityImpact(opts.lang), 63 | MAValue: names.MAValueOf(environmental.MA, opts.lang), 64 | EnvironmentalScore: strconv.FormatFloat(environmental.Score(), 'f', -1, 64), 65 | SeverityName: names.Severity(opts.lang), 66 | SeverityValue: names.SeverityValueOf(environmental.Severity(), opts.lang), 67 | } 68 | } 69 | 70 | //ExportWithTemplate returns string of CVSS report 71 | func (rep *EnvironmentalReport) ExportWith(r io.Reader) (io.Reader, error) { 72 | str, err := getTempleteString(r) 73 | if err != nil { 74 | return nil, errs.Wrap(err) 75 | } 76 | return rep.ExportWithString(str) 77 | } 78 | 79 | //ExportWithTemplate returns string of CVSS report 80 | func (rep *EnvironmentalReport) ExportWithString(str string) (io.Reader, error) { 81 | if rep == nil { 82 | return nil, errs.Wrap(cvsserr.ErrNullPointer) 83 | } 84 | return executeTemplate(rep, str) 85 | } 86 | 87 | /* Copyright 2022 Spiegel 88 | * 89 | * Licensed under the Apache License, Version 2.0 (the "License"); 90 | * you may not use this file except in compliance with the License. 91 | * You may obtain a copy of the License at 92 | * 93 | * http://www.apache.org/licenses/LICENSE-2.0 94 | * 95 | * Unless required by applicable law or agreed to in writing, software 96 | * distributed under the License is distributed on an "AS IS" BASIS, 97 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 98 | * See the License for the specific language governing permissions and 99 | * limitations under the License. 100 | */ 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [go-cvss] - Common Vulnerability Scoring System (CVSS) 2 | 3 | [![check vulns](https://github.com/goark/go-cvss/workflows/vulns/badge.svg)](https://github.com/goark/go-cvss/actions) 4 | [![lint status](https://github.com/goark/go-cvss/workflows/lint/badge.svg)](https://github.com/goark/go-cvss/actions) 5 | [![GitHub license](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://raw.githubusercontent.com/goark/go-cvss/master/LICENSE) 6 | [![GitHub release](https://img.shields.io/github/release/goark/go-cvss.svg)](https://github.com/goark/go-cvss/releases/latest) 7 | 8 | Importing CVSS vector and scoring. 9 | 10 | - Supports CVSS v2, v3.0 and v3.1 11 | - Exporting CVSS information with template string 12 | 13 | **Migrated repository to [github.com/goark/go-cvss][go-cvss]** 14 | 15 | ## Sample Code 16 | 17 | ### Base Metrics 18 | 19 | ```go 20 | package main 21 | 22 | import ( 23 | "fmt" 24 | "os" 25 | 26 | "github.com/goark/go-cvss/v3/metric" 27 | ) 28 | 29 | func main() { 30 | bm, err := metric.NewBase().Decode("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H") //CVE-2020-1472: ZeroLogon 31 | if err != nil { 32 | fmt.Fprintln(os.Stderr, err) 33 | return 34 | } 35 | fmt.Printf("Severity: %v (%v)\n", bm.Severity(), bm.Score()) 36 | // Output: 37 | // Severity: Critical (10) 38 | } 39 | ``` 40 | 41 | ### Temporal Metrics 42 | 43 | ```go 44 | package main 45 | 46 | import ( 47 | "fmt" 48 | "os" 49 | 50 | "github.com/goark/go-cvss/v3/metric" 51 | ) 52 | 53 | func main() { 54 | tm, err := metric.NewTemporal().Decode("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H/E:F/RL:W/RC:R") //CVE-2020-1472: ZeroLogon 55 | if err != nil { 56 | fmt.Fprintln(os.Stderr, err) 57 | return 58 | } 59 | fmt.Printf("Base Severity: %v (%v)\n", tm.BaseMetrics().Severity(), tm.BaseMetrics().Score()) 60 | fmt.Printf("Temporal Severity: %v (%v)\n", tm.Severity(), tm.Score()) 61 | // Output: 62 | // Base Severity: Critical (10) 63 | // Temporal Severity: Critical (9.1) 64 | } 65 | ``` 66 | 67 | ### Environmental Metrics 68 | 69 | ```go 70 | package main 71 | 72 | import ( 73 | "fmt" 74 | "github.com/goark/go-cvss/v3/metric" 75 | "os" 76 | ) 77 | 78 | func main() { 79 | em, err := metric.NewEnvironmental().Decode("CVSS:3.1/AV:P/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H/E:F/RL:U/RC:C/CR:M/IR:H/AR:M/MAV:L/MAC:H/MPR:L/MUI:R/MS:U/MC:L/MI:H/MA:L") //Random CVSS Vector 80 | if err != nil { 81 | fmt.Fprintln(os.Stderr, err) 82 | return 83 | } 84 | fmt.Printf("Base Severity: %v (%v)\n", em.BaseMetrics().Severity(), em.BaseMetrics().Score()) 85 | fmt.Printf("Temporal Severity: %v (%v)\n", em.TemporalMetrics().Severity(), em.TemporalMetrics().Score()) 86 | fmt.Printf("Environmental Severity: %v (%v)\n", em.Severity(), em.Score()) 87 | // Output: 88 | // Base Severity: Critical (6.1) 89 | // Temporal Severity: Critical (6) 90 | // Environmental Severity: Critical (6.5) 91 | } 92 | ``` 93 | 94 | ### CVSSv2 Base Metrics 95 | 96 | ```go 97 | package main 98 | 99 | import ( 100 | "fmt" 101 | "os" 102 | 103 | "github.com/goark/go-cvss/v2/metric" 104 | ) 105 | 106 | func main() { 107 | bm, err := metric.NewBase().Decode("AV:N/AC:L/Au:N/C:N/I:N/A:C") //CVE-2002-0392 108 | if err != nil { 109 | fmt.Fprintln(os.Stderr, err) 110 | return 111 | } 112 | fmt.Printf("Severity: %v (%v)\n", bm.Severity(), bm.Score()) 113 | // Output: 114 | // Severity: Severity: High (7.8) 115 | } 116 | ``` 117 | 118 | ### CVSSv2 Temporal Metrics 119 | 120 | ```go 121 | package main 122 | 123 | import ( 124 | "fmt" 125 | "os" 126 | 127 | "github.com/goark/go-cvss/v2/metric" 128 | ) 129 | 130 | func main() { 131 | tm, err := metric.NewTemporal().Decode("AV:N/AC:L/Au:N/C:N/I:N/A:C/E:F/RL:OF/RC:C") //CVE-2002-0392 132 | if err != nil { 133 | fmt.Fprintln(os.Stderr, err) 134 | return 135 | } 136 | fmt.Printf("Severity (Base): %v (%v)\n", tm.Base.Severity(), tm.Base.Score()) 137 | fmt.Printf("Severity (Temporal): %v (%v)\n", tm.Severity(), tm.Score()) 138 | // Output: 139 | // Severity (Base): High (7.8) 140 | // Severity (Temporal): Medium (6.4) 141 | } 142 | ``` 143 | 144 | ### CVSSv2 Environmental Metrics 145 | 146 | ```go 147 | package main 148 | 149 | import ( 150 | "fmt" 151 | "os" 152 | 153 | "github.com/goark/go-cvss/v2/metric" 154 | ) 155 | 156 | func main() { 157 | tm, err := metric.NewEnvironmental().Decode("AV:N/AC:L/Au:N/C:N/I:N/A:C/E:F/RL:OF/RC:C/CDP:H/TD:H/CR:M/IR:M/AR:H") //CVE-2002-0392 158 | if err != nil { 159 | fmt.Fprintln(os.Stderr, err) 160 | return 161 | } 162 | fmt.Printf("Severity (Base): %v (%v)\n", tm.Base.Severity(), tm.Base.Score()) 163 | fmt.Printf("Severity (Temporal): %v (%v)\n", tm.Temporal.Severity(), tm.Temporal.Score()) 164 | fmt.Printf("Severity (Environmental): %v (%v)\n", tm.Severity(), tm.Score()) 165 | // Output: 166 | // Severity (Base): High (7.8) 167 | // Severity (Temporal): Medium (6.4) 168 | // Severity (Environmental): High (9.2) 169 | } 170 | ``` 171 | 172 | ### Reporting with template (CVSSv3 only) 173 | 174 | ref: [sample.go](https://github.com/goark/go-cvss/blob/master/sample/sample.go) 175 | 176 | ## Reference 177 | 178 | - [CVSS v2 Complete Documentation](https://www.first.org/cvss/v2/guide) 179 | - [CVSS v3.0 Specification Document](https://www.first.org/cvss/v3.0/specification-document) 180 | - [CVSS v3.1 Specification Document](https://www.first.org/cvss/v3.1/specification-document) 181 | 182 | [go-cvss]: https://github.com/goark/go-cvss 183 | -------------------------------------------------------------------------------- /v2/metric/temporal.go: -------------------------------------------------------------------------------- 1 | package metric 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/goark/errs" 8 | "github.com/goark/go-cvss/cvsserr" 9 | ) 10 | 11 | const ( 12 | metricE = "E" 13 | metricRL = "RL" 14 | metricRC = "RC" 15 | ) 16 | 17 | // Temporal is Temporal Metrics for CVSSv2 18 | type Temporal struct { 19 | *Base 20 | E Exploitability 21 | RL RemediationLevel 22 | RC ReportConfidence 23 | names map[string]bool 24 | } 25 | 26 | // NewTemporal returns Temporal Metrics instance 27 | func NewTemporal() *Temporal { 28 | return &Temporal{ 29 | Base: NewBase(), 30 | E: ExploitabilityInvalid, 31 | RL: RemediationLevelInvalid, 32 | RC: ReportConfidenceInvalid, 33 | names: map[string]bool{}, 34 | } 35 | } 36 | 37 | // Decode returns Metrics instance by CVSSv2 vector 38 | func (m *Temporal) Decode(vector string) (*Temporal, error) { 39 | if m == nil { 40 | m = NewTemporal() 41 | } 42 | values := strings.Split(vector, "/") 43 | // parse metrics 44 | var lastErr error 45 | for _, value := range values { 46 | if err := m.decodeOne(value); err != nil { 47 | if !errs.Is(err, cvsserr.ErrNotSupportMetric) { 48 | return nil, errs.Wrap(err, errs.WithContext("vector", vector)) 49 | } 50 | lastErr = err 51 | } 52 | } 53 | if lastErr != nil { 54 | return nil, lastErr 55 | } 56 | enc, err := m.Encode() 57 | if err != nil { 58 | return nil, errs.Wrap(err, errs.WithContext("vector", vector)) 59 | } 60 | if vector != enc { 61 | return nil, errs.Wrap(cvsserr.ErrMisordered, errs.WithContext("vector", vector)) 62 | } 63 | return m, nil 64 | } 65 | 66 | func (m *Temporal) decodeOne(str string) error { 67 | if err := m.Base.decodeOne(str); err != nil { 68 | if !errs.Is(err, cvsserr.ErrNotSupportMetric) { 69 | return errs.Wrap(err, errs.WithContext("metric", str)) 70 | } 71 | } else { 72 | return nil 73 | } 74 | elm := strings.Split(str, ":") 75 | if len(elm) != 2 || len(elm[0]) == 0 || len(elm[1]) == 0 { 76 | return errs.Wrap(cvsserr.ErrInvalidVector, errs.WithContext("metric", str)) 77 | } 78 | name := elm[0] 79 | if m.names[name] { 80 | return errs.Wrap(cvsserr.ErrSameMetric, errs.WithContext("metric", str)) 81 | } 82 | switch name { 83 | case metricE: // Exploitability 84 | m.E = GetExploitability(elm[1]) 85 | if m.E == ExploitabilityInvalid { 86 | return errs.Wrap(cvsserr.ErrInvalidValue, errs.WithContext("metric", str)) 87 | } 88 | case metricRL: // RemediationLevel 89 | m.RL = GetRemediationLevel(elm[1]) 90 | if m.RL == RemediationLevelInvalid { 91 | return errs.Wrap(cvsserr.ErrInvalidValue, errs.WithContext("metric", str)) 92 | } 93 | case metricRC: // RemediationLevel 94 | m.RC = GetReportConfidence(elm[1]) 95 | if m.RC == ReportConfidenceInvalid { 96 | return errs.Wrap(cvsserr.ErrInvalidValue, errs.WithContext("metric", str)) 97 | } 98 | default: 99 | return errs.Wrap(cvsserr.ErrNotSupportMetric, errs.WithContext("vector", str)) 100 | } 101 | m.names[name] = true 102 | return nil 103 | } 104 | 105 | // GetError returns error instance if undefined metric 106 | func (m *Temporal) GetError() error { 107 | if m == nil { 108 | return errs.Wrap(cvsserr.ErrNoTemporalMetrics) 109 | } 110 | if err := m.Base.GetError(); err != nil { 111 | return errs.Wrap(err) 112 | } 113 | if m.IsEmpty() { 114 | return nil 115 | } 116 | switch true { 117 | case !m.E.IsValid(), !m.RL.IsValid(), !m.RC.IsValid(): 118 | return errs.Wrap(cvsserr.ErrNoTemporalMetrics) 119 | default: 120 | return nil 121 | } 122 | } 123 | 124 | // IsEmpty returns true if all elements of Temporal Metrics are empty. 125 | func (m *Temporal) IsEmpty() bool { 126 | return !m.names[metricE] && !m.names[metricRL] && !m.names[metricRC] 127 | } 128 | 129 | // Encode returns CVSSv2 vector string 130 | func (m *Temporal) Encode() (string, error) { 131 | if m == nil { 132 | return "", errs.Wrap(cvsserr.ErrNoBaseMetrics) 133 | } 134 | r := &strings.Builder{} 135 | r.WriteString(m.Base.String()) //Vector of Base metrics 136 | if m.names[metricE] { 137 | r.WriteString(fmt.Sprintf("/%s:%v", metricE, m.E)) // Exploitability 138 | } 139 | if m.names[metricRL] { 140 | r.WriteString(fmt.Sprintf("/%s:%v", metricRL, m.RL)) // Remediation Level 141 | } 142 | if m.names[metricRC] { 143 | r.WriteString(fmt.Sprintf("/%s:%v", metricRC, m.RC)) // Report Conf 144 | } 145 | return r.String(), m.GetError() 146 | } 147 | 148 | // String is stringer method. 149 | func (m *Temporal) String() string { 150 | s, _ := m.Encode() 151 | return s 152 | } 153 | 154 | // Score returns score of Temporal metrics 155 | func (m *Temporal) Score() float64 { 156 | if err := m.GetError(); err != nil { 157 | return 0 158 | } 159 | bs := m.Base.Score() 160 | if m.IsEmpty() { 161 | return bs 162 | } 163 | return m.score(bs) 164 | } 165 | 166 | func (m *Temporal) score(baseScore float64) float64 { 167 | return roundTo1Decimal(baseScore * m.E.Value() * m.RL.Value() * m.RC.Value()) 168 | } 169 | 170 | // GetSeverity returns severity by score of Base metrics 171 | func (m *Temporal) Severity() Severity { 172 | return severity(m.Score()) 173 | } 174 | 175 | // BaseMetrics returns Base metrics in Temporal metrics instance 176 | func (m *Temporal) BaseMetrics() *Base { 177 | if m == nil { 178 | return nil 179 | } 180 | return m.Base 181 | } 182 | 183 | /* Copyright 2023 Spiegel 184 | * 185 | * Licensed under the Apache License, Version 2.0 (the "License"); 186 | * you may not use this file except in compliance with the License. 187 | * You may obtain a copy of the License at 188 | * 189 | * http://www.apache.org/licenses/LICENSE-2.0 190 | * 191 | * Unless required by applicable law or agreed to in writing, software 192 | * distributed under the License is distributed on an "AS IS" BASIS, 193 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 194 | * See the License for the specific language governing permissions and 195 | * limitations under the License. 196 | */ 197 | --------------------------------------------------------------------------------