From 248909e2518ae6c17543a4f1e3db8330a51f11f2 Mon Sep 17 00:00:00 2001 From: Fabian Kutsche Date: Fri, 16 Jul 2021 09:25:08 +0200 Subject: [PATCH] chore: generate typescript types automatically on build --- README.md | 40 ++++++++++++----------- dist/cvss.d.ts | 20 ++++++++++++ dist/production.min.js | 2 +- dist/score.d.ts | 18 ++++++++++ dist/util.d.ts | 74 ++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +-- tsconfig.json | 9 +++++ yarn.lock | 5 +++ 8 files changed, 151 insertions(+), 22 deletions(-) create mode 100644 dist/cvss.d.ts create mode 100644 dist/score.d.ts create mode 100644 dist/util.d.ts create mode 100644 tsconfig.json diff --git a/README.md b/README.md index 9a9d941..c1bd6af 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

cvss.js by turingpoint.

- Version + Version License: MIT @@ -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): @@ -37,12 +37,14 @@ 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"); +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', +); // 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', ); ``` @@ -50,15 +52,15 @@ 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" @@ -69,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 @@ -80,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 @@ -90,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 @@ -101,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" } diff --git a/dist/cvss.d.ts b/dist/cvss.d.ts new file mode 100644 index 0000000..5c310e1 --- /dev/null +++ b/dist/cvss.d.ts @@ -0,0 +1,20 @@ +export = CVSS; +/** + * Creates a new CVSS object + * + * @param {String} vector + */ +declare function CVSS(vector: string): { + vector: string; + getScore: () => number; + getTemporalScore: () => number; + getEnvironmentalScore: () => number; + getRating: () => string; + getTemporalRating: () => string; + getEnvironmentalRating: () => string; + getVectorObject: () => any; + getDetailedVectorObject: () => any; + getVersion: () => string; + getCleanVectorString: () => string; + isValid: true; +}; diff --git a/dist/production.min.js b/dist/production.min.js index 9b8117f..04b31e6 100644 --- a/dist/production.min.js +++ b/dist/production.min.js @@ -1 +1 @@ -var CVSS=function(e){var n={};function r(a){if(n[a])return n[a].exports;var i=n[a]={i:a,l:!1,exports:{}};return e[a].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=n,r.d=function(e,n,a){r.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:a})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,n){if(1&n&&(e=r(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(r.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var i in e)r.d(a,i,function(n){return e[n]}.bind(null,i));return a},r.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(n,"a",n),n},r.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},r.p="",r(r.s=1)}([function(e,n,r){const a=r(3),i=function(e){return a.definitions.find(n=>n.abbr===e)};e.exports={roundUpExact:function(e){const n=Math.round(1e5*e);return n%1e4==0?n/1e5:(Math.floor(n/1e4)+1)/10},roundUpApprox:function(e,n){return n=Math.pow(10,n),Math.ceil(e*n)/n},getVectorObject:function(e){const n=e.split("/"),r={};a.definitions.forEach(e=>r[e.abbr]="X");for(const e of n){const n=e.split(":");r[n[0]]=n[1]}return r},getDetailedVectorObject:function(e){return e.split("/").reduce((e,n,r)=>{const a=n.split(":"),t={...e.metrics};if(r){const n=i(a[0]),r={name:n.name,abbr:n.abbr,fullName:`${n.name} (${n.abbr})`,value:n.metrics.find(e=>e.abbr===a[1]).name,valueAbbr:a[1]};return Object.assign(e,{metrics:Object.assign(t,{[a[0].trim()]:r})})}return Object.assign(e,{[a[0].trim()]:a[1]})},{metrics:{}})},findMetric:i,findMetricValue:function(e,n){const r=i(e);return r.metrics.find(e=>e.abbr===n[r.abbr])},getRating:function(e){let n="None";return n=0===e?"None":e<=3.9?"Low":e<=6.9?"Medium":e<=8.9?"High":"Critical",n},isVectorValid:function(e){const n=a.definitions.reduce((e,n,r)=>{const a=`${n.abbr}:[${n.metrics.reduce((e,n)=>e+n.abbr,"")}]`;return 0!==r?`(${e}|${a})`:a},"");if(!new RegExp("^CVSS:3.(0|1)(/"+n+")+$").test(e))return!1;const r=a.definitions.map(e=>new RegExp(`/${e.abbr}:[${e.metrics.reduce((e,n)=>e+n.abbr,"")}]`,"g"));for(const n of r)if((e.match(n)||[]).length>1)return!1;const i=[/\/AV:[NALP]/g,/\/AC:[LH]/g,/\/PR:[NLH]/g,/\/UI:[NR]/g,/\/S:[UC]/g,/\/C:[NLH]/g,/\/I:[NLH]/g,/\/A:[NLH]/g];for(const n of i)if((e.match(n)||[]).length<1)return!1;return!0},parseVectorObjectToString:function(e){if("string"==typeof e)return e;let n=`CVSS:${e.CVSS}/`;for(const r of a.definitions){const a=r.abbr;Object.prototype.hasOwnProperty.call(e,a)&&(n+=`${a}:${e[a]}/`)}return n=n.slice(0,-1),n},getVersion:function(e){const n=e.split("/");return"CVSS:3.0"===n[0]?"3.0":"CVSS:3.1"===n[0]?"3.1":"Error"},getCleanVectorString:function(e){const n=e.split("/"),r=[];for(const e of n){"X"!==e.split(":")[1]&&r.push(e)}return r.join("/")}}},function(e,n,r){const a=r(2);e.exports=a},function(e,n,r){const a=r(0),i=r(4);e.exports=function(e){function n(){return a.getVersion(e)}function r(){return i.getScore(e)}function t(){return i.getTemporalScore(e)}function c(){return i.getEnvironmentalScore(e)}var o;if(o=e,e=a.parseVectorObjectToString(o),"Error"===n())throw new Error("The vector version is not valid");const b=a.isVectorValid(e);if(!b)throw new Error("The vector format is not valid!");return{vector:e,getScore:r,getTemporalScore:t,getEnvironmentalScore:c,getRating:function(){return a.getRating(r())},getTemporalRating:function(){return a.getRating(t())},getEnvironmentalRating:function(){return a.getRating(c())},getVectorObject:function(){return a.getVectorObject(e)},getDetailedVectorObject:function(){return a.getDetailedVectorObject(e)},getVersion:n,getCleanVectorString:function(){return a.getCleanVectorString(e)},isValid:b}}},function(e){e.exports=JSON.parse('{"version":"3.0","definitions":[{"name":"Attack Vector","abbr":"AV","metrics":[{"name":"Network","abbr":"N","numerical":0.85},{"name":"Adjacent","abbr":"A","numerical":0.62},{"name":"Local","abbr":"L","numerical":0.55},{"name":"Physical","abbr":"P","numerical":0.2}]},{"name":"Attack Complexity","abbr":"AC","metrics":[{"name":"Low","abbr":"L","numerical":0.77},{"name":"High","abbr":"H","numerical":0.44}]},{"name":"Privileges Required","abbr":"PR","metrics":[{"name":"None","abbr":"N","numerical":{"changed":0.85,"unchanged":0.85}},{"name":"Low","abbr":"L","numerical":{"changed":0.68,"unchanged":0.62}},{"name":"High","abbr":"H","numerical":{"changed":0.5,"unchanged":0.27}}]},{"name":"User Interaction","abbr":"UI","metrics":[{"name":"None","abbr":"N","numerical":0.85},{"name":"Required","abbr":"R","numerical":0.62}]},{"name":"Scope","abbr":"S","metrics":[{"name":"Unchanged","abbr":"U"},{"name":"Changed","abbr":"C"}]},{"name":"Confidentiality","abbr":"C","metrics":[{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]},{"name":"Integrity","abbr":"I","metrics":[{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]},{"name":"Availability","abbr":"A","metrics":[{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]},{"name":"Exploit Code Maturity","abbr":"E","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"High","abbr":"H","numerical":1},{"name":"Functional","abbr":"F","numerical":0.97},{"name":"Proof of Concept","abbr":"P","numerical":0.94},{"name":"Unproven","abbr":"U","numerical":0.91}]},{"name":"Remediation Level","abbr":"RL","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"Unavailable","abbr":"U","numerical":1},{"name":"Workaround","abbr":"W","numerical":0.97},{"name":"Temporary Fix","abbr":"T","numerical":0.96},{"name":"Official Fix","abbr":"O","numerical":0.95}]},{"name":"Report Confidence","abbr":"RC","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"Confirmed","abbr":"C","numerical":1},{"name":"Reasonable","abbr":"R","numerical":0.96},{"name":"Unknown","abbr":"U","numerical":0.92}]},{"name":"Confidentiality Req.","abbr":"CR","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"High","abbr":"H","numerical":1.5},{"name":"Medium","abbr":"M","numerical":1},{"name":"Low","abbr":"L","numerical":0.5}]},{"name":"Integrity Req.","abbr":"IR","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"High","abbr":"H","numerical":1.5},{"name":"Medium","abbr":"M","numerical":1},{"name":"Low","abbr":"L","numerical":0.5}]},{"name":"Availability Req.","abbr":"AR","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"High","abbr":"H","numerical":1.5},{"name":"Medium","abbr":"M","numerical":1},{"name":"Low","abbr":"L","numerical":0.5}]},{"name":"Modified Attack Vector","abbr":"MAV","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"Network","abbr":"N","numerical":0.85},{"name":"Adjacent","abbr":"A","numerical":0.62},{"name":"Local","abbr":"L","numerical":0.55},{"name":"Physical","abbr":"P","numerical":0.2}]},{"name":"Modified Attack Complexity","abbr":"MAC","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"Low","abbr":"L","numerical":0.77},{"name":"High","abbr":"H","numerical":0.44}]},{"name":"Modified Privileges Required","abbr":"MPR","metrics":[{"name":"Not Defined","abbr":"X","numerical":{"changed":1,"unchanged":1}},{"name":"None","abbr":"N","numerical":{"changed":0.85,"unchanged":0.85}},{"name":"Low","abbr":"L","numerical":{"changed":0.68,"unchanged":0.62}},{"name":"High","abbr":"H","numerical":{"changed":0.5,"unchanged":0.27}}]},{"name":"Modified User Interaction","abbr":"MUI","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"None","abbr":"N","numerical":0.85},{"name":"Required","abbr":"R","numerical":0.62}]},{"name":"Modified Scope","abbr":"MS","metrics":[{"name":"Not Defined","abbr":"X"},{"name":"Unchanged","abbr":"U"},{"name":"Changed","abbr":"C"}]},{"name":"Modified Confidentiality","abbr":"MC","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]},{"name":"Modified Integrity","abbr":"MI","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]},{"name":"Modified Availability","abbr":"MA","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]}]}')},function(e,n,r){const a=r(0);function i(e){const n=a.getVectorObject(e),r="C"===n.S,i=t(n),o=c(i,r,e);if(o<=0)return 0;const u=b(n,r);return m(r?Math.min(1.08*(o+u),10):Math.min(o+u,10),1,e)}const t=function(e){return 1-(1-a.findMetricValue("C",e).numerical)*(1-a.findMetricValue("I",e).numerical)*(1-a.findMetricValue("A",e).numerical)};const c=function(e,n,r){return n?"3.0"===a.getVersion(r)||"3.1"===a.getVersion(r)?7.52*(e-.029)-3.25*Math.pow(e-.02,15):void 0:6.42*e},o=function(e,n,r){return n?"3.0"===a.getVersion(r)?7.52*(e-.029)-3.25*Math.pow(e-.02,15):"3.1"===a.getVersion(r)?7.52*(e-.029)-3.25*Math.pow(.9731*e-.02,13):void 0:6.42*e},b=function(e,n){const r=a.findMetricValue("AV",e).numerical,i=a.findMetricValue("AC",e).numerical,t=a.findMetricValue("PR",e).numerical,c=a.findMetricValue("UI",e).numerical;return 8.22*r*i*(n?t.changed:t.unchanged)*c};const u=function(e,n){let r=a.findMetricValue("MAV",e),i=a.findMetricValue("MAC",e),t=a.findMetricValue("MPR",e),c=a.findMetricValue("MUI",e);r&&"X"!==r.abbr||(r=a.findMetricValue("AV",e)),i&&"X"!==i.abbr||(i=a.findMetricValue("AC",e)),t&&"X"!==t.abbr||(t=a.findMetricValue("PR",e)),c&&"X"!==c.abbr||(c=a.findMetricValue("UI",e));const o=n?t.numerical.changed:t.numerical.unchanged;return 8.22*r.numerical*i.numerical*o*c.numerical};function m(e,n,r){return"3.0"===a.getVersion(r)?a.roundUpApprox(e,n):"3.1"===a.getVersion(r)?a.roundUpExact(e):void 0}e.exports={getScore:i,getTemporalScore:function(e){const n=a.getVectorObject(e),r=i(e),t=a.findMetricValue("E",n),c=t?t.numerical:1,o=a.findMetricValue("RL",n),b=o?o.numerical:1,u=a.findMetricValue("RC",n);return m(r*c*b*(u?u.numerical:1),1,e)},getEnvironmentalScore:function(e){const n=a.getVectorObject(e),r="X"===n.MS?"C"===n.S:"C"===n.MS,i=function(e){let n=a.findMetricValue("MC",e),r=a.findMetricValue("MI",e),i=a.findMetricValue("MA",e);const t=a.findMetricValue("CR",e).numerical,c=a.findMetricValue("IR",e).numerical,o=a.findMetricValue("AR",e).numerical;n&&"X"!==n.abbr||(n=a.findMetricValue("C",e));r&&"X"!==r.abbr||(r=a.findMetricValue("I",e));i&&"X"!==i.abbr||(i=a.findMetricValue("A",e));return Math.min(1-(1-n.numerical*t)*(1-r.numerical*c)*(1-i.numerical*o),.915)}(n),t=u(n,r),c=o(i,r,e);if(c<=0)return 0;const b=a.findMetricValue("E",n),l=a.findMetricValue("RL",n),f=a.findMetricValue("RC",n),d=b?b.numerical:1,s=l?l.numerical:1,g=f?f.numerical:1;return m(r?m(Math.min(1.08*(c+t),10),1,e)*d*s*g:m(Math.min(c+t,10),1,e)*d*s*g,1,e)}}}]); \ No newline at end of file +var CVSS;(()=>{var e={10:(e,n,r)=>{const a=r(803);e.exports=a},803:(e,n,r)=>{const a=r(502),i=r(14);e.exports=function(e){function n(){return a.getVersion(e)}function r(){return i.getScore(e)}function t(){return i.getTemporalScore(e)}function c(){return i.getEnvironmentalScore(e)}var b;if(b=e,e=a.parseVectorObjectToString(b),"Error"===n())throw new Error("The vector version is not valid");const m=a.isVectorValid(e);if(!m)throw new Error("The vector format is not valid!");return{vector:e,getScore:r,getTemporalScore:t,getEnvironmentalScore:c,getRating:function(){return a.getRating(r())},getTemporalRating:function(){return a.getRating(t())},getEnvironmentalRating:function(){return a.getRating(c())},getVectorObject:function(){return a.getVectorObject(e)},getDetailedVectorObject:function(){return a.getDetailedVectorObject(e)},getVersion:n,getCleanVectorString:function(){return a.getCleanVectorString(e)},isValid:m}}},868:e=>{"use strict";e.exports=JSON.parse('{"version":"3.0","definitions":[{"name":"Attack Vector","abbr":"AV","metrics":[{"name":"Network","abbr":"N","numerical":0.85},{"name":"Adjacent","abbr":"A","numerical":0.62},{"name":"Local","abbr":"L","numerical":0.55},{"name":"Physical","abbr":"P","numerical":0.2}]},{"name":"Attack Complexity","abbr":"AC","metrics":[{"name":"Low","abbr":"L","numerical":0.77},{"name":"High","abbr":"H","numerical":0.44}]},{"name":"Privileges Required","abbr":"PR","metrics":[{"name":"None","abbr":"N","numerical":{"changed":0.85,"unchanged":0.85}},{"name":"Low","abbr":"L","numerical":{"changed":0.68,"unchanged":0.62}},{"name":"High","abbr":"H","numerical":{"changed":0.5,"unchanged":0.27}}]},{"name":"User Interaction","abbr":"UI","metrics":[{"name":"None","abbr":"N","numerical":0.85},{"name":"Required","abbr":"R","numerical":0.62}]},{"name":"Scope","abbr":"S","metrics":[{"name":"Unchanged","abbr":"U"},{"name":"Changed","abbr":"C"}]},{"name":"Confidentiality","abbr":"C","metrics":[{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]},{"name":"Integrity","abbr":"I","metrics":[{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]},{"name":"Availability","abbr":"A","metrics":[{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]},{"name":"Exploit Code Maturity","abbr":"E","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"High","abbr":"H","numerical":1},{"name":"Functional","abbr":"F","numerical":0.97},{"name":"Proof of Concept","abbr":"P","numerical":0.94},{"name":"Unproven","abbr":"U","numerical":0.91}]},{"name":"Remediation Level","abbr":"RL","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"Unavailable","abbr":"U","numerical":1},{"name":"Workaround","abbr":"W","numerical":0.97},{"name":"Temporary Fix","abbr":"T","numerical":0.96},{"name":"Official Fix","abbr":"O","numerical":0.95}]},{"name":"Report Confidence","abbr":"RC","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"Confirmed","abbr":"C","numerical":1},{"name":"Reasonable","abbr":"R","numerical":0.96},{"name":"Unknown","abbr":"U","numerical":0.92}]},{"name":"Confidentiality Req.","abbr":"CR","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"High","abbr":"H","numerical":1.5},{"name":"Medium","abbr":"M","numerical":1},{"name":"Low","abbr":"L","numerical":0.5}]},{"name":"Integrity Req.","abbr":"IR","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"High","abbr":"H","numerical":1.5},{"name":"Medium","abbr":"M","numerical":1},{"name":"Low","abbr":"L","numerical":0.5}]},{"name":"Availability Req.","abbr":"AR","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"High","abbr":"H","numerical":1.5},{"name":"Medium","abbr":"M","numerical":1},{"name":"Low","abbr":"L","numerical":0.5}]},{"name":"Modified Attack Vector","abbr":"MAV","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"Network","abbr":"N","numerical":0.85},{"name":"Adjacent","abbr":"A","numerical":0.62},{"name":"Local","abbr":"L","numerical":0.55},{"name":"Physical","abbr":"P","numerical":0.2}]},{"name":"Modified Attack Complexity","abbr":"MAC","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"Low","abbr":"L","numerical":0.77},{"name":"High","abbr":"H","numerical":0.44}]},{"name":"Modified Privileges Required","abbr":"MPR","metrics":[{"name":"Not Defined","abbr":"X","numerical":{"changed":1,"unchanged":1}},{"name":"None","abbr":"N","numerical":{"changed":0.85,"unchanged":0.85}},{"name":"Low","abbr":"L","numerical":{"changed":0.68,"unchanged":0.62}},{"name":"High","abbr":"H","numerical":{"changed":0.5,"unchanged":0.27}}]},{"name":"Modified User Interaction","abbr":"MUI","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"None","abbr":"N","numerical":0.85},{"name":"Required","abbr":"R","numerical":0.62}]},{"name":"Modified Scope","abbr":"MS","metrics":[{"name":"Not Defined","abbr":"X"},{"name":"Unchanged","abbr":"U"},{"name":"Changed","abbr":"C"}]},{"name":"Modified Confidentiality","abbr":"MC","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]},{"name":"Modified Integrity","abbr":"MI","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]},{"name":"Modified Availability","abbr":"MA","metrics":[{"name":"Not Defined","abbr":"X","numerical":1},{"name":"None","abbr":"N","numerical":0},{"name":"Low","abbr":"L","numerical":0.22},{"name":"High","abbr":"H","numerical":0.56}]}]}')},14:(e,n,r)=>{const a=r(502);function i(e){const n=a.getVectorObject(e),r="C"===n.S,i=t(n),o=c(i,r,e);if(o<=0)return 0;const u=b(n,r);return m(r?Math.min(1.08*(o+u),10):Math.min(o+u,10),1,e)}const t=function(e){return 1-(1-a.findMetricValue("C",e).numerical)*(1-a.findMetricValue("I",e).numerical)*(1-a.findMetricValue("A",e).numerical)},c=function(e,n,r){return n?"3.0"===a.getVersion(r)||"3.1"===a.getVersion(r)?7.52*(e-.029)-3.25*Math.pow(e-.02,15):void 0:6.42*e},b=function(e,n){const r=a.findMetricValue("AV",e).numerical,i=a.findMetricValue("AC",e).numerical,t=a.findMetricValue("PR",e).numerical,c=a.findMetricValue("UI",e).numerical;return 8.22*r*i*(n?t.changed:t.unchanged)*c};function m(e,n,r){return"3.0"===a.getVersion(r)?a.roundUpApprox(e,n):"3.1"===a.getVersion(r)?a.roundUpExact(e):void 0}e.exports={getScore:i,getTemporalScore:function(e){const n=a.getVectorObject(e),r=i(e),t=a.findMetricValue("E",n),c=t?t.numerical:1,b=a.findMetricValue("RL",n),o=b?b.numerical:1,u=a.findMetricValue("RC",n);return m(r*c*o*(u?u.numerical:1),1,e)},getEnvironmentalScore:function(e){const n=a.getVectorObject(e),r="X"===n.MS?"C"===n.S:"C"===n.MS,i=function(e){let n=a.findMetricValue("MC",e),r=a.findMetricValue("MI",e),i=a.findMetricValue("MA",e);const t=a.findMetricValue("CR",e).numerical,c=a.findMetricValue("IR",e).numerical,b=a.findMetricValue("AR",e).numerical;return n&&"X"!==n.abbr||(n=a.findMetricValue("C",e)),r&&"X"!==r.abbr||(r=a.findMetricValue("I",e)),i&&"X"!==i.abbr||(i=a.findMetricValue("A",e)),Math.min(1-(1-n.numerical*t)*(1-r.numerical*c)*(1-i.numerical*b),.915)}(n),t=function(e,n){let r=a.findMetricValue("MAV",e),i=a.findMetricValue("MAC",e),t=a.findMetricValue("MPR",e),c=a.findMetricValue("MUI",e);r&&"X"!==r.abbr||(r=a.findMetricValue("AV",e)),i&&"X"!==i.abbr||(i=a.findMetricValue("AC",e)),t&&"X"!==t.abbr||(t=a.findMetricValue("PR",e)),c&&"X"!==c.abbr||(c=a.findMetricValue("UI",e));const b=n?t.numerical.changed:t.numerical.unchanged;return 8.22*r.numerical*i.numerical*b*c.numerical}(n,r),c=function(e,n,r){return n?"3.0"===a.getVersion(r)?7.52*(e-.029)-3.25*Math.pow(e-.02,15):"3.1"===a.getVersion(r)?7.52*(e-.029)-3.25*Math.pow(.9731*e-.02,13):void 0:6.42*e}(i,r,e);if(c<=0)return 0;const b=a.findMetricValue("E",n),o=a.findMetricValue("RL",n),u=a.findMetricValue("RC",n),l=b?b.numerical:1,d=o?o.numerical:1,f=u?u.numerical:1;return m(r?m(Math.min(1.08*(c+t),10),1,e)*l*d*f:m(Math.min(c+t,10),1,e)*l*d*f,1,e)}}},502:(e,n,r)=>{const a=r(868),i=function(e){return a.definitions.find((n=>n.abbr===e))};e.exports={roundUpExact:function(e){const n=Math.round(1e5*e);return n%1e4==0?n/1e5:(Math.floor(n/1e4)+1)/10},roundUpApprox:function(e,n){return n=Math.pow(10,n),Math.ceil(e*n)/n},getVectorObject:function(e){const n=e.split("/"),r={};a.definitions.forEach((e=>r[e.abbr]="X"));for(const e of n){const n=e.split(":");r[n[0]]=n[1]}return r},getDetailedVectorObject:function(e){return e.split("/").reduce(((e,n,r)=>{const a=n.split(":"),t={...e.metrics};if(r){const n=i(a[0]),r={name:n.name,abbr:n.abbr,fullName:`${n.name} (${n.abbr})`,value:n.metrics.find((e=>e.abbr===a[1])).name,valueAbbr:a[1]};return Object.assign(e,{metrics:Object.assign(t,{[a[0].trim()]:r})})}return Object.assign(e,{[a[0].trim()]:a[1]})}),{metrics:{}})},findMetric:i,findMetricValue:function(e,n){const r=i(e);return r.metrics.find((e=>e.abbr===n[r.abbr]))},getRating:function(e){let n="None";return n=0===e?"None":e<=3.9?"Low":e<=6.9?"Medium":e<=8.9?"High":"Critical",n},isVectorValid:function(e){const n=a.definitions.reduce(((e,n,r)=>{const a=`${n.abbr}:[${n.metrics.reduce(((e,n)=>e+n.abbr),"")}]`;return 0!==r?`(${e}|${a})`:a}),"");if(!new RegExp("^CVSS:3.(0|1)(/"+n+")+$").test(e))return!1;const r=a.definitions.map((e=>new RegExp(`/${e.abbr}:[${e.metrics.reduce(((e,n)=>e+n.abbr),"")}]`,"g")));for(const n of r)if((e.match(n)||[]).length>1)return!1;const i=[/\/AV:[NALP]/g,/\/AC:[LH]/g,/\/PR:[NLH]/g,/\/UI:[NR]/g,/\/S:[UC]/g,/\/C:[NLH]/g,/\/I:[NLH]/g,/\/A:[NLH]/g];for(const n of i)if((e.match(n)||[]).length<1)return!1;return!0},parseVectorObjectToString:function(e){if("string"==typeof e)return e;let n=`CVSS:${e.CVSS}/`;for(const r of a.definitions){const a=r.abbr;Object.prototype.hasOwnProperty.call(e,a)&&(n+=`${a}:${e[a]}/`)}return n=n.slice(0,-1),n},getVersion:function(e){const n=e.split("/");return"CVSS:3.0"===n[0]?"3.0":"CVSS:3.1"===n[0]?"3.1":"Error"},getCleanVectorString:function(e){const n=e.split("/"),r=[];for(const e of n)"X"!==e.split(":")[1]&&r.push(e);return r.join("/")}}}},n={},r=function r(a){var i=n[a];if(void 0!==i)return i.exports;var t=n[a]={exports:{}};return e[a](t,t.exports,r),t.exports}(10);CVSS=r})(); \ No newline at end of file diff --git a/dist/score.d.ts b/dist/score.d.ts new file mode 100644 index 0000000..54de1eb --- /dev/null +++ b/dist/score.d.ts @@ -0,0 +1,18 @@ +/** + * Parses the vector to a number score + * + * @returns {Number} Calculated Score + */ +export function getScore(vector: any): number; +/** + * Parses the vector to the temporal score + * + * @returns {Number} Temporal Score + */ +export function getTemporalScore(vector: any): number; +/** + * Parses the vector to the environmental score + * + * @returns {Number} Environmental Score + */ +export function getEnvironmentalScore(vector: any): number; diff --git a/dist/util.d.ts b/dist/util.d.ts new file mode 100644 index 0000000..b1d3607 --- /dev/null +++ b/dist/util.d.ts @@ -0,0 +1,74 @@ +/** + * @param {Number} num The number to round + * + * @returns The rounded number + */ +export function roundUpExact(num: number): number; +/** + * @param {Number} num The number to round + * @param {Number} precision The number of decimal places to preserve + * + * @returns The rounded number + */ +export function roundUpApprox(num: number, precision: number): number; +/** + * Retrieves an object of vector's metrics + * + * @param {String} vector + * @returns {Object} Abbreviations & Vector Value pair + */ +export function getVectorObject(vector: string): any; +/** + * Retrieves an object of vector's metrics + * + * @param {String} vector + * @returns {Object} Abbreviations & Vectors Detailed Values + */ +export function getDetailedVectorObject(vector: string): any; +/** + * Finds the vector's metric by it's abbreviation + * + * @param {String} abbr + */ +export function findMetric(abbr: string): any; +/** + * Finds the vector's value for a specific metric + * + * @param {String} abbr + * @param {Object} vectorObject + */ +export function findMetricValue(abbr: string, vectorObject: any): any; +/** + * Calculates the rating of the given vector + * + * @param Score calculated score from getScore() in cvss.js + * @returns {String} returns one of the five possible ratings + */ +export function getRating(score: any): string; +/** + * Checks whether the vector passed is valid + * + * @param {String} vector + * @returns {Boolean} result with whether the vector is valid or not + */ +export function isVectorValid(vector: string): boolean; +/** + * This transforms an object in the format of getVectorObject() + * and parses it to a CVSS comaptible string + * + * @param {Object} obj + */ +export function parseVectorObjectToString(obj: any): string; +/** + * Retrives the version from the vector string + * + * @return {String} returns the version number + */ +export function getVersion(vector: any): string; +/** + * Returns a vector without undefined values + * + * @param {String} vector + * @returns {String} Vector without undefined values + */ +export function getCleanVectorString(vector: string): string; diff --git a/package.json b/package.json index 05fe212..ed90299 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "@turingpointde/cvss.js", - "version": "1.4.5", + "version": "1.4.6", "description": "A tiny library to work with cvss vectors", "scripts": { - "build": "webpack", + "build": "webpack && tsc", "start": "node index.js", "lint": "npx eslint ./", "test": "jest --detectOpenHandles --forceExit" @@ -14,6 +14,7 @@ "devDependencies": { "eslint": "^7.30.0", "jest": "^27.0.6", + "typescript": "^4.3.5", "webpack": "^5.44.0", "webpack-cli": "^4.7.2" }, diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ae816bb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "include": ["lib/**/*"], + "compilerOptions": { + "allowJs": true, + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "dist" + } +} diff --git a/yarn.lock b/yarn.lock index 9693769..85e5a8d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3383,6 +3383,11 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +typescript@^4.3.5: + version "4.3.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" + integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== + universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"