Skip to content

Commit

Permalink
Merge pull request #89 from turingsecure/update-vector-function
Browse files Browse the repository at this point in the history
add: update vector function
  • Loading branch information
Fubinator authored Aug 29, 2022
2 parents e0bdfec + 40e6dd7 commit 4844f62
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 90 deletions.
49 changes: 29 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<h1 align="center">cvss.js by <a href="https://turingpoint.eu" target="_blank">turingpoint.</a></h1>
<p>
<img alt="Version" src="https://img.shields.io/badge/version-1.4.6-blue.svg?cacheSeconds=2592000" />
<img alt="Version" src="https://img.shields.io/badge/version-1.4.7-blue.svg?cacheSeconds=2592000" />
<a href="#" target="_blank">
<img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg" />
</a>
Expand All @@ -20,9 +20,9 @@ yarn add @turingpointde/cvss.js
Import the library to use it in your code:

```js
const CVSS = require('@turingpointde/cvss.js');
const CVSS = require("@turingpointde/cvss.js");
// or
import CVSS from '@turingpointde/cvss.js';
import CVSS from "@turingpointde/cvss.js";
```

You can also use the library directly from the **CDN** (instead of yarn or npm):
Expand All @@ -37,30 +37,30 @@ After importing the library, the CVSS function must first be called with the vec

```js
// Vector only with base score
const vector1 = CVSS('CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:L');
const vector1 = CVSS("CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:L");
// Vector with temporal score
const vector2 = CVSS(
'CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:L/I:L/A:L/E:U/RL:T/RC:R',
"CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:L/I:L/A:L/E:U/RL:T/RC:R"
);
// Vector with environmental score
const vector3 = CVSS(
'CVSS:3.0/AV:L/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N/CR:M/IR:H/AR:M/MAV:N/MAC:H/MPR:L/MUI:N/MS:C/MC:N/MI:L/MA:L',
"CVSS:3.0/AV:L/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N/CR:M/IR:H/AR:M/MAV:N/MAC:H/MPR:L/MUI:N/MS:C/MC:N/MI:L/MA:L"
);
```

It is possible to pass in an object as well

```js
const vectorObject = {
CVSS: '3.0',
AV: 'N',
AC: 'H',
PR: 'H',
UI: 'R',
S: 'U',
C: 'H',
I: 'N',
A: 'N',
CVSS: "3.0",
AV: "N",
AC: "H",
PR: "H",
UI: "R",
S: "U",
C: "H",
I: "N",
A: "N",
};

console.log(CVSS(vectorObject).vector); // "CVSS:3.0/AV:N/AC:H/PR:H/UI:R/S:U/C:H/I:N/A:N"
Expand All @@ -71,7 +71,7 @@ To get the scores, simply call the respective function.
```js
// Create a vector
const vector = CVSS(
'CVSS:3.0/AV:L/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N/E:P/RL:O/CR:M/IR:H/AR:M/MAV:N/MAC:H/MPR:L/MUI:N/MS:C/MC:N/MI:L/MA:L',
"CVSS:3.0/AV:L/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N/E:P/RL:O/CR:M/IR:H/AR:M/MAV:N/MAC:H/MPR:L/MUI:N/MS:C/MC:N/MI:L/MA:L"
);

console.log(vector.getScore()); // 3.6
Expand All @@ -82,7 +82,7 @@ console.log(vector.getEnvironmentalScore()); // 5.1
Sometimes it is useful to get a qualitative rating of a score

```js
const vector = CVSS('CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:L');
const vector = CVSS("CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:L");

console.log(vector.getRating()); // Medium
console.log(vector.getTemporalRating()); // Medium
Expand All @@ -92,7 +92,7 @@ console.log(vector.getEnvironmentalRating()); // Low
A few useful variables/functions to work with the vectors:

```js
const vector = CVSS('CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:L');
const vector = CVSS("CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:L");

console.log(vector.isValid); // true
console.log(vector.vector); // CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:L
Expand All @@ -103,7 +103,7 @@ The following functions are suitable for displaying the vector in a human-readab

```js
const vector = CVSS(
'CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:L/I:L/A:L/E:U/RL:T/RC:R/MAC:X/MUI:X/MA:X/MI:X',
"CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:L/I:L/A:L/E:U/RL:T/RC:R/MAC:X/MUI:X/MA:X/MI:X"
);

console.log(vector.getVectorObject()); // { CVSS: "3.0", AV: "N", AC: "H", PR: "L", UI: "R", S: "C", C: "L", I: "L", A: "L", E: "U", RL: "T", RC: "R", CR: "X", IR: "X", AR: "X", MAV: "X", MAC: "X", MPR: "X", MUI: "X", MS: "X" , MC: "X", MI: "X", MA: "X" }
Expand Down Expand Up @@ -229,12 +229,21 @@ console.log(vector.getDetailedVectorObject()); // see spoiler below

</details>

To update a vector's metric:

```js
const vector = CVSS(
"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N/RL:X/RC:X"
).updateVectorValue("AV", "L");
console.log(vector); // "CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N"
```

## Contributing

Contributions, issues and feature requests are welcome.
Feel free to check out the [issues page](https://github.com/turingpointde/cvss.js/issues) if you want to contribute.

## License

Copyright © 2021 [turingpoint GmbH](https://turingpoint.eu).
Copyright © 2022 [turingpoint GmbH](https://turingpoint.eu).
This project is [MIT](LICENSE) licensed.
1 change: 1 addition & 0 deletions dist/cvss.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ declare function CVSS(vector: string): {
getDetailedVectorObject: () => any;
getVersion: () => string;
getCleanVectorString: () => string;
updateVectorValue: (metric: string, value: string) => string;
isValid: true;
};
2 changes: 1 addition & 1 deletion dist/production.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/util.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export function findMetricValue(abbr: string, vectorObject: any): any;
* @returns {String} returns one of the five possible ratings
*/
export function getRating(score: any): string;
export function updateVectorValue(vector: any, metric: any, value: any): string;
/**
* Checks whether the vector passed is valid
*
Expand Down
26 changes: 18 additions & 8 deletions lib/cvss.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,13 @@ function CVSS(vector) {

/**
* Retrives the version from the vector string
*
* @return {String} returns the version number
*
* @return {String} returns the version number
*/
function getVersion(){
function getVersion() {
return util.getVersion(vector);
}


/**
* Parses the vector to a number score
*
Expand Down Expand Up @@ -125,16 +124,26 @@ function CVSS(vector) {
return util.getCleanVectorString(vector);
}

vector = parseVectorObjectToString(vector);
/**
* Updates a vector's metric by a specific value
*
* @param {String} vector
* @param {String} metric
* @param {String} value
* @returns {String} Vector with updated value
*/
function updateVectorValue(metric, value) {
return util.updateVectorValue(vector, metric, value);
}

vector = parseVectorObjectToString(vector);

//Check if vector version is valid
const isVersionValid = getVersion();
if (isVersionValid === "Error") {
throw new Error("The vector version is not valid");
}


//Check if vector format is valid
const isValid = isVectorValid();
if (!isValid) {
Expand All @@ -153,8 +162,9 @@ function CVSS(vector) {
getDetailedVectorObject,
getVersion,
getCleanVectorString,
isValid
updateVectorValue,
isValid,
};
}

module.exports = CVSS;
module.exports = CVSS;
71 changes: 48 additions & 23 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ const findMetric = function (abbr) {
*/
const findMetricValue = function (abbr, vectorObject) {
const definition = findMetric(abbr);
const value = definition.metrics.find((metric) => metric.abbr === vectorObject[definition.abbr]);
const value = definition.metrics.find(
(metric) => metric.abbr === vectorObject[definition.abbr]
);

return value;
};
Expand Down Expand Up @@ -57,7 +59,9 @@ function roundUpExact(num) {
function getVectorObject(vector) {
const vectorArray = vector.split("/");
const vectorObject = {};
definitions.definitions.forEach((definition) => (vectorObject[definition["abbr"]] = "X"));
definitions.definitions.forEach(
(definition) => (vectorObject[definition["abbr"]] = "X")
);

for (const entry of vectorArray) {
const values = entry.split(":");
Expand Down Expand Up @@ -102,13 +106,17 @@ function getDetailedVectorObject(vector) {
abbr: vectorDef.abbr,
fullName: `${vectorDef.name} (${vectorDef.abbr})`,
value: vectorDef.metrics.find((def) => def.abbr === values[1]).name,
valueAbbr: values[1]
valueAbbr: values[1],
};
return Object.assign(vectorObjectAccumulator, {
metrics: Object.assign(metrics, { [values[0].trim()]: detailedVectorObject })
metrics: Object.assign(metrics, {
[values[0].trim()]: detailedVectorObject,
}),
});
} else {
return Object.assign(vectorObjectAccumulator, { [values[0].trim()]: values[1] });
return Object.assign(vectorObjectAccumulator, {
[values[0].trim()]: values[1],
});
}
},
{ metrics: {} }
Expand Down Expand Up @@ -153,21 +161,25 @@ const isVectorValid = function (vector) {
* Exit example:
* ((((((((((AV:[NALP]|AC:[LH])|PR:[NLH])|UI:[NR])|S:[UC])|C:[NLW])|I:[NLW])|A:[NLW])|E:[XUPFH])|RL:[XOTWU])|RC:[XURC])
*/
const expression = definitions.definitions.reduce((accumulator, currentValue, index) => {
const serializedAbbr = `${currentValue.abbr}:[${currentValue.metrics.reduce(
(accumulator2, currentValue2) => {
const expression = definitions.definitions.reduce(
(accumulator, currentValue, index) => {
const serializedAbbr = `${
currentValue.abbr
}:[${currentValue.metrics.reduce((accumulator2, currentValue2) => {
return accumulator2 + currentValue2.abbr;
},
""
)}]`;
if (index !== 0) {
return `(${accumulator}|${serializedAbbr})`;
} else {
return serializedAbbr;
}
}, "");
}, "")}]`;
if (index !== 0) {
return `(${accumulator}|${serializedAbbr})`;
} else {
return serializedAbbr;
}
},
""
);

const totalExpressionVector = new RegExp("^CVSS:3.(0|1)(/" + expression + ")+$");
const totalExpressionVector = new RegExp(
"^CVSS:3.(0|1)(/" + expression + ")+$"
);

//Checks if the vector is in valid format
if (!totalExpressionVector.test(vector)) {
Expand All @@ -185,9 +197,12 @@ const isVectorValid = function (vector) {
*/
const allExpressions = definitions.definitions.map((currentValue) => {
return new RegExp(
`/${currentValue.abbr}:[${currentValue.metrics.reduce((accumulator2, currentValue2) => {
return accumulator2 + currentValue2.abbr;
}, "")}]`,
`/${currentValue.abbr}:[${currentValue.metrics.reduce(
(accumulator2, currentValue2) => {
return accumulator2 + currentValue2.abbr;
},
""
)}]`,
"g"
);
});
Expand All @@ -206,7 +221,7 @@ const isVectorValid = function (vector) {
/\/S:[UC]/g,
/\/C:[NLH]/g,
/\/I:[NLH]/g,
/\/A:[NLH]/g
/\/A:[NLH]/g,
];

//Checks whether all mandatory parameters are present in the vector
Expand Down Expand Up @@ -244,6 +259,15 @@ function parseVectorObjectToString(obj) {
return vectorString;
}

function updateVectorValue(vector, metric, value) {
const vectorObject = getVectorObject(vector);
vectorObject[metric] = value;

const vectorString = parseVectorObjectToString(vectorObject);

return getCleanVectorString(vectorString);
}

/**
* Retrives the version from the vector string
*
Expand All @@ -268,8 +292,9 @@ module.exports = {
findMetric,
findMetricValue,
getRating,
updateVectorValue,
isVectorValid,
parseVectorObjectToString,
getVersion,
getCleanVectorString
getCleanVectorString,
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@turingpointde/cvss.js",
"version": "1.4.6",
"version": "1.4.7",
"description": "A tiny library to work with cvss vectors",
"scripts": {
"build": "webpack && tsc",
Expand Down
Loading

0 comments on commit 4844f62

Please sign in to comment.