Skip to content

add: update vector function #89

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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