diff --git a/data/schema/SSVC_Computed_v2.01.schema.json b/data/schema/SSVC_Computed_v2.01.schema.json deleted file mode 100644 index 0ccb1024..00000000 --- a/data/schema/SSVC_Computed_v2.01.schema.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "$id": "https://democert.org/ssvc/SVC_Computed_v2.01.schema.json", - "title": "Computed SSVC score representing the path in the decision tree", - "description": "This schema represents the full path in the decision tree taken by an analyst with a specific role. The representation of the full decision tree is optional", - "type": "object", - "properties": { - "choices": { - "type": "array", - "items": { - "type": "object", - "patternProperties": { - ".*": { - "type": ["array","string"], - "items": { - "type": "string" - } - } - } - }, - "minItems": 1, - "uniqueItems": true - }, - "timestamp" : { - "description": "Date and time in ISO format ISO 8601 format", - "type": "string", - "format": "date-time" - }, - "role": { - "type": "string", - "description": "Roles are defined in SSVC spec and optional in SSVC provision schema" - }, - "version": { - "type": "string", - "description":"Version of the SSVC that was used in this decision" - }, - "decision_tree": { - "description": "The full decision tree that was used for this SSVC computed score", - "$ref": "https://democert.org/ssvc/SSVC_Provision_v2.01.schema.json" - } - }, - "required": [ - "choices", - "timestamp", - "role", - "id", - "version" - ] -} diff --git a/data/schema/SSVC_Provision_v2.01.schema.json b/data/schema/SSVC_Provision_v2.01.schema.json deleted file mode 100644 index ef81dcc7..00000000 --- a/data/schema/SSVC_Provision_v2.01.schema.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "$id": "https://democert.org/ssvc/SSVC_Provision_v2.01.schema.json", - "title": "Decision tree schema definition for SSVC", - "description": "This provides a schema for a decision tree used to compute SSVC score for a vulnerability", - "type": "object", - "definitions": { - "decision_points": { - "description": "Decision points are represented an an array of Nodes (in the decision tree language) in the decision tree, including the Root Node. Each decision point has a \"label\" with two or more \"options\" for each decision point", - "type": "array", - "items": { - "type": "object", - "properties": { - "label": { - "description": "A short label that captures a short name of this Node", - "type": "string", - "maxLength": 255 - }, - "key": { - "description": "An optional short \"key\" that identified this \"descision_point\" in SSVC score vector form. This is one or two letter(s) used in short-form vector representation of the SSVC score.", - "maxLength": 2, - "type": "string" - }, - "options": { - "description": "This provides an array of choices that are relevant for leaving a Node in the decision tree to proceed to the next Node. ", - "type": "array", - "items": { - "type": "object", - "properties": { - "description": { - "description": "This should provide full information about this \"option\" ", - "maxLength": 65535, - "type": "string" - }, - "label": { - "description": "A short label of this \"option\" or choice.", - "maxLength": 255, - "type": "string" - }, - "key": { - "description": "An optional short \"key\" that identified this \"descision_point\" in SSVC score vector form. This is one or two letter(s) used in short-form vector representation of the SSVC score.", - "type": "string", - "maxLength": 2 - }, - "color": { - "description": "This is an optional color to represent the final edge node or final recommended action provided by the SSVC tree. This is preferably predefined color names, or with RGB, HEX, HSL, RGBA, or HSLA values.", - "type": "string", - "maxLength": 127 - } - }, - "required": [ - "label", - "description", - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "decision_type": { - "type": "string", - "enum": [ - "child", - "complex", - "simple", - "final" - ], - "description": "Decision Type is used to identify if this is a \"simple\" decision or a \"complex\" decision. The \"complex\" decisions can have \"child\" decisions under them. The \"final\" decision basically is the last node on the decision tree" - }, - "children": { - "type": "array", - "items": { "$ref": "#/definitions/decision_points" }, - "minItems": 1 - } - }, - "anyOf": [ - { - "required": [ - "decision_type", - "label", - "children" - ] - }, - { - "required": [ - "decision_type", - "label", - "options" - ] - } - ] - }, - "minItems": 1 - } - }, - "properties": { - "decision_points": { "$ref": "#/definitions/decision_points" }, - "decisions_table": { - "type": "array", - "items": { - "type": "object" - }, - "minItems": 1, - "type": "array" - }, - "lang": { - "maxLength": 7, - "type": "string" - }, - "roles": { - "description": "Roles as described in SSVC as distinct array elements", - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1, - "uniqueItems": true - }, - "title": { - "maxLength": 255, - "type": "string" - }, - "version": { - "enum": [ - "1.0", - "2.0" - ] - } - }, - "required": [ - "lang", - "version", - "decision_points", - "decisions_table" - ] -} - diff --git a/data/schema_examples/README.MD b/data/schema_examples/README.MD index 475cea48..fa6c9b9b 100644 --- a/data/schema_examples/README.MD +++ b/data/schema_examples/README.MD @@ -8,3 +8,4 @@ The JSON files here are 3. Computed SSVC score with the full decision tree embedded. + diff --git a/data/v1/csv/ssvc_1_applier.csv b/data/v1/csv/ssvc_1_applier.csv deleted file mode 100644 index e00f414c..00000000 --- a/data/v1/csv/ssvc_1_applier.csv +++ /dev/null @@ -1,226 +0,0 @@ -,Exploitation,Exposure,MissionImpact,SafetyImpact,Outcome -0,none,small,none,none,defer -1,none,small,none,minor,defer -2,none,small,none,major,defer -3,none,small,none,hazardous,scheduled -4,none,small,none,catastrophic,out-of-cycle -5,none,small,degraded,none,defer -6,none,small,degraded,minor,defer -7,none,small,degraded,major,scheduled -8,none,small,degraded,hazardous,scheduled -9,none,small,degraded,catastrophic,out-of-cycle -10,none,small,MEF crippled,none,defer -11,none,small,MEF crippled,minor,scheduled -12,none,small,MEF crippled,major,scheduled -13,none,small,MEF crippled,hazardous,scheduled -14,none,small,MEF crippled,catastrophic,out-of-cycle -15,none,small,MEF fail,none,scheduled -16,none,small,MEF fail,minor,scheduled -17,none,small,MEF fail,major,scheduled -18,none,small,MEF fail,hazardous,scheduled -19,none,small,MEF fail,catastrophic,out-of-cycle -20,none,small,mission fail,none,scheduled -21,none,small,mission fail,minor,scheduled -22,none,small,mission fail,major,scheduled -23,none,small,mission fail,hazardous,scheduled -24,none,small,mission fail,catastrophic,out-of-cycle -25,none,controlled,none,none,defer -26,none,controlled,none,minor,defer -27,none,controlled,none,major,scheduled -28,none,controlled,none,hazardous,out-of-cycle -29,none,controlled,none,catastrophic,out-of-cycle -30,none,controlled,degraded,none,defer -31,none,controlled,degraded,minor,defer -32,none,controlled,degraded,major,scheduled -33,none,controlled,degraded,hazardous,out-of-cycle -34,none,controlled,degraded,catastrophic,out-of-cycle -35,none,controlled,MEF crippled,none,defer -36,none,controlled,MEF crippled,minor,scheduled -37,none,controlled,MEF crippled,major,scheduled -38,none,controlled,MEF crippled,hazardous,out-of-cycle -39,none,controlled,MEF crippled,catastrophic,out-of-cycle -40,none,controlled,MEF fail,none,scheduled -41,none,controlled,MEF fail,minor,scheduled -42,none,controlled,MEF fail,major,scheduled -43,none,controlled,MEF fail,hazardous,out-of-cycle -44,none,controlled,MEF fail,catastrophic,out-of-cycle -45,none,controlled,mission fail,none,out-of-cycle -46,none,controlled,mission fail,minor,out-of-cycle -47,none,controlled,mission fail,major,out-of-cycle -48,none,controlled,mission fail,hazardous,out-of-cycle -49,none,controlled,mission fail,catastrophic,out-of-cycle -50,none,open,none,none,defer -51,none,open,none,minor,scheduled -52,none,open,none,major,scheduled -53,none,open,none,hazardous,out-of-cycle -54,none,open,none,catastrophic,immediate -55,none,open,degraded,none,defer -56,none,open,degraded,minor,scheduled -57,none,open,degraded,major,scheduled -58,none,open,degraded,hazardous,out-of-cycle -59,none,open,degraded,catastrophic,immediate -60,none,open,MEF crippled,none,scheduled -61,none,open,MEF crippled,minor,scheduled -62,none,open,MEF crippled,major,scheduled -63,none,open,MEF crippled,hazardous,out-of-cycle -64,none,open,MEF crippled,catastrophic,immediate -65,none,open,MEF fail,none,scheduled -66,none,open,MEF fail,minor,scheduled -67,none,open,MEF fail,major,out-of-cycle -68,none,open,MEF fail,hazardous,out-of-cycle -69,none,open,MEF fail,catastrophic,immediate -70,none,open,mission fail,none,out-of-cycle -71,none,open,mission fail,minor,out-of-cycle -72,none,open,mission fail,major,out-of-cycle -73,none,open,mission fail,hazardous,out-of-cycle -74,none,open,mission fail,catastrophic,immediate -75,poc,small,none,none,defer -76,poc,small,none,minor,defer -77,poc,small,none,major,scheduled -78,poc,small,none,hazardous,scheduled -79,poc,small,none,catastrophic,out-of-cycle -80,poc,small,degraded,none,defer -81,poc,small,degraded,minor,defer -82,poc,small,degraded,major,scheduled -83,poc,small,degraded,hazardous,scheduled -84,poc,small,degraded,catastrophic,out-of-cycle -85,poc,small,MEF crippled,none,scheduled -86,poc,small,MEF crippled,minor,scheduled -87,poc,small,MEF crippled,major,scheduled -88,poc,small,MEF crippled,hazardous,out-of-cycle -89,poc,small,MEF crippled,catastrophic,out-of-cycle -90,poc,small,MEF fail,none,scheduled -91,poc,small,MEF fail,minor,scheduled -92,poc,small,MEF fail,major,scheduled -93,poc,small,MEF fail,hazardous,out-of-cycle -94,poc,small,MEF fail,catastrophic,immediate -95,poc,small,mission fail,none,scheduled -96,poc,small,mission fail,minor,scheduled -97,poc,small,mission fail,major,out-of-cycle -98,poc,small,mission fail,hazardous,out-of-cycle -99,poc,small,mission fail,catastrophic,immediate -100,poc,controlled,none,none,defer -101,poc,controlled,none,minor,defer -102,poc,controlled,none,major,scheduled -103,poc,controlled,none,hazardous,out-of-cycle -104,poc,controlled,none,catastrophic,immediate -105,poc,controlled,degraded,none,defer -106,poc,controlled,degraded,minor,scheduled -107,poc,controlled,degraded,major,scheduled -108,poc,controlled,degraded,hazardous,out-of-cycle -109,poc,controlled,degraded,catastrophic,immediate -110,poc,controlled,MEF crippled,none,scheduled -111,poc,controlled,MEF crippled,minor,scheduled -112,poc,controlled,MEF crippled,major,scheduled -113,poc,controlled,MEF crippled,hazardous,out-of-cycle -114,poc,controlled,MEF crippled,catastrophic,immediate -115,poc,controlled,MEF fail,none,scheduled -116,poc,controlled,MEF fail,minor,scheduled -117,poc,controlled,MEF fail,major,out-of-cycle -118,poc,controlled,MEF fail,hazardous,out-of-cycle -119,poc,controlled,MEF fail,catastrophic,immediate -120,poc,controlled,mission fail,none,immediate -121,poc,controlled,mission fail,minor,immediate -122,poc,controlled,mission fail,major,immediate -123,poc,controlled,mission fail,hazardous,immediate -124,poc,controlled,mission fail,catastrophic,immediate -125,poc,open,none,none,defer -126,poc,open,none,minor,scheduled -127,poc,open,none,major,scheduled -128,poc,open,none,hazardous,out-of-cycle -129,poc,open,none,catastrophic,immediate -130,poc,open,degraded,none,scheduled -131,poc,open,degraded,minor,scheduled -132,poc,open,degraded,major,out-of-cycle -133,poc,open,degraded,hazardous,out-of-cycle -134,poc,open,degraded,catastrophic,immediate -135,poc,open,MEF crippled,none,scheduled -136,poc,open,MEF crippled,minor,scheduled -137,poc,open,MEF crippled,major,out-of-cycle -138,poc,open,MEF crippled,hazardous,out-of-cycle -139,poc,open,MEF crippled,catastrophic,immediate -140,poc,open,MEF fail,none,out-of-cycle -141,poc,open,MEF fail,minor,out-of-cycle -142,poc,open,MEF fail,major,out-of-cycle -143,poc,open,MEF fail,hazardous,out-of-cycle -144,poc,open,MEF fail,catastrophic,immediate -145,poc,open,mission fail,none,immediate -146,poc,open,mission fail,minor,immediate -147,poc,open,mission fail,major,immediate -148,poc,open,mission fail,hazardous,immediate -149,poc,open,mission fail,catastrophic,immediate -150,active,small,none,none,defer -151,active,small,none,minor,defer -152,active,small,none,major,scheduled -153,active,small,none,hazardous,out-of-cycle -154,active,small,none,catastrophic,immediate -155,active,small,degraded,none,defer -156,active,small,degraded,minor,scheduled -157,active,small,degraded,major,scheduled -158,active,small,degraded,hazardous,out-of-cycle -159,active,small,degraded,catastrophic,immediate -160,active,small,MEF crippled,none,scheduled -161,active,small,MEF crippled,minor,scheduled -162,active,small,MEF crippled,major,scheduled -163,active,small,MEF crippled,hazardous,out-of-cycle -164,active,small,MEF crippled,catastrophic,immediate -165,active,small,MEF fail,none,scheduled -166,active,small,MEF fail,minor,scheduled -167,active,small,MEF fail,major,out-of-cycle -168,active,small,MEF fail,hazardous,out-of-cycle -169,active,small,MEF fail,catastrophic,immediate -170,active,small,mission fail,none,out-of-cycle -171,active,small,mission fail,minor,out-of-cycle -172,active,small,mission fail,major,out-of-cycle -173,active,small,mission fail,hazardous,immediate -174,active,small,mission fail,catastrophic,immediate -175,active,controlled,none,none,defer -176,active,controlled,none,minor,scheduled -177,active,controlled,none,major,scheduled -178,active,controlled,none,hazardous,out-of-cycle -179,active,controlled,none,catastrophic,immediate -180,active,controlled,degraded,none,scheduled -181,active,controlled,degraded,minor,scheduled -182,active,controlled,degraded,major,out-of-cycle -183,active,controlled,degraded,hazardous,out-of-cycle -184,active,controlled,degraded,catastrophic,immediate -185,active,controlled,MEF crippled,none,scheduled -186,active,controlled,MEF crippled,minor,scheduled -187,active,controlled,MEF crippled,major,out-of-cycle -188,active,controlled,MEF crippled,hazardous,out-of-cycle -189,active,controlled,MEF crippled,catastrophic,immediate -190,active,controlled,MEF fail,none,out-of-cycle -191,active,controlled,MEF fail,minor,out-of-cycle -192,active,controlled,MEF fail,major,out-of-cycle -193,active,controlled,MEF fail,hazardous,immediate -194,active,controlled,MEF fail,catastrophic,immediate -195,active,controlled,mission fail,none,immediate -196,active,controlled,mission fail,minor,immediate -197,active,controlled,mission fail,major,immediate -198,active,controlled,mission fail,hazardous,immediate -199,active,controlled,mission fail,catastrophic,immediate -200,active,open,none,none,defer -201,active,open,none,minor,scheduled -202,active,open,none,major,out-of-cycle -203,active,open,none,hazardous,immediate -204,active,open,none,catastrophic,immediate -205,active,open,degraded,none,scheduled -206,active,open,degraded,minor,out-of-cycle -207,active,open,degraded,major,out-of-cycle -208,active,open,degraded,hazardous,immediate -209,active,open,degraded,catastrophic,immediate -210,active,open,MEF crippled,none,out-of-cycle -211,active,open,MEF crippled,minor,out-of-cycle -212,active,open,MEF crippled,major,out-of-cycle -213,active,open,MEF crippled,hazardous,immediate -214,active,open,MEF crippled,catastrophic,immediate -215,active,open,MEF fail,none,immediate -216,active,open,MEF fail,minor,immediate -217,active,open,MEF fail,major,immediate -218,active,open,MEF fail,hazardous,immediate -219,active,open,MEF fail,catastrophic,immediate -220,active,open,mission fail,none,immediate -221,active,open,mission fail,minor,immediate -222,active,open,mission fail,major,immediate -223,active,open,mission fail,hazardous,immediate -224,active,open,mission fail,catastrophic,immediate \ No newline at end of file diff --git a/data/v1/csv/ssvc_1_developer.csv b/data/v1/csv/ssvc_1_developer.csv deleted file mode 100644 index 1edcb3a1..00000000 --- a/data/v1/csv/ssvc_1_developer.csv +++ /dev/null @@ -1,91 +0,0 @@ -,Exploitation,Utility,TechnicalImpact,SafetyImpact,Outcome -0,none,laborious,partial,none,defer -1,none,laborious,partial,minor,defer -2,none,laborious,partial,major,scheduled -3,none,laborious,partial,hazardous,scheduled -4,none,laborious,partial,catastrophic,scheduled -5,none,laborious,total,none,defer -6,none,laborious,total,minor,defer -7,none,laborious,total,major,scheduled -8,none,laborious,total,hazardous,scheduled -9,none,laborious,total,catastrophic,out-of-cycle -10,none,efficient,partial,none,defer -11,none,efficient,partial,minor,scheduled -12,none,efficient,partial,major,scheduled -13,none,efficient,partial,hazardous,scheduled -14,none,efficient,partial,catastrophic,out-of-cycle -15,none,efficient,total,none,scheduled -16,none,efficient,total,minor,scheduled -17,none,efficient,total,major,scheduled -18,none,efficient,total,hazardous,out-of-cycle -19,none,efficient,total,catastrophic,out-of-cycle -20,none,super effective,partial,none,scheduled -21,none,super effective,partial,minor,scheduled -22,none,super effective,partial,major,scheduled -23,none,super effective,partial,hazardous,out-of-cycle -24,none,super effective,partial,catastrophic,out-of-cycle -25,none,super effective,total,none,scheduled -26,none,super effective,total,minor,scheduled -27,none,super effective,total,major,scheduled -28,none,super effective,total,hazardous,out-of-cycle -29,none,super effective,total,catastrophic,out-of-cycle -30,poc,laborious,partial,none,scheduled -31,poc,laborious,partial,minor,scheduled -32,poc,laborious,partial,major,out-of-cycle -33,poc,laborious,partial,hazardous,out-of-cycle -34,poc,laborious,partial,catastrophic,out-of-cycle -35,poc,laborious,total,none,scheduled -36,poc,laborious,total,minor,scheduled -37,poc,laborious,total,major,out-of-cycle -38,poc,laborious,total,hazardous,out-of-cycle -39,poc,laborious,total,catastrophic,immediate -40,poc,efficient,partial,none,scheduled -41,poc,efficient,partial,minor,scheduled -42,poc,efficient,partial,major,out-of-cycle -43,poc,efficient,partial,hazardous,immediate -44,poc,efficient,partial,catastrophic,immediate -45,poc,efficient,total,none,scheduled -46,poc,efficient,total,minor,out-of-cycle -47,poc,efficient,total,major,out-of-cycle -48,poc,efficient,total,hazardous,immediate -49,poc,efficient,total,catastrophic,immediate -50,poc,super effective,partial,none,scheduled -51,poc,super effective,partial,minor,out-of-cycle -52,poc,super effective,partial,major,out-of-cycle -53,poc,super effective,partial,hazardous,immediate -54,poc,super effective,partial,catastrophic,immediate -55,poc,super effective,total,none,out-of-cycle -56,poc,super effective,total,minor,out-of-cycle -57,poc,super effective,total,major,out-of-cycle -58,poc,super effective,total,hazardous,immediate -59,poc,super effective,total,catastrophic,immediate -60,active,laborious,partial,none,scheduled -61,active,laborious,partial,minor,out-of-cycle -62,active,laborious,partial,major,out-of-cycle -63,active,laborious,partial,hazardous,immediate -64,active,laborious,partial,catastrophic,immediate -65,active,laborious,total,none,out-of-cycle -66,active,laborious,total,minor,out-of-cycle -67,active,laborious,total,major,out-of-cycle -68,active,laborious,total,hazardous,immediate -69,active,laborious,total,catastrophic,immediate -70,active,efficient,partial,none,out-of-cycle -71,active,efficient,partial,minor,out-of-cycle -72,active,efficient,partial,major,immediate -73,active,efficient,partial,hazardous,immediate -74,active,efficient,partial,catastrophic,immediate -75,active,efficient,total,none,out-of-cycle -76,active,efficient,total,minor,out-of-cycle -77,active,efficient,total,major,immediate -78,active,efficient,total,hazardous,immediate -79,active,efficient,total,catastrophic,immediate -80,active,super effective,partial,none,out-of-cycle -81,active,super effective,partial,minor,immediate -82,active,super effective,partial,major,immediate -83,active,super effective,partial,hazardous,immediate -84,active,super effective,partial,catastrophic,immediate -85,active,super effective,total,none,immediate -86,active,super effective,total,minor,immediate -87,active,super effective,total,major,immediate -88,active,super effective,total,hazardous,immediate -89,active,super effective,total,catastrophic,immediate diff --git a/data/v2/README.md b/data/v2/README.md deleted file mode 100644 index ce67a146..00000000 --- a/data/v2/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# SSVC v2 CSV files - -Here is a list of files in the /data/v2/csv directory: - -* ssvc_2_coord-publish.csv - Coordinator Publication Priority -* ssvc_2_coord-triage.csv - Coordinator Case Priority -* ssvc_2_deployer.csv - Deployer Priority -* ssvc_2_supplier.csv - Supplier Priority diff --git a/data/v2/csv/ssvc_2_coord-publish.csv b/data/v2/csv/ssvc_2_coord-publish.csv deleted file mode 100644 index df25def7..00000000 --- a/data/v2/csv/ssvc_2_coord-publish.csv +++ /dev/null @@ -1,28 +0,0 @@ -Supplier involvement,Exploitation,Value added,Outcome -fix ready,none,precedence,publish -fix ready,PoC,precedence,publish -fix ready,active,precedence,publish -cooperative,none,precedence,publish -cooperative,PoC,precedence,publish -cooperative,active,precedence,publish -un-coop/responsive,none,precedence,publish -un-coop/responsive,PoC,precedence,publish -un-coop/responsive,active,precedence,publish -fix ready,none,ampliative,don't publish -fix ready,PoC,ampliative,don't publish -fix ready,active,ampliative,publish -cooperative,none,ampliative,don't publish -cooperative,PoC,ampliative,don't publish -cooperative,active,ampliative,publish -un-coop/responsive,none,ampliative,don't publish -un-coop/responsive,PoC,ampliative,publish -un-coop/responsive,active,ampliative,publish -fix ready,none,limited,don't publish -fix ready,PoC,limited,don't publish -fix ready,active,limited,don't publish -cooperative,none,limited,don't publish -cooperative,PoC,limited,don't publish -cooperative,active,limited,don't publish -un-coop/responsive,none,limited,don't publish -un-coop/responsive,PoC,limited,don't publish -un-coop/responsive,active,limited,don't publish diff --git a/data/v2/csv/ssvc_2_coord-triage.csv b/data/v2/csv/ssvc_2_coord-triage.csv deleted file mode 100644 index 9ca8fc6c..00000000 --- a/data/v2/csv/ssvc_2_coord-triage.csv +++ /dev/null @@ -1,49 +0,0 @@ -Public,Contacted,Credible,Cardinality,Engagement,Utility,PublicSafetyImpact,Outcome -No,Yes,Yes,one,active,laborious,minimal,decline -No,Yes,Yes,one,active,laborious,significant,decline -No,Yes,Yes,one,active,efficient,minimal,decline -No,Yes,Yes,one,active,efficient,significant,track -No,Yes,Yes,one,active,super-effective,minimal,decline -No,Yes,Yes,one,active,super-effective,significant,track -No,Yes,Yes,one,unresponsive,laborious,minimal,track -No,Yes,Yes,one,unresponsive,laborious,significant,coordinate -No,Yes,Yes,one,unresponsive,efficient,minimal,coordinate -No,Yes,Yes,one,unresponsive,efficient,significant,coordinate -No,Yes,Yes,one,unresponsive,super-effective,minimal,coordinate -No,Yes,Yes,one,unresponsive,super-effective,significant,coordinate -No,Yes,Yes,multiple,active,laborious,minimal,decline -No,Yes,Yes,multiple,active,laborious,significant,track -No,Yes,Yes,multiple,active,efficient,minimal,decline -No,Yes,Yes,multiple,active,efficient,significant,track -No,Yes,Yes,multiple,active,super-effective,minimal,coordinate -No,Yes,Yes,multiple,active,super-effective,significant,coordinate -No,Yes,Yes,multiple,unresponsive,laborious,minimal,coordinate -No,Yes,Yes,multiple,unresponsive,laborious,significant,coordinate -No,Yes,Yes,multiple,unresponsive,efficient,minimal,coordinate -No,Yes,Yes,multiple,unresponsive,efficient,significant,coordinate -No,Yes,Yes,multiple,unresponsive,super-effective,minimal,coordinate -No,Yes,Yes,multiple,unresponsive,super-effective,significant,coordinate -No,Yes,No,one,active,laborious,minimal,decline -No,Yes,No,one,active,laborious,significant,decline -No,Yes,No,one,active,efficient,minimal,decline -No,Yes,No,one,active,efficient,significant,track -No,Yes,No,one,active,super-effective,minimal,decline -No,Yes,No,one,active,super-effective,significant,track -No,Yes,No,one,unresponsive,laborious,minimal,decline -No,Yes,No,one,unresponsive,laborious,significant,decline -No,Yes,No,one,unresponsive,efficient,minimal,decline -No,Yes,No,one,unresponsive,efficient,significant,track -No,Yes,No,one,unresponsive,super-effective,minimal,decline -No,Yes,No,one,unresponsive,super-effective,significant,track -No,Yes,No,multiple,active,laborious,minimal,decline -No,Yes,No,multiple,active,laborious,significant,track -No,Yes,No,multiple,active,efficient,minimal,decline -No,Yes,No,multiple,active,efficient,significant,track -No,Yes,No,multiple,active,super-effective,minimal,track -No,Yes,No,multiple,active,super-effective,significant,coordinate -No,Yes,No,multiple,unresponsive,laborious,minimal,decline -No,Yes,No,multiple,unresponsive,laborious,significant,track -No,Yes,No,multiple,unresponsive,efficient,minimal,decline -No,Yes,No,multiple,unresponsive,efficient,significant,track -No,Yes,No,multiple,unresponsive,super-effective,minimal,track -No,Yes,No,multiple,unresponsive,super-effective,significant,coordinate diff --git a/data/v2/csv/ssvc_2_deployer.csv b/data/v2/csv/ssvc_2_deployer.csv deleted file mode 100644 index 67e0699e..00000000 --- a/data/v2/csv/ssvc_2_deployer.csv +++ /dev/null @@ -1,109 +0,0 @@ -Exploitation,Exposure,Utility,Well-being and Mission Impact,Outcome -none,small,laborious,low,defer -none,small,laborious,medium,defer -none,small,laborious,high,scheduled -none,small,laborious,very high,scheduled -none,small,efficient,low,defer -none,small,efficient,medium,scheduled -none,small,efficient,high,scheduled -none,small,efficient,very high,scheduled -none,small,super effective,low,defer -none,small,super effective,medium,scheduled -none,small,super effective,high,scheduled -none,small,super effective,very high,scheduled -none,controlled,laborious,low,defer -none,controlled,laborious,medium,scheduled -none,controlled,laborious,high,scheduled -none,controlled,laborious,very high,scheduled -none,controlled,efficient,low,defer -none,controlled,efficient,medium,scheduled -none,controlled,efficient,high,scheduled -none,controlled,efficient,very high,scheduled -none,controlled,super effective,low,scheduled -none,controlled,super effective,medium,scheduled -none,controlled,super effective,high,scheduled -none,controlled,super effective,very high,scheduled -none,open,laborious,low,defer -none,open,laborious,medium,scheduled -none,open,laborious,high,scheduled -none,open,laborious,very high,scheduled -none,open,efficient,low,scheduled -none,open,efficient,medium,scheduled -none,open,efficient,high,scheduled -none,open,efficient,very high,scheduled -none,open,super effective,low,scheduled -none,open,super effective,medium,scheduled -none,open,super effective,high,scheduled -none,open,super effective,very high,out-of-cycle -PoC,small,laborious,low,defer -PoC,small,laborious,medium,scheduled -PoC,small,laborious,high,scheduled -PoC,small,laborious,very high,scheduled -PoC,small,efficient,low,defer -PoC,small,efficient,medium,scheduled -PoC,small,efficient,high,scheduled -PoC,small,efficient,very high,scheduled -PoC,small,super effective,low,scheduled -PoC,small,super effective,medium,scheduled -PoC,small,super effective,high,scheduled -PoC,small,super effective,very high,scheduled -PoC,controlled,laborious,low,defer -PoC,controlled,laborious,medium,scheduled -PoC,controlled,laborious,high,scheduled -PoC,controlled,laborious,very high,scheduled -PoC,controlled,efficient,low,scheduled -PoC,controlled,efficient,medium,scheduled -PoC,controlled,efficient,high,scheduled -PoC,controlled,efficient,very high,scheduled -PoC,controlled,super effective,low,scheduled -PoC,controlled,super effective,medium,scheduled -PoC,controlled,super effective,high,scheduled -PoC,controlled,super effective,very high,out-of-cycle -PoC,open,laborious,low,defer -PoC,open,laborious,medium,scheduled -PoC,open,laborious,high,scheduled -PoC,open,laborious,very high,out-of-cycle -PoC,open,efficient,low,scheduled -PoC,open,efficient,medium,scheduled -PoC,open,efficient,high,scheduled -PoC,open,efficient,very high,out-of-cycle -PoC,open,super effective,low,scheduled -PoC,open,super effective,medium,scheduled -PoC,open,super effective,high,out-of-cycle -PoC,open,super effective,very high,out-of-cycle -active,small,laborious,low,scheduled -active,small,laborious,medium,scheduled -active,small,laborious,high,out-of-cycle -active,small,laborious,very high,out-of-cycle -active,small,efficient,low,scheduled -active,small,efficient,medium,scheduled -active,small,efficient,high,out-of-cycle -active,small,efficient,very high,out-of-cycle -active,small,super effective,low,scheduled -active,small,super effective,medium,scheduled -active,small,super effective,high,out-of-cycle -active,small,super effective,very high,out-of-cycle -active,controlled,laborious,low,scheduled -active,controlled,laborious,medium,scheduled -active,controlled,laborious,high,out-of-cycle -active,controlled,laborious,very high,out-of-cycle -active,controlled,efficient,low,scheduled -active,controlled,efficient,medium,scheduled -active,controlled,efficient,high,out-of-cycle -active,controlled,efficient,very high,out-of-cycle -active,controlled,super effective,low,scheduled -active,controlled,super effective,medium,out-of-cycle -active,controlled,super effective,high,out-of-cycle -active,controlled,super effective,very high,out-of-cycle -active,open,laborious,low,scheduled -active,open,laborious,medium,scheduled -active,open,laborious,high,out-of-cycle -active,open,laborious,very high,immediate -active,open,efficient,low,scheduled -active,open,efficient,medium,out-of-cycle -active,open,efficient,high,immediate -active,open,efficient,very high,immediate -active,open,super effective,low,out-of-cycle -active,open,super effective,medium,out-of-cycle -active,open,super effective,high,immediate -active,open,super effective,very high,immediate diff --git a/data/v2/csv/ssvc_2_supplier.csv b/data/v2/csv/ssvc_2_supplier.csv deleted file mode 100644 index e2fa9a49..00000000 --- a/data/v2/csv/ssvc_2_supplier.csv +++ /dev/null @@ -1,37 +0,0 @@ -Exploitation,Utility,TechnicalImpact,PublicSafetyImpact,Outcome -none,laborious,partial,minimal,defer -none,laborious,partial,significant,scheduled -none,laborious,total,minimal,defer -none,laborious,total,significant,out-of-cycle -none,efficient,partial,minimal,scheduled -none,efficient,partial,significant,out-of-cycle -none,efficient,total,minimal,scheduled -none,efficient,total,significant,out-of-cycle -none,super effective,partial,minimal,scheduled -none,super effective,partial,significant,out-of-cycle -none,super effective,total,minimal,scheduled -none,super effective,total,significant,out-of-cycle -poc,laborious,partial,minimal,scheduled -poc,laborious,partial,significant,out-of-cycle -poc,laborious,total,minimal,scheduled -poc,laborious,total,significant,immediate -poc,efficient,partial,minimal,scheduled -poc,efficient,partial,significant,immediate -poc,efficient,total,minimal,out-of-cycle -poc,efficient,total,significant,immediate -poc,super effective,partial,minimal,out-of-cycle -poc,super effective,partial,significant,immediate -poc,super effective,total,minimal,out-of-cycle -poc,super effective,total,significant,immediate -active,laborious,partial,minimal,out-of-cycle -active,laborious,partial,significant,immediate -active,laborious,total,minimal,out-of-cycle -active,laborious,total,significant,immediate -active,efficient,partial,minimal,out-of-cycle -active,efficient,partial,significant,immediate -active,efficient,total,minimal,out-of-cycle -active,efficient,total,significant,immediate -active,super effective,partial,minimal,immediate -active,super effective,partial,significant,immediate -active,super effective,total,minimal,immediate -active,super effective,total,significant,immediate diff --git a/ssvc-calc/README.md b/ssvc-calc/README.md index 70966e00..64feb4e8 100644 --- a/ssvc-calc/README.md +++ b/ssvc-calc/README.md @@ -12,7 +12,7 @@ defer, scheduled, out-of-cycle, and immediate. * There are also a number of sample CVE in a dropdown that will auto-select a number of steps in the decision tree * Use the "Start Decision" to navigate the tree for assesing your prioritization for a vulnerability. * You can also import custom decision trees and custom CVE samples for the current decision tree. -* Custom decision trees can be from JSON see example [sample-ssvc.json](./sample-ssvc.json) and the JSON schema file [SSVC_JSON_2.0_min.schema.json](./SSVC_JSON_2.0_min.schema.json) -* Customer decision tree can also be just a text file tab-delimited as in [ssvc.txt](./ssvc.txt) OR [ssvc.tsv](./ssvc.tsv) -* CVE samples files [sample-ssvc-scores.txt](./sample-ssvc-scores.txt) shows a tab-delimited +* There is a [data](../data/) folder where there is a number of examples both of schema and examples of schema outputs. +* You can install this directory as a folder in your public website directory. and expose it. All referenced url's are relative in the scripts and HTML files. + diff --git a/ssvc-calc/SSVC_JSON_2.0_min.schema.json b/ssvc-calc/SSVC_JSON_2.0_min.schema.json deleted file mode 100644 index ade7c119..00000000 --- a/ssvc-calc/SSVC_JSON_2.0_min.schema.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "_comment": "This file is moved to ../data/schema/" -} diff --git a/ssvc-calc/css.css b/ssvc-calc/css.css index 6948b391..1518016e 100644 --- a/ssvc-calc/css.css +++ b/ssvc-calc/css.css @@ -1,4 +1,19 @@ -/* css version 2.1 */ +/* css version 2.2 */ +.icon8 { + width:14px; + filter:invert(1); +} +.btn-group.show.primary-button .dropdown-menu, +.btn-group.show.primary-button a.dropdown-item { + color: #fff; + background-color: #0062cc; + border-color: #005cbf; +} +.btn-group.show a.dropdown-item:hover { + color: #eee; + background-color: #0062ff; + border-color: #005cff; +} @media screen and (max-width: 1000px) { .cert-tweet { display: none; } .tright a:nth-child(n+2) { display: none;} @@ -6,10 +21,28 @@ position: absolute; left: 0px; } - .mastfoot { display:none; } #mwb,.tescape { max-width: 450px; } .nomobile { display: none; } } +@media screen and (max-width: 601px) { + .mastfoot { display:none; } + .form-control { + font-size: 12px; + padding: 3px 0px 3px 0px; + font-weight: normal; + height: 20px; + } + .btn { + padding: 2px; + } + #mpopup { + font-size: smaller; + max-width: 400px; + } + #mgraph { + margin-left: 600px; + } +} .decisiontab { background: #222; border: 2px solid white; @@ -41,6 +74,8 @@ } #topalert { display: none; + position: fixed; + opacity: 0.9; } span.bold { font-weight: bold; @@ -83,6 +118,8 @@ span.bold { width:75%; padding:12px; border-radius:10px; + overflow-y: scroll; + overflow-x: scroll; } .top_blue { width: 50%; @@ -100,6 +137,21 @@ span.bold { text-align: center; text-decoration: underline; } +#mpopup h5 { + padding: 0px; + margin: 0px; +} +#mpopup p { + text-align: center; + font-style: italic; + margin: 0px; + padding: 0px; +} +#mpopup blockquote { + border-left: 1px dashed white; + margin-left: 12px; + font-size: 85%; +} #mpopup hr { margin: 2px; } @@ -196,9 +248,8 @@ html,.blackbody { border-radius: 5px; padding: 4px; text-align: left; - max-width: 400px; + max-width: 600px; } - .node { cursor: pointer; } diff --git a/ssvc-calc/index.html b/ssvc-calc/index.html index e589be56..3e854344 100644 --- a/ssvc-calc/index.html +++ b/ssvc-calc/index.html @@ -3,7 +3,7 @@ - CERT/CC Demo Server - SSVC Calc App + CERT/CC Demo Server - Dryad SSVC Calc App - + + + - + CERT Logo
+ title="Dryad SSVC Calc App"> i @@ -68,8 +75,10 @@

- SSVC Calc App -
(Coordinator v2)
+ Dryad - SSVC Calc App +
+ (CISA Coordinator v2) +

- -
+
Exploitation choices
@@ -278,12 +292,12 @@
Public Well-being Impact Decision Values
Stakeholder-Specific Vulnerability Categorization (SSVC)
- version 1 (December 2019) + version 2 (October 2020)

Introduction:

- Our proposed SSVC approach for vulnerability prioritization takes the form of decision trees. This decision tree can be adapted for different vulnerability management stakeholders such as patch developers and patch appliers. In this instance of SSVC app, SSVC is being prototyped for CISA in their unique role as advisors to be able to provide decision support to various stakeholders and influence their prioritization of vulnerabilities. Note: the current actions defined as "Track", "Track*", "Critical" and "High" are likely to be updated. + Our proposed SSVC approach for vulnerability prioritization takes the form of decision trees. This decision tree can be adapted for different vulnerability management stakeholders such as patch developers and patch appliers. In this instance of Drayd - SSVC calculator app, SSVC is being prototyped for CISA in their unique role as advisors to be able to provide decision support to various stakeholders and influence their prioritization of vulnerabilities.

@@ -366,7 +380,7 @@

Decision Tree Usage:

-
@@ -390,15 +404,43 @@

Decision Tree Usage:

@@ -406,7 +448,13 @@

Decision Tree Usage:

- + + diff --git a/ssvc-calc/sample-ssvc-scores.txt b/ssvc-calc/sample-ssvc-scores.txt deleted file mode 100644 index a38aa908..00000000 --- a/ssvc-calc/sample-ssvc-scores.txt +++ /dev/null @@ -1,8 +0,0 @@ -CVE Vulnerability CVSS (v3.x Base Score) SSVC (Decision) Exploit Virulence Technical Mission/Well-Being (Impact) -CVE-2020-7961 Liferay Portal JSON web services (JSONWS) deserialization 9.8 Track PoC Rapid Total Low (Minimal/Minimal) -CVE-2020-5847 Unraid 6.8.0 PHP RCE 9.8 Track PoC Rapid Total Low (Minimal/Minimal) -CVE-2019-0708 Microsoft Windows Remote Desktop RCE (BlueKeep) 9.8 Track* PoC Rapid Total Medium (Support/Material) -CVE-2019-13918 Rockwell Automation MicroLogix Controller open redirect 6.1 Track* PoC Slow Partial High (Essential/Material) -CVE-2019-19781 Citrix directory traversal and Perl RCE 9.8 Critical Active Rapid Total Medium (Support/Minimal) -CVE-2014-0751 GE CIMPLICITY HMI/SCADA directory traversal RCE (Black Energy) 9.8 Critical Active Slow Total High (Essential/Material) -CVE-2018-5734 BIND 9 SERVFAIL assertion failure in badcache.c 7.5 Track None Rapid Partial Medium (Support/Minimal) diff --git a/ssvc-calc/sample-ssvc.json b/ssvc-calc/sample-ssvc.json deleted file mode 100644 index 7f236bbf..00000000 --- a/ssvc-calc/sample-ssvc.json +++ /dev/null @@ -1,371 +0,0 @@ -{ - "decision_points": [ - { - "choices": [ - { - "description": "There is no evidence of active exploitation and no public proof of concept (PoC) of how to exploit the vulnerability.", - "label": "None" - }, - { - "description": "(Proof of Concept)One of the following cases is true: (1) private evidence of exploitation is attested but not shared; (2) widespread hearsay attests to exploitation; (3) typical public PoC in places such as Metasploit or ExploitDB; or (4) the vulnerability has a well-known method of exploitation. Some examples of condition (4) are open-source web proxies serve as the PoC code for how to exploit any vulnerability in the vein of improper validation of TLS certificates. As another example, Wireshark serves as a PoC for packet replay attacks on ethernet or WiFi networks.", - "label": "PoC" - }, - { - "description": "Shared, observable, reliable evidence that the exploit is being used in the wild by real attackers; there is credible public reporting.", - "label": "Active" - } - ], - "label": "Exploitation", - "decision_type": "simple" - }, - { - "choices": [ - { - "description": "Steps 1-4 of the kill chain cannot be reliably automated for this vulnerability for some reason. These steps are reconnaissance, weaponization, delivery, and exploitation. Example reasons for why a step may not be reliably automatable include (1) the vulnerable component is not searchable or enumerable on the network, (2) weaponization may require human direction for each target, (3) delivery may require channels that widely deployed network security configurations block, and (4) exploitation may be frustrated by adequate exploit-prevention techniques enabled by default; ASLR is an example of an exploit-prevention tool.", - "label": "Slow" - }, - { - "description": "Steps 1-4 of the of the kill chain can be reliably automated. If the vulnerability allows unauthenticated remote code execution (RCE) or command injection, the response is likely rapid.", - "label": "Rapid" - } - ], - "label": "Virulence", - "decision_type": "simple" - }, - { - "choices": [ - { - "description": "The exploit gives the adversary limited control over, or information exposure about, the behavior of the software that contains the vulnerability. Or the exploit gives the adversary an importantly low stochastic opportunity for total control. In this context, \"low\" means that the attacker cannot reasonably make enough attempts to overcome the low chance of each attempt not working. Denial of service is a form of limited control over the behavior of the vulnerable component.", - "label": "Partial" - }, - { - "description": "The exploit gives the adversary total control over the behavior of the software, or it gives total disclosure of all information on the system that contains the vulnerability.", - "label": "Total" - } - ], - "label": "Technical Impact", - "decision_type": "simple" - }, - { - "children": [ - "Mission Prevalence", - "Public Well-Being Impact" - ], - "label": "Mission & Well-being", - "decision_type": "complex" - }, - { - "choices": [ - { - "description": "Neither support nor essential apply. The vulnerable component may be used within the entities, but it is not used as a mission-essential component nor does it support (enough) mission essential functions.", - "label": "Minimal" - }, - { - "description": "The operation of the vulnerable component merely supports mission essential functions for two or more entities. Essentially the vulnerable component directly provides capabilities that constitute at least one MEF for at least one entity, and failure may (but need not) lead to overall mission failure.", - "label": "Support" - } - ], - "label": "Mission Prevalence", - "decision_type": "child" - }, - { - "choices": [ - { - "description": "This decision involves combining \"Impact\" and \"Type of Harm\" definitions", - "label": "Minimal" - }, - { - "description": "This decision involves combining \"Impact\" and \"Type of Harm\" definitions", - "label": "Material" - }, - { - "description": "This decision involves combining \"Impact\" and \"Type of Harm\" definitions", - "label": "Irreversible" - } - ], - "label": "Public Well-Being Impact", - "decision_type": "child" - } - ], - "decision_table": [ - { - "Decision": "Track", - "Exploitation": "none", - "Mission & Well-being": "low", - "Technical Impact": "partial", - "Virulence": "slow" - }, - { - "Decision": "Track", - "Exploitation": "none", - "Mission & Well-being": "medium", - "Technical Impact": "partial", - "Virulence": "slow" - }, - { - "Decision": "Track", - "Exploitation": "none", - "Mission & Well-being": "high", - "Technical Impact": "partial", - "Virulence": "slow" - }, - { - "Decision": "Track", - "Exploitation": "none", - "Mission & Well-being": "low", - "Technical Impact": "total", - "Virulence": "slow" - }, - { - "Decision": "Track", - "Exploitation": "none", - "Mission & Well-being": "medium", - "Technical Impact": "total", - "Virulence": "slow" - }, - { - "Decision": "Track*", - "Exploitation": "none", - "Mission & Well-being": "high", - "Technical Impact": "total", - "Virulence": "slow" - }, - { - "Decision": "Track", - "Exploitation": "none", - "Mission & Well-being": "low", - "Technical Impact": "partial", - "Virulence": "rapid" - }, - { - "Decision": "Track", - "Exploitation": "none", - "Mission & Well-being": "medium", - "Technical Impact": "partial", - "Virulence": "rapid" - }, - { - "Decision": "Attend", - "Exploitation": "none", - "Mission & Well-being": "high", - "Technical Impact": "partial", - "Virulence": "rapid" - }, - { - "Decision": "Track", - "Exploitation": "none", - "Mission & Well-being": "low", - "Technical Impact": "total", - "Virulence": "rapid" - }, - { - "Decision": "Track", - "Exploitation": "none", - "Mission & Well-being": "medium", - "Technical Impact": "total", - "Virulence": "rapid" - }, - { - "Decision": "Attend", - "Exploitation": "none", - "Mission & Well-being": "high", - "Technical Impact": "total", - "Virulence": "rapid" - }, - { - "Decision": "Track", - "Exploitation": "poc", - "Mission & Well-being": "low", - "Technical Impact": "partial", - "Virulence": "slow" - }, - { - "Decision": "Track", - "Exploitation": "poc", - "Mission & Well-being": "medium", - "Technical Impact": "partial", - "Virulence": "slow" - }, - { - "Decision": "Track*", - "Exploitation": "poc", - "Mission & Well-being": "high", - "Technical Impact": "partial", - "Virulence": "slow" - }, - { - "Decision": "Track", - "Exploitation": "poc", - "Mission & Well-being": "low", - "Technical Impact": "total", - "Virulence": "slow" - }, - { - "Decision": "Track*", - "Exploitation": "poc", - "Mission & Well-being": "medium", - "Technical Impact": "total", - "Virulence": "slow" - }, - { - "Decision": "Attend", - "Exploitation": "poc", - "Mission & Well-being": "high", - "Technical Impact": "total", - "Virulence": "slow" - }, - { - "Decision": "Track", - "Exploitation": "poc", - "Mission & Well-being": "low", - "Technical Impact": "partial", - "Virulence": "rapid" - }, - { - "Decision": "Track", - "Exploitation": "poc", - "Mission & Well-being": "medium", - "Technical Impact": "partial", - "Virulence": "rapid" - }, - { - "Decision": "Attend", - "Exploitation": "poc", - "Mission & Well-being": "high", - "Technical Impact": "partial", - "Virulence": "rapid" - }, - { - "Decision": "Track", - "Exploitation": "poc", - "Mission & Well-being": "low", - "Technical Impact": "total", - "Virulence": "rapid" - }, - { - "Decision": "Track*", - "Exploitation": "poc", - "Mission & Well-being": "medium", - "Technical Impact": "total", - "Virulence": "rapid" - }, - { - "Decision": "Attend", - "Exploitation": "poc", - "Mission & Well-being": "high", - "Technical Impact": "total", - "Virulence": "rapid" - }, - { - "Decision": "Track", - "Exploitation": "active", - "Mission & Well-being": "low", - "Technical Impact": "partial", - "Virulence": "slow" - }, - { - "Decision": "Track", - "Exploitation": "active", - "Mission & Well-being": "medium", - "Technical Impact": "partial", - "Virulence": "slow" - }, - { - "Decision": "Attend", - "Exploitation": "active", - "Mission & Well-being": "high", - "Technical Impact": "partial", - "Virulence": "slow" - }, - { - "Decision": "Track", - "Exploitation": "active", - "Mission & Well-being": "low", - "Technical Impact": "total", - "Virulence": "slow" - }, - { - "Decision": "Attend", - "Exploitation": "active", - "Mission & Well-being": "medium", - "Technical Impact": "total", - "Virulence": "slow" - }, - { - "Decision": "Act", - "Exploitation": "active", - "Mission & Well-being": "high", - "Technical Impact": "total", - "Virulence": "slow" - }, - { - "Decision": "Attend", - "Exploitation": "active", - "Mission & Well-being": "low", - "Technical Impact": "partial", - "Virulence": "rapid" - }, - { - "Decision": "Attend", - "Exploitation": "active", - "Mission & Well-being": "medium", - "Technical Impact": "partial", - "Virulence": "rapid" - }, - { - "Decision": "Act", - "Exploitation": "active", - "Mission & Well-being": "high", - "Technical Impact": "partial", - "Virulence": "rapid" - }, - { - "Decision": "Attend", - "Exploitation": "active", - "Mission & Well-being": "low", - "Technical Impact": "total", - "Virulence": "rapid" - }, - { - "Decision": "Act", - "Exploitation": "active", - "Mission & Well-being": "medium", - "Technical Impact": "total", - "Virulence": "rapid" - }, - { - "Decision": "Act", - "Exploitation": "active", - "Mission & Well-being": "high", - "Technical Impact": "total", - "Virulence": "rapid" - } - ], - "decisions": [ - { - "description": "The vulnerability does not require attention outside of Vulnerability Management (VM) at this time. Continue to track the situation and reassess the severity of vulnerability if necessary.", - "label": "Track", - "color":"rgba(40,167,69,1)" - - }, - { - "description": "Track these closely, especially if mitigation is unavailable or difficult. Recommended that analyst discuss with other analysts and get a second opinion.", - "label": "Track*", - "color": "rgba(255,193,7,1)" - }, - { - "description": "The vulnerability requires to be attended to by stakeholders outside VM. The action is a request to others for assistance / information / details, as well as a potential publication about the issue.", - "label": "Attend", - "color": "rgba(238, 135, 51,1)" - - }, - { - "description": "The vulnerability requires immediate action by the relevant leadership. The action is a high-priority meeting among the relevant supervisors to decide how to respond.", - "label": "Act", - "color": "rgba(220, 53, 69,1)" - } - ], - "lang": "en", - "version": "2.0", - "title": "CISA Coordinator Decision Tree" -} diff --git a/ssvc-calc/ssvc.js b/ssvc-calc/ssvc.js index 6d66589a..ea21b838 100644 --- a/ssvc-calc/ssvc.js +++ b/ssvc-calc/ssvc.js @@ -1,15 +1,24 @@ /* SSVC code for graph building */ -const _version = 4.2 +const _version = "5.1.1" +const _tool = "Dryad SSVC Calculator "+_version var showFullTree = false var diagonal,tree,svg,duration,root var treeData = [] -/* Deefault color array of possible color choices */ +/* Deefault color array of possible color options */ var acolors = ["#28a745","#ffc107","#EE8733","#dc3545","#ff0000","#aa0000","#ff0000"] -var lcolors = {"Track":"#28a745","Track*":"#ffc107","High":"#EE8733","Critical":"#dc3545"} -lcolors = {"Track":"#28a745","Track*":"#ffc107","Attend":"#EE8733","Act":"#dc3545"} +var lcolors = {"Track":"#28a745","Track*":"#ffc107","Attend":"#EE8733","Act":"#dc3545"} +var ssvc_short_keys = {}; /* These variables are for decision tree schema JSON aka SSVC Provision Schema */ var export_schema = {decision_points: [],decisions_table: [], lang: "en", version: "2.0", title: "SSVC Provision table"} +/* If a new analysis is being done use this for export */ +var current_score = []; +var current_tree = "CISA-Coordinator-v2.02.json"; +var current_schema = "SSVC_Computed_v2.02.schema.json"; +/* A dictionary of elements that are children of a decision point*/ +var ischild = {}; +var isparent = {}; + /* Extend jQuery to support simulate D3 click events */ jQuery.fn.simClick = function () { this.each(function (i, e) { @@ -17,67 +26,36 @@ jQuery.fn.simClick = function () { e.dispatchEvent(evt); }); }; +function reset_form() { + /* This is to clear stupid Firefox cached form values*/ + $('select').prop('selectedIndex',0); + $('input[type="file"]').hide(); + $('input').val(''); + $('select').prop('selectedIndex',0); + $('input[type="file"]').hide(); +} $(function () { - $('[data-toggle="tooltip"]').tooltip() + reset_form(); + $('#topalert').width($('main').width()); + window.onresize = function() { $('#topalert').width($('main').width())} + $('[data-toggle="tooltip"]').tooltip(); if(localStorage.getItem("beenhere")) { - tooltip_cycle_through() + tooltip_cycle_through(); } else { - $('#helper').show() - localStorage.setItem("beenhere",1) + $('#helper').show(); + localStorage.setItem("beenhere",1); } - load_tsv_score() - export_tree() + //load_tsv_score(); + //tree_process("CISA-Coordinator-v2.01.json"); + $.getJSON(current_tree).done(function(idata) { + parse_json(idata); + }).fail(function() { + console.log("Failed to Load CISA tree. Loading default tree"); + }); + export_tree(); + load_tsv_score(); }) -var raw = [ - {name:"Exploitation",id:254,children:[],parent:null,props:"{}"}, - {name:"Virulence:none",id:1,children:[],parent:"Exploitation",props:"{}"}, - {name:"Virulence:poc",id:2,children:[],parent:"Exploitation",props:"{}"}, - {name:"Virulence:active",id:3,children:[],parent:"Exploitation",props:"{}"}, - {name:"Technical Impact:none:slow",id:4,children:[],parent:"Virulence:none",props:"{}"}, - {name:"Technical Impact:none:rapid",id:5,children:[],parent:"Virulence:none",props:"{}"}, - {name:"Technical Impact:poc:slow",id:6,children:[],parent:"Virulence:poc",props:"{}"}, - {name:"Technical Impact:poc:rapid",id:7,children:[],parent:"Virulence:poc",props:"{}"}, - {name:"Technical Impact:active:slow",id:8,children:[],parent:"Virulence:active",props:"{}"}, - {name:"Technical Impact:active:rapid",id:9,children:[],parent:"Virulence:active",props:"{}"}, - {"name":"Mission & Well-being:none:slow:partial","id":11,"children":[],"parent":"Technical Impact:none:slow",props:"{}"},{"name":"Mission & Well-being:none:slow:total","id":12,"children":[],"parent":"Technical Impact:none:slow",props:"{}"},{"name":"Mission & Well-being:none:rapid:partial","id":13,"children":[],"parent":"Technical Impact:none:rapid",props:"{}"},{"name":"Mission & Well-being:none:rapid:total","id":14,"children":[],"parent":"Technical Impact:none:rapid",props:"{}"},{"name":"Mission & Well-being:poc:slow:partial","id":15,"children":[],"parent":"Technical Impact:poc:slow",props:"{}"},{"name":"Mission & Well-being:poc:slow:total","id":16,"children":[],"parent":"Technical Impact:poc:slow",props:"{}"},{"name":"Mission & Well-being:poc:rapid:partial","id":17,"children":[],"parent":"Technical Impact:poc:rapid",props:"{}"},{"name":"Mission & Well-being:poc:rapid:total","id":18,"children":[],"parent":"Technical Impact:poc:rapid",props:"{}"},{"name":"Mission & Well-being:active:slow:partial","id":19,"children":[],"parent":"Technical Impact:active:slow",props:"{}"},{"name":"Mission & Well-being:active:slow:total","id":20,"children":[],"parent":"Technical Impact:active:slow",props:"{}"},{"name":"Mission & Well-being:active:rapid:partial","id":21,"children":[],"parent":"Technical Impact:active:rapid",props:"{}"},{"name":"Mission & Well-being:active:rapid:total","id":22,"children":[],"parent":"Technical Impact:active:rapid",props:"{}"}, - {"name":"Track:none:slow:partial:low","id":24,"children":[],"parent":"Mission & Well-being:none:slow:partial",props:"{}"}, - {"name":"Track:none:slow:partial:medium","id":25,"children":[],"parent":"Mission & Well-being:none:slow:partial",props:"{}"}, - {"name":"Track:none:slow:partial:high","id":26,"children":[],"parent":"Mission & Well-being:none:slow:partial",props:"{}"}, - {"name":"Track:none:slow:total:low","id":27,"children":[],"parent":"Mission & Well-being:none:slow:total",props:"{}"}, - {"name":"Track:none:slow:total:medium","id":28,"children":[],"parent":"Mission & Well-being:none:slow:total",props:"{}"}, - {"name":"Track*:none:slow:total:high","id":29,"children":[],"parent":"Mission & Well-being:none:slow:total",props:"{}"}, - {"name":"Track:none:rapid:partial:low","id":30,"children":[],"parent":"Mission & Well-being:none:rapid:partial",props:"{}"}, - {"name":"Track:none:rapid:partial:medium","id":31,"children":[],"parent":"Mission & Well-being:none:rapid:partial",props:"{}"}, - {"name":"Attend:none:rapid:partial:high","id":32,"children":[],"parent":"Mission & Well-being:none:rapid:partial",props:"{}"}, - {"name":"Track:none:rapid:total:low","id":33,"children":[],"parent":"Mission & Well-being:none:rapid:total",props:"{}"}, - {"name":"Track:none:rapid:total:medium","id":34,"children":[],"parent":"Mission & Well-being:none:rapid:total",props:"{}"}, - {"name":"Attend:none:rapid:total:high","id":35,"children":[],"parent":"Mission & Well-being:none:rapid:total",props:"{}"}, - {"name":"Track:poc:slow:partial:low","id":36,"children":[],"parent":"Mission & Well-being:poc:slow:partial",props:"{}"}, - {"name":"Track:poc:slow:partial:medium","id":37,"children":[],"parent":"Mission & Well-being:poc:slow:partial",props:"{}"}, - {"name":"Track*:poc:slow:partial:high","id":38,"children":[],"parent":"Mission & Well-being:poc:slow:partial",props:"{}"}, - {"name":"Track:poc:slow:total:low","id":39,"children":[],"parent":"Mission & Well-being:poc:slow:total",props:"{}"}, - {"name":"Track*:poc:slow:total:medium","id":40,"children":[],"parent":"Mission & Well-being:poc:slow:total",props:"{}"}, - {"name":"Attend:poc:slow:total:high","id":41,"children":[],"parent":"Mission & Well-being:poc:slow:total",props:"{}"}, - {"name":"Track:poc:rapid:partial:low","id":42,"children":[],"parent":"Mission & Well-being:poc:rapid:partial",props:"{}"}, - {"name":"Track:poc:rapid:partial:medium","id":43,"children":[],"parent":"Mission & Well-being:poc:rapid:partial",props:"{}"}, - {"name":"Attend:poc:rapid:partial:high","id":44,"children":[],"parent":"Mission & Well-being:poc:rapid:partial",props:"{}"}, - {"name":"Track:poc:rapid:total:low","id":45,"children":[],"parent":"Mission & Well-being:poc:rapid:total",props:"{}"}, - {"name":"Track*:poc:rapid:total:medium","id":46,"children":[],"parent":"Mission & Well-being:poc:rapid:total",props:"{}"}, - {"name":"Attend:poc:rapid:total:high","id":47,"children":[],"parent":"Mission & Well-being:poc:rapid:total",props:"{}"}, - {"name":"Track:active:slow:partial:low","id":48,"children":[],"parent":"Mission & Well-being:active:slow:partial",props:"{}"}, - {"name":"Track:active:slow:partial:medium","id":49,"children":[],"parent":"Mission & Well-being:active:slow:partial",props:"{}"}, - {"name":"Attend:active:slow:partial:high","id":50,"children":[],"parent":"Mission & Well-being:active:slow:partial",props:"{}"}, - {"name":"Track:active:slow:total:low","id":51,"children":[],"parent":"Mission & Well-being:active:slow:total",props:"{}"}, - {"name":"Attend:active:slow:total:medium","id":52,"children":[],"parent":"Mission & Well-being:active:slow:total",props:"{}"}, - {"name":"Act:active:slow:total:high","id":53,"children":[],"parent":"Mission & Well-being:active:slow:total",props:"{}"}, - {"name":"Attend:active:rapid:partial:low","id":54,"children":[],"parent":"Mission & Well-being:active:rapid:partial",props:"{}"}, - {"name":"Attend:active:rapid:partial:medium","id":55,"children":[],"parent":"Mission & Well-being:active:rapid:partial",props:"{}"}, - {"name":"Act:active:rapid:partial:high","id":56,"children":[],"parent":"Mission & Well-being:active:rapid:partial",props:"{}"}, - {"name":"Attend:active:rapid:total:low","id":57,"children":[],"parent":"Mission & Well-being:active:rapid:total",props:"{}"}, - {"name":"Act:active:rapid:total:medium","id":58,"children":[],"parent":"Mission & Well-being:active:rapid:total",props:"{}"}, - {"name":"Act:active:rapid:total:high","id":59,"children":[],"parent":"Mission & Well-being:active:rapid:total",props:"{}"}, - -] +var raw = []; document.onkeyup = function(evt) { evt = evt || window.event; @@ -114,12 +92,73 @@ function usage_privacy() { var title = 'Usage and Privacy' swal(title,msg) } + +function dynamic_mwb() { + var mpdata = $('#mwb').data('parent'); + var mcdata = {} + $('#mwb select').each( + (i,k) => { + var opchoice = $(k).val(); + var cdata = $(k).data('moptions'); + if('label' in cdata) { + /* Global variable for export then local var*/ + var tscore = {}; + tscore[cdata['label']] = opchoice; + mcdata[cdata['label']] = opchoice; + current_score.push(tscore); + } else { + console.log("Error cannot find relationship information with label"); + } + }); + var keys_match = Object.keys(mcdata).length + var result = "Unknown/Error"; + var soptions = mpdata.options + find_score: + for(var i=0; i x == myopt) > -1) { + current_match[spt[j][k].child_label] = 1; + if(Object.keys(current_match).length == keys_match) { + result = soptions[i].label; + break find_score; + } + } + } + } + } + } + } + $('#wscore').html(result); + $('#wsdiv').show(); + $('circle[nameid="'+result.toLowerCase()+'"]').parent().simClick(); + $('#wsdiv').fadeOut('slow'); + setTimeout(function() { + $('#mwb').modal('hide'); + var ptranslate = "translate(120,-250)"; + if(window.innerWidth <= 1000) + ptranslate = "translate(30,-90) scale(0.4,0.4)"; + d3.select("#pgroup").transition() + .duration(600).attr("transform", ptranslate); + export_show(); + }, 2000) +} + function calculate_mwb() { var options = ["Low","Medium","High"] var mp = parseInt($('#mp').val()) var wb = parseInt($('#wb').val()) var result = options[Math.max(mp,wb)] - var xcolor={"Low":"text-success","Medium":"text-warning","High":"text-danger"} + var xcolor={"Low":"text-success", + "Medium":"text-warning", + "High":"text-danger"} $('#wscore').removeClass().addClass(xcolor[result]).html(result) $('#wsdiv').show() $('circle[nameid="'+result.toLowerCase()+'"]').parent().simClick() @@ -133,17 +172,55 @@ function calculate_mwb() { .duration(600).attr("transform", ptranslate) export_show() }, 900) + } -function export_show() { +function export_show(novector) { var q = $('#exporter').html() $('#graph').append(q) if($('#cve_samples').val().match(/^(cve|vu)/i)) $('.exportId').val($('#cve_samples').val()) + if(novector == true) + return + setTimeout(make_ssvc_vector,1000); } +function make_ssvc_vector() { + var tstamp = new Date() + var labels = current_score.map(x => Object.keys(x)[0]); + var vals = current_score.map((x,i) => x[labels[i]]); + labels.push("Decision"); + /* last node in graph */ + var finals = $('#graph svg g.node text:last').text(); + vals.push(finals); + /* SSVCv2/Ps:Nm/T:T/U:E/1605040000/ + For a vulnerability with no or minor Public Safety Impact, + total Technical Impact, and efficient Utility, + which was evaluated on Nov 10, 2020. */ + var computed = "SSVCv2/" + var ochoice = labels.map((k, i) => { + var ox = {} + ox[k] = vals[i] + var lhs = k[0].toUpperCase() + if (k in ssvc_short_keys) + lhs = ssvc_short_keys[k] + var rhs = vals[i][0].toUpperCase() + if(vals[i] in ssvc_short_keys) + rhs = ssvc_short_keys[vals[i]] + computed = computed + lhs+":"+rhs+"/" + return ox + }) + /* Save the ochoice object for Export to JSON*/ + $('#graph .Exporter').attr('data-ochoice',JSON.stringify(ochoice)) + /* new Time string will be ISO 8601 "2021-09-28T21:46:38Z" + q=new Date().toISOString().replace(/\..*$/,'Z') */ + //computed = computed + String(parseInt(tstamp.getTime()/1000))+"/" + var q = new Date().toISOString().replace(/\..*$/,'Z'); + computed = computed+q+"/" + $('.ssvcvector').html(computed); +} function export_tree() { /* First column is the decision in this tree */ - var tchoices = [] + var toptions = [] var yhead = ["Decision"] var yprops = {} export_schema.decisions_table = raw.filter(x => { @@ -160,68 +237,63 @@ function export_tree() { }).map(x => x.name.split(":"). reduce((z,y,i) => { z[yhead[i]] = y - if(!tchoices[i]) { - tchoices[i] = [{label: y, description: y}] + if(!toptions[i]) { + toptions[i] = [{label: y, description: y}] } - else if (!tchoices[i].find(t => t.label == y)) - tchoices[i].push({label: y, description:y}) + else if (!toptions[i].find(t => t.label == y)) + toptions[i].push({label: y, description:y}) return z },{})) /* Now the decision points should be moved to the end of the array */ yhead.push(yhead.shift()) - tchoices.push(tchoices.shift()) + toptions.push(toptions.shift()) export_schema.decision_points = yhead.map((a,i) => { - var ax = {label: a, decision_type: "simple", choices: tchoices[i]} + var ax = {label: a, decision_type: "simple", options: toptions[i]} return ax }) - //console.log(tchoices) + //console.log(toptions) //export_schema.decisions = tdecisions.map((x,i) => Object.assign(x,{color: acolors[i]})) /* - export_schema.decisions = Object.keys(tdecisions).map((n,i) => { - return {label: n, description: n, color:acolors[i]}}) - */ + export_schema.decisions = Object.keys(tdecisions).map((n,i) => { + return {label: n, description: n, color:acolors[i]}}) + */ //return allrows; -/* "[{"Exploitation":"none"},{"Utility":"partial"}, - {"TechnicalImpact":"laborious"},{"SafetyImpact":"none"}, - {"Decision":"defer"}]" */ + /* "[{"Exploitation":"none"},{"Utility":"partial"}, + {"TechnicalImpact":"laborious"},{"SafetyImpact":"none"}, + {"Decision":"defer"}]" */ } -function export_vul(includetree) { +function export_json() { + var includetree = $('#graph .includetree').is(':checked') + $('.Exporter').css({'pointer-events':'none'}); var tstamp = new Date() - var oexport = { timestamp: tstamp.toISOString(), - timestamp_epoch_ms: tstamp.getTime(), - role: $('#graph .exportRole').val() || "Unknown", + var oexport = { role: $('#graph .exportRole').val() || "Unknown", id: $('#graph .exportId').val() || "Unspecified", - version: "2.0" + version: "2.0", + generator: _tool } - var labels = $('#graph svg g.node text').map((i,w) => $(w).html()).toArray() - var vals = $('#graph svg g.pathlink textPath.chosen').map((i,w) => $(w).html()).toArray() - vals.push(labels[labels.length-1]) - labels[labels.length-1] = "Decision" - /* SSVCv2/Ps:Nm/T:T/U:E/1605040000/ - For a vulnerability with no or minor Public Safety Impact, - total Technical Impact, and efficient Utility, - which was evaluated on Nov 10, 2020. */ - var computed = "SSVCv2/" - var ochoice = labels.map((k, i) => { - var ox = {} - ox[k] = vals[i] - computed = computed + k[0].toUpperCase()+":"+vals[i][0].toUpperCase()+"/" - return ox - }) - computed = computed + String(parseInt(tstamp.getTime()/1000))+"/" - oexport['computed'] = computed - oexport['choices'] = ochoice + oexport['computed'] = $('#graph .ssvcvector').html(); + + oexport['timestamp'] = $('#graph .ssvcvector').html().split('/'). + slice(-2,-1)[0] + + /* Copy current_score as is to options that were selected */ + oexport['options'] = current_score; + oexport['$schema'] = location.origin + location.pathname + current_schema + oexport['decision_tree_url'] = location.origin + location.pathname + + current_tree; var a = document.createElement("a") var download_filename = oexport.id+"_"+oexport.role+"_json.txt" if (includetree) { oexport['decision_tree'] = export_schema - download_filename = "tree_and_path-"+oexport.id+"_"+oexport.role+"_json.txt" + download_filename = "tree_and_path-"+ oexport.id + "_" + oexport.role + + "_json.txt" } a.href = "data:text/plain;charset=utf-8,"+ encodeURIComponent(JSON.stringify(oexport,null,2)) a.setAttribute("download", download_filename) a.click() a.remove() + $('.Exporter').css({'pointer-events':'all'}); } function readFile(input) { @@ -242,8 +314,9 @@ function readFile(input) { else tsv_load(reader.result) }catch(err) { - topalert("Reading data in file as text failed, Sorry check format "+ - "and try again!","danger") + reset_form(); + topalert("Reading data in file as text failed, Sorry check format"+ + " and try again!","danger") console.log(err) } }; @@ -257,37 +330,156 @@ function readFile(input) { function topalert(msg,level) { if(!level) level = "info" + var mw = $('#topalert').parent().width() + $('#topalert').width(String(mw)+"px"); $('#topalert').html(msg).removeClass().addClass("alert alert-"+level,msg).fadeIn("fast",function() { $(this).delay(2000).fadeOut("slow"); }) } function tree_process(w) { var ptree = $(w).val() - if(ptree == "import") - return $('#dtreecsvload').click() + if(ptree == "import") { + if(navigator.userAgent.indexOf("Chrome") < 0) { + $('#dtreecsvload').show() + $('#dtreecsvload').click() + topalert("Choose the file to upload below") + } else + $('#dtreecsvload').click() + return + } $.get(ptree, function(idata) { if(ptree.match(/\.json$/i)) parse_json(idata) else parse_file(idata) + /* remove .json from the name. This method uses the file name */ var ptree_name = ptree.replace(/\.[^\.]+$/,'') - $('.cover_heading_append').remove() - $('.cover-heading').append('
('+ - ptree_name+')
') - + $('.cover_heading_append').html('('+ptree_name+')'); }) } +function create_permalink(copyme){ + $('.permalink').removeClass('d-none'); + var purl = location.origin+location.pathname+"#"+ + $("#graph .ssvcvector").html() + var uparts = [".ssvcvector",".exportId",".exportRole"] + for (var i=0; i 0) { + var index = pchildren[0]['index'] + current_score.splice(index,0,...pchildren.map(x => { + var y = {}; + y[x.childlabel] = x.childval; + return y; + })); + } + var ptranslate = "translate(120,-250)" + if(window.innerWidth <= 1000) + ptranslate = "translate(30,-90) scale(0.4,0.4)" + d3.select("#pgroup").transition() + .duration(600).attr("transform", ptranslate) + setTimeout(function() { + export_show(true) + if(plparts[0]) + $('#graph .ssvcvector').html(plparts[0]); + if(plparts[1]) + $('#graph .exportId').val(plparts[1]) + if(plparts[2]) + $('#graph .exportRole').val(plparts[2]); + $('#biscuit').fadeOut() + }, 800) +} +function permalink() { + if(location.hash == "") + return; + topalert("Now loading permalink URL parameters","success"); + dt_clear(); + dt_start(); + try { + $('#biscuit').fadeIn(); + var plink = location.hash.substr(1); + var pchildren = []; + var plparts = plink.split("&"); + var fm = plparts[0].split("/"); + $("#mwb").attr("data-override",1); + /* "SSVCv2/E:A/V:S/T:T/M:H/D:C/1632171335/&CVE-2014-01-01&Coordinator" + OR + "SSVCv2/E:A/V:S/T:T/M:H/D:C/2021-01-09/&CVE-2014-01-01&Coordinator" */ + var sI = {} + var last_precheck = "" + for(var i=1;i x.key == dtup[0]); + if(fstep.length != 1) { + console.log("This decision point does not exist"); + console.log(dtup); + continue; + } + var fopt = fstep[0].options.filter(x => x.key == dtup[1]); + if(fstep[0].label in ischild) { + console.log("This is a child decision, do it later"); + pchildren.push({ + index: i-1, + childlabel: fstep[0].label, + childval: fopt[0].label + }); + continue; + } + var precheck = fopt[0].label.toLowerCase(); + sI[precheck] = setInterval( + function(u) { + if($('.prechk-'+u).length == 1) { + $('.prechk-'+u).simClick(); + clearInterval(sI[u]); + delete sI[u]; + if(u == last_precheck) + finish_permalink(plparts,pchildren); + return; + } + },600*i,precheck); + last_precheck = precheck; + } + setTimeout(function() { + for (let k in sI) { + console.log("Pending jobs incomplete after 20 seconds"); + clearInterval(sI[k]); + delete sI[k]; + } + },20000) + console.log(sI); + }catch(err) { + console.log(err); + topalert("Failed to parse Permalink URL!","error") + } + +} function process(w) { var cve = $(w).val() - if(cve == "import") - return $('#cvetsvload').click() + if(cve == "import") { + if(navigator.userAgent.indexOf("Chrome") < 0) { + $('#cvetsvload').show() + topalert("Choose the file to upload below") + } else + $('#cvetsvload').click() + return + } var cve_data = $('#'+cve).data() if(!cve_data) { alert("Some error in loading this CVE data check the template and try again") return } - dt_clear() - $('#biscuit').fadeIn() - dt_start() + dt_clear(); + $('#biscuit').fadeIn(); + dt_start(); + $('#cve_table tbody tr td').remove() var steps = ['Exploit','Virulence','Technical'] var stimes = [1600,3200,5100] @@ -350,32 +542,90 @@ function tsv_load(data) { if(rmv) topalert("Loaded TSV CVE samples count of "+scores.length,"success") } -function parse_json(xraw) { - var zraw = [] - var tm = JSON.parse(xraw) +function create_short_keys(x,uniq_keys) { + /* If a key is provided for short_key representation use it + if not detect one using the last */ + if("key" in x) { + ssvc_short_keys[x.label] = x.key + return true; + } + else { + var iuniq = 0 + ssvc_short_keys[x.label] = x.label[0].toUpperCase() + while (x.label[iuniq] in uniq_keys) { + iuniq = iuniq + 1; + ssvc_short_keys[x.label] = x.label[iuniq].toUpperCase() + } + uniq_keys[x.label[iuniq]] = 1; + /* Create a key if one does not exist for reference in the full + exported JSON */ + x["key"] = ssvc_short_keys[x.label]; + } +} +function parse_json(xraw,paused) { + var zraw = []; + var tm; + if(typeof(xraw) == "string") + tm = JSON.parse(xraw) + else + tm = xraw + if('decision_tree' in tm) { + /* This has a decision_tree and a score - a computed and provision + schemas together*/ + tm = tm.decision_tree; + } + if(!('decision_points' in tm)) { topalert("JSON schema has no decision_points","danger") return } if(!('decisions_table' in tm)) { - topalert("JSON schema has no decision table, we can't help you with that","danger") - return + topalert("JSON schema has no decision table, we can't help you with that","danger"); + console.log(tm); + return; } /* Save JSON for export*/ export_schema = tm - - /* decisions_points have a label field which we care about with type != child */ - var x = tm.decision_points.filter(q => q["decision_type"] != "child").map(r => r.label) - //console.log(x) + /* This is temp key to find full child elements */ + var xkeys = {}; + /* Find array that are children as children will also have the decision + type simple */ + ischild = tm.decision_points.reduce( + (x,y) => { + /* Use either key or label to create a hash of everyone */ + xkeys[y.label] = y; + if("key" in y) + xkeys[y.key] = y.label + /* Use either key or label to mark the xkeys to a child + decision tree */ + if("children" in y) { + isparent[y.label] = []; + y.children.map(z => { + var tx = z.label; + if(("key" in z) && (z.key != "")) { + tx = xkeys[z.key]; + } + isparent[y.label].push(xkeys[tx]); + x[tx] = 1; + }); + } + return x; + },{}); + /* Check to make sure neither key nor label is in a ischild object */ + var x = tm.decision_points.filter( + x => (!(x.label in ischild))).map(r => r.label) var y = tm.decisions_table //console.log(y) var yraw = [...Array(x.length)].map(u => []) var id = 1 var thash = {} var decisions = tm.decision_points.filter(x => x.decision_type == "final") + if('title' in tm) + $('.cover_heading_append').html('('+tm.title+')'); if(decisions.length != 1) { - topalert("JSON schema has no decisions marked as final, this is required!","danger") - return + topalert("JSON schema has no decisions marked as final, assuming the last element is the \"Final\" decision.","warning") + tm.decision_points[tm.decision_points.length - 1]['decision_type'] = "final" + decisions = [tm.decision_points[tm.decision_points.length - 1]] } var decision_keyword = decisions[0].label //console.log(decisions) @@ -384,13 +634,13 @@ function parse_json(xraw) { //var tname = y[i].pop()+":"+y[i].join(":") //console.log(y[i]) /* Decision table should have the "outcome" or "decision" fiel if not skip - this entry */ + this entry */ if(!(decision_keyword in y[i])) continue var tname = y[i][decision_keyword]+":"+x.map(t => y[i][t]).slice(0,-1).join(":") for( var j=0; j< x.length-1; j++) { //var tparent = x[x.length-2-j]+":"+y[i].slice(0,x.length-2-j).join(":") - var tparent = x[x.length-2-j]+":"+x.slice(0,x.length-2-j).map(q => y[i][q]).join(":") + var tparent = x[x.length-2-j]+":"+x.slice(0,x.length-2-j).map(q => y[i][q]).join(":") //var tparent = x[x.length-1-j]+":"+x.slice(0,x.length-1-j).map(q => y[i][q]).join(":") if(!(tname in thash)) var yt = {name:tname.replace(/\:+$/,''),id:id++,parent:tparent.replace(/\:+$/,''),props:"{}",children:[]} @@ -401,7 +651,7 @@ function parse_json(xraw) { yraw[j].push(yt) } } - + for(var j=yraw.length; j> -1; j--) { if(yraw.length > 0) zraw = zraw.concat(yraw[j]) @@ -411,12 +661,23 @@ function parse_json(xraw) { zraw[0] = {name:x[0],id:id+254,children:[],parent:null,props:"{}"} /* yraw[0].push({name:"Exploitation:",id:1024,children:[],parent:null,props:"{}"}) */ raw = zraw - topalert("Decision tree has been updated with "+raw.length+" nodes, with "+ - y.length+" possible decisions, You can use it now!","success") + //console.log(raw) + topalert("Decision tree JSON has been updated with "+raw.length+ + " nodes, with "+y.length+" possible outcomes, You can "+ + "use it now!","success") dt_clear() /* Create label fields if they exists*/ + var lastdiv = ""; + /* Unique keys for decision points*/ + var duniq_keys = {}; + /* unique keys for choices under decision points*/ + var ouniq_keys = {}; tm.decision_points.map(x => { - var choices_html = x.choices.reduce((h,r) => { + create_short_keys(x,duniq_keys); + var options_data = {} + var options_html = x.options.reduce((h,r) => { + create_short_keys(r,ouniq_keys); + options_data[r.label] = r.description; var rlabel = r.label[0].toLocaleUpperCase()+r.label.substr(1) return h + ""+rlabel+" "+r.description+"
" },"
"+x.label+"
") @@ -425,10 +686,47 @@ function parse_json(xraw) { $("."+hdiv).remove() $('body').append($('
').addClass("d-none "+hdiv)) } - $("."+hdiv).html(choices_html) - }) + $("."+hdiv).html(options_html) + if(x.label in isparent) { + /* Save the entier decision object in data parent value*/ + $('#mwb').attr("data-parent",JSON.stringify(x)); + $("."+hdiv+" h5").after("

(Complex Decision)

"); + //console.log(isparent[x.label]); + $("#mwb h5").html(x.label + " (Cummulative Score)"); + //('#wbtable tr') + $("#wbtable tr").remove(); + isparent[x.label].forEach( (t,k) => { + var stdiv = safedivname(t.label); + var tselect = $("
").append($("
- +
+ + + + + + + + +
+ + +
+ + Include decision tree in export -
- +
+
+ + +
").append(tlabel)). + append($("").append(tselect)); + $("#wbtable").append(tr); + var addcontent = "
Depends on "+String(k+1) + addcontent += $("."+stdiv).html()+"
"; + $("."+hdiv).append(addcontent); + $('#mwb .btn-primary').removeAttr('onclick'); + $('#mwb .btn-primary').attr({'onclick': 'dynamic_mwb()'}); + }); + } + lastdiv = hdiv + //console.log(options_data); + $("."+hdiv).attr("data-options",JSON.stringify(options_data)); + }); + $("."+lastdiv).addClass("Decision"); var classes = [] - var decision_div = decisions[0].choices.reduce((h,r) => { + var decision_div = decisions[0].options.reduce((h,r) => { classes.push(safedivname(r.label)) return h + $("
").append($("").addClass("decisiontab"). css({color:r.color}).html(r.label)) @@ -441,23 +739,47 @@ function parse_json(xraw) { //console.log(classes) //console.log(decision_div) $("."+classes[0]).addClass(classes.join(" ")).html(decision_div) + permalink(); + $('#dtreecsvload').hide(); +} +function shwhelp(w) { + var iconPos = w.getBoundingClientRect(); + var tm = $(w).data('tdiv') + if(tm) { + $('#mpopup').css({left:(iconPos.right + 10) + "px", + top:(window.scrollY + iconPos.top - 20) + "px", + "max-width": "-moz-available", + "max-width": "-webkit-fill-available", + "max-width": "stretch", + "overflow-y": "auto", + "z-index":1050, + display:"block"}); + $('#mpopup').html($('.'+tm).html()) + $('#mwb').on('hidden.bs.modal', function (e) { + $('#mpopup').hide(); + }) + } + $('#mpopup').show() } + function safedivname(instr) { var uri_esc = encodeURIComponent(instr) var safestr = btoa(uri_esc.replace(/%([0-9A-F]{2})/g, - (m, p) => String.fromCharCode('0x' + p))) - var fstr = "d-"+safestr.replace(/[\+\/\=]/gi,(m,p) => { return m.charCodeAt(0) }) - return fstr.substr(0,14) + (m, p) => + String.fromCharCode('0x' + p))); + var fstr = "d-"+safestr.replace(/[\+\/\=]/gi, + (m,p) => { return m.charCodeAt(0) }); + return fstr.substr(0,14); } function create_export_schema_dtable(yi,x) { export_schema.decisions_table.push(yi.reduce((a,b,c) => { /* Add labels that do not exist */ - if(export_schema.decision_points[c]['choices'] + if(export_schema.decision_points[c]['options'] .filter(d => ('label' in d) && (d.label == b)).length != 1) - export_schema.decision_points[c]['choices'].push({label: b, description:b}) + export_schema.decision_points[c]['options'].push({label: b, description:b}) a[x[c]] = b return a; },{})) } @@ -470,14 +792,11 @@ function parse_file(xraw) { /* CSV or TSV looks like ID,Exploitation,Utility,TechnicalImpact,SafetyImpact,Outcome */ - console.log(xraw) var xarray = xraw.split('\n') - console.log(xarray) var xr = xarray.map(x => x.split(/[\t,]+/)) /* Remove first row has the headers and pass the rest to variable y */ var y = xr.splice(1) /* Check if rowID first column of second row to match not number*/ - console.log(xr) var is_ssvc_v1 = y[0][0].match(/\D+/) ? false : true /* Remove ID column in the first row to create x*/ if (is_ssvc_v1) @@ -485,15 +804,15 @@ function parse_file(xraw) { else var x = xr[0] /* Now xr looks like below for ssvc csv v1 */ - /* (6)[["Row", "Exploitation", "Virulence", "Technical", "Mission_Well-being", "Decision"]] */ + /* [["Row", "Exploitation", "Virulence", "Technical", "Mission_Well-being", "Decision"]] */ //var yraw = [[],[],[],[],[]] /* Register the export schema decision points, assume all decisions are simple */ - export_schema.decision_points = x.map(dc => - { - var ix = {decision_type:"simple", choices:[]} - ix.label = dc - return ix - }) + export_schema.decision_points = x.map( + dc => { + var ix = {decision_type:"simple", options:[]} + ix.label = dc + return ix + }) /* make the last column final decision/outcome/action */ export_schema.decision_points[export_schema.decision_points.length-1].decision_type="final" /* Initialize Empty arrray */ @@ -507,6 +826,7 @@ function parse_file(xraw) { if(is_ssvc_v1) y[i].shift() /* Add lame CSV/TSV data to export schema */ + //console.log(y[i]); create_export_schema_dtable(y[i],x) var tname = y[i].pop()+":"+y[i].join(":") //console.log(tname) @@ -544,8 +864,7 @@ function parse_file(xraw) { y.length+" possible decisions using "+detect_version+" CSV/TSV file, You can use it now!","success") dt_clear() export_schema.decision_points[export_schema.decision_points.length-1]. - choices.map((x,i) => lcolors[x.label] = acolors[i]) - + options.map((x,i) => lcolors[x.label] = acolors[i]) } function add_invalid_feedback(xel,msg) { @@ -699,7 +1018,9 @@ function update(source) { .attr("x",function(d) { return check_children(d,"-55","+20") }) .attr("y",function(d) { return check_children(d,"-37","0") }) .attr("dy", ".35em") - .text(function(d) { return d.name.split(":")[0]; }) + .attr("class",function(d) { + return "prechk-"+d.name.split(":")[0].toLowerCase() + }).text(function(d) { return d.name.split(":")[0]; }) .style("font-size",font) .style("fill", function(d) { var t = d.name.split(":")[0] var x = "white" @@ -794,7 +1115,7 @@ function update(source) { d.x0 = d.x; d.y0 = d.y; }); - setTimeout(update_links,1500) + setTimeout(update_links,1500); } function pathclick(w) { var sid = $(this).attr("csid") @@ -836,7 +1157,7 @@ function update_links() { .attr("csid",csid) .text(text).attr("startOffset",doffset+"%") .on("click",pathclick) - //.each(function() { console.log("Completed") }) + //.each(function() { console.log("Completed") }) //$(this).remove() "fill","#17a2b8") "text-anchor","middle" }) } @@ -857,17 +1178,28 @@ function showdiv(d) { var addons = '' var safename = safedivname(name) //console.log(name,safename) + /* Default left position*/ + var leftpos = String(iconPos.right + 10) + "px" + if(window.innerWidth - iconPos.right < iconPos.right) { + /* right half of screen, move left position */ + leftpos = String(iconPos.left - $('#mpopup').width()) +"px" + } + if($('.'+safename).length == 1) { $('#mpopup').html($('.'+safename).html()) - $('#mpopup').css({left:(iconPos.right + 10) + "px", + $('#mpopup').css({left: leftpos, top:(window.scrollY + iconPos.top - 20) + "px", - display:"block"}) - + display:"block"}); } } function hidediv(d) { $('#mpopup').hide() } +function checkclose() { + /* */ + $('#mpopup').hide(); +} + function dorightclick(d) { return } @@ -885,6 +1217,14 @@ function closeSiblings(d) { function doclick(d) { if(showFullTree === false) { + if(d.parent && d.parent.name) { + /* Virulence:none means Exploitation(i.e., d.parent.name) => none*/ + var dparent = d.parent.name.split(":").shift(); + var thash = {}; + thash[dparent] = d.name.split(":").pop(); + current_score.push(thash); + } + if(('clickkill' in d) && (d.clickkill === true)) { console.log("We have reached this already "+d) @@ -895,7 +1235,11 @@ function doclick(d) { (d.name.indexOf("Mission ") == 0) ) { $('#wb').val(0) $('#mp').val(0) - $('#mwb').modal() + /* If mwb is overriden by permalink or full score reset it and ignore it*/ + if($("#mwb").data("override") == 1) + $("#mwb").attr("data-override",0) + else + $('#mwb').modal() } if('id' in d) { var idl = $('[csid="'+d.id+'"]').attr("id") @@ -906,7 +1250,6 @@ function doclick(d) { if(d.parent) closeSiblings(d) } - $('.pathlink').remove() if (d.children) { d._children = d.children; @@ -972,6 +1315,7 @@ function showme(divid,vul_flag) { } function dt_start() { + current_score = []; showFullTree = false $('svg.mgraph').remove() var xraw = JSON.parse(JSON.stringify(raw)) @@ -984,15 +1328,17 @@ function dt_start() { }, 900) } function dt_clear() { - showFullTree = false - raw.map(x => { x.children=[]; delete x._children;}) + showFullTree = false; + current_score = []; + raw.map(x => { x.children=[]; delete x._children;}); /* Clear all graph to start */ - $('svg.mgraph').remove() - $('#graph').html('') + $('svg.mgraph').remove(); + $('#graph').html(''); } function show_full_tree() { showFullTree = true + $('#graph .exportdiv').remove() $('svg.mgraph').remove() var xraw = JSON.parse(JSON.stringify(raw)) treeData=grapharray_open(xraw) @@ -1022,6 +1368,7 @@ function add_text(links) { ((d.source.y + d.target.y)/2) + "," + ((d.source.x + d.target.x)/2) + ")"; }) + .attr("class",function(d) { return d.target.name.toLowerCase(); }) .attr("dy", ".35em") .attr("text-anchor", "middle") .text(function(d) { @@ -1029,3 +1376,680 @@ function add_text(links) { return d.target.name; }); } +function createHeaders(keys) { + var result = []; + for (var i = 0; i < keys.length; i += 1) { + result.push({ + id: keys[i], + name: keys[i], + prompt: keys[i], + width: 65, + align: "center", + padding: 0 + }); + } + return result; +} +function deepsearch(obj,dir) { + var xobj = obj + var path = dir.split(".") + for(var i=0; i Object.keys(x)[0]); + var decisions = current_score.map((x,i) => x[steps[i]]); + var final_decision = $('#graph svg g.node text:last').text(); + //steps.push + decisions.push(final_decision); + // Last element name is hard-coded key word "Decision" + steps.push("Decision"); + //var steps=["Exploitation","Virulence","Technical Impact","Mission & Well-Being","Decision"] + //var decisions = ["Active","Slow","Partial","Low","Track"] + var actions = [] + var xOffset = 20 + var yOffset = 30 + var cradius = 3 + var ysteps = 40 + + //rgb(40, 167, 69) + + /* fill: rgb(176, 196, 222); + stroke: rgb(70, 130, 180);*/ + var ij = 0; + for (var i=0; i< steps.length; i++) { + if(steps[i] in ischild) { + console.log("Skipping this one as it is a child decision"); + console.log(steps[i]); + continue; + } + var x = xOffset+ysteps*ij; + doc.setLineWidth(1); + doc.setFont("helvetica",'bold'); + doc.setDrawColor(70,130,180); + doc.setFillColor(176, 196, 222); + if(i == steps.length - 1) { + /* Last circle change color */ + if(final_decision in lcolors) { + doc.setDrawColor(192,192,192); + doc.setFillColor(lcolors[final_decision]); + } + + } + doc.circle(x, yOffset, cradius, "FD"); + q = doc.getStringUnitWidth(steps[i]) + //#343a40 + doc.setTextColor(0x11,0x3a,0x40); + doc.setFontSize(12); + //doc.setFont(undefined,'bold') + doc.text(steps[i],x-q*2,yOffset-5); + if (i < steps.length-1) { + /* Not Final decision */ + doc.line(x+3,yOffset,x+3+34,yOffset) + //#17a2b8 !important + doc.setTextColor(0x17,0xa2,0xb8); + doc.setFont("courier","bolditalic"); + doc.text(decisions[i],x+q*2,yOffset+4) + } + ij++; + } + + // rgb(40, 167, 69); + doc.setFont("courier"); + //doc.setFontType("bolditalic"); + doc.setFont("courier",'bolditalic') + var lastx = xOffset+ysteps*(ij-1)+10 + if(final_decision in lcolors) + doc.setTextColor(lcolors[final_decision]) + else + doc.setTextColor(1,1,1) + console.log(lastx); + doc.text(final_decision,lastx,yOffset+1); + + doc.setFont("helvetica",'bold'); + doc.setTextColor(0,0,0); + doc.setFontSize(14); + xOffset = 12; + doc.text("Summary",xOffset,yOffset+13); + doc.setFontSize(12); + var vector_string = $('#graph .ssvcvector').html() + + doc.setFont("helvetica","normal"); + doc.text("Recommendation:",xOffset,yOffset+20); + doc.text("SSVC Vector :",xOffset,yOffset+25); + doc.text("Timestamp:",xOffset,yOffset+30); + doc.text("SSVC Role:",xOffset,yOffset+35); + doc.text("Vulnerability Info:",xOffset,yOffset+40); + + doc.setFont("courier",'italic'); + var ycve = vulnerability.toUpperCase() + if(ycve.indexOf("CVE") == 0) { + var link = 'https://nvd.nist.gov/vuln/detail/'+ycve + doc.setTextColor(0,0,255); + doc.textWithLink(vulnerability, xOffset+40, yOffset+40, {url: link}); + doc.setLineWidth(0.5); + doc.setDrawColor(0,0,255); + doc.line(xOffset+40,yOffset+41,xOffset+40+33,yOffset+41) + //doc.text(xOffset+40,yOffset+20,link); + doc.setTextColor(0,0,0); + } else { + doc.text(vulnerability, xOffset+40, yOffset+40); + } + doc.text(vector_string,xOffset+40,yOffset+25); + q = doc.getStringUnitWidth(vector_string) + doc.addImage("icons8-copy-link-48-blue.png","PNG",60+q*4,yOffset+20,6,6); + var purl = create_permalink(false); + doc.link(61+q*4,yOffset+21,12,12,{url: purl}); + var timeprint = ""; + doc.setFont("courier",'italic'); + if(vector_string.match(/\/[0-9]+\/$/)) { + var ts = new Date(parseInt(vector_string.split('/').slice(-2,-1)[0]*1000)); + timeprint = ts.toGMTString().replace("GMT","UTC"); + } else { + var tmsec = Date.parse(vector_string.split('/').slice(-2,-1)[0]); + var ts = new Date(tmsec); + timeprint = ts.toGMTString().replace("GMT","UTC"); + } + doc.setFont("courier","bolditalic"); + if(final_decision in lcolors) { + doc.setTextColor(lcolors[final_decision]); + } + doc.text(final_decision,xOffset+40,yOffset+20); + doc.setTextColor(0,0,0); + doc.setFont("courier",'italic'); + doc.text(timeprint,xOffset+40,yOffset+30); + var role = coord; + doc.text(role,xOffset+40,yOffset+35); + var ynow = yOffset + 40 + if(cveinfo.length > 28) { + /* Treat first line in a different way*/ + var ft = cveinfo.match(/.{1,27}(\s|$)/g); + q = doc.getStringUnitWidth(vulnerability); + doc.text(ft[0],xOffset+40+q*4.4,ynow); + ynow = ynow+5 + cveinfo = cveinfo.substr(ft[0].length); + var f = cveinfo.match(/.{1,45}(\s|$)/g); + for (var j = 0; j { + var ix = $('.'+safedivname(x)).data('options'); + if(typeof(ix) != "object") return t.push("No information provided"); + else if(decisions[i] in ix) return t.push($("
").html(ix[decisions[i]]).text()); + return t.push("No information available") + }) + doc.setFontSize(12); + for(var i = 0; i < t.length; i++) { + if(steps[i] in ischild) { + continue; + } + if(steps[i] in isparent) { + var q = isparent[steps[i]]; + var istring = "This is a cummulative score of \""; + q.forEach(x => { + if('label' in x) { + var t = current_score.forEach( + (b) => { + if(x.label in b) { + istring += x.label +"\" => \""+b[x.label]+"\" and " + } + },""); + } + }) + /* Replace the string with cummulative information */ + t[i] = istring.slice(0,-5) + ". Review the full SSVC tree for details." + } + doc.setFont("helvetica",'bold'); + doc.text(steps[i]+":",xOffset,ynow); + q = doc.getStringUnitWidth(steps[i]) + + doc.setTextColor(0x17,0xa2,0xb8); + if(decisions[i] in lcolors) + doc.setTextColor(lcolors[decisions[i]]); + doc.setFont("courier","bolditalic"); + doc.text(decisions[i],xOffset+q*4.8,ynow); + doc.setTextColor(0,0,0); + doc.setFont("courier",'normal'); + q = q + doc.getStringUnitWidth(decisions[i]) + + var f = t[i].match(/.{1,45}(\s|$)/g); + doc.text("=> "+f[0],xOffset+q*5,ynow); + if(t[i].length<= f[0].length) { + ynow = ynow +10 + continue + } + //console.log(t[i].substr(f[0].length)); + f = t[i].substr(f[0].length).match(/.{1,65}(\s|$)/g); + for (var j = 0; j [x[0],-1*x[1]]) + doc.lines(f,xstart,yc) + + //doc.circle(xstart,yc,3,"FD") + /* Non edges nodes will use this color*/ + d_fillColor = "#b0c4de"; + d_drawColor = "#4682b4"; + circles.push([xstart,yc,3,"FD",d_drawColor,d_fillColor]) +} +function make_table(cdp,doc,ynow) { + /* Give it a complex decision point CDP */ + var dims = []; + var x = []; + var y = []; + var xy = []; + xy.push([]); + var i = 0; + var j = 0; + cdp.options.forEach((d) => { + d.child_combinations.forEach((p) => { + p.forEach((r) => { + var xory = dims.findIndex(q => q == r.child_label); + if(xory < 0) { + dims.push(r.child_label) + xory = dims.findIndex(q => q == r.child_label); + } + r.child_option_labels.forEach((s) => { + if (xory == 0) { + i = x.findIndex(q => q == s); + if(i < 0) { + x.push(s); + i = x.findIndex(q => q == s); + } + } else { + j = y.findIndex(q => q == s); + if(j < 0) { + y.push(s); + j = y.findIndex(q => q == s); + } + } + console.log(xory,i,j); + if(!xy[i]) + xy[i] = []; + xy[i][j] = d.label; + }) + }) + }) + }) + doc.setFont("helvetica","bold"); + doc.setFontSize(12); + y.splice(0,0," ") + + var headers = []; + for (var i = 0; i < y.length; i += 1) { + var tf = { + name: y[i], + prompt: y[i], + width: 40, + align: "center", + padding: 0 + } + headers.push(tf); + } + + + var result = [y.reduce((a,f) =>{ a[f] = f; return a; },{})] + var data = {} + for (var i = 0; i < x.length; i += 1) { + + data[y[0]] = x[i] + + data[y[1]] = xy[i][0]; + data[y[2]] = xy[i][1] + data[y[3]] = xy[i][2] + + result.push(Object.assign({}, data)); + } + + doc.setFont("helvetica","bold"); + doc.setFontSize(14); + doc.setFillColor("#c7c7c7") + doc.rect(50,ynow,120,15,"FD") + doc.text("Public Well-being Impact",70,ynow+10) + doc.setFillColor("#c7c7c7") + doc.rect(20,ynow,30,63,"FD") + ynow = ynow +15; + doc.text(" Mission\nPrevelance",21,ynow+15,0) + doc.setFont("courier","italic"); + doc.setFontSize(10); + doc.table(50, ynow, result, headers, { autoSize: false, + printHeaders:false }); + //doc.text("FF",15,ynow+55) + console.log(ynow); + return ynow+55; +} + +function appendtree(doc,dfilename) { + /* Add the full tree in colorful fashion to the current data*/ + doc.addPage("a4"); + window.circles = []; + var ax = export_schema; + //ax.decision_points[ax.decision_points.length-1].options.forEach(d => { if("color" in d) colors[d.label] = d.color}) + doc.setFontSize(16); + doc.setFont("helvetica",'bold'); + doc.setTextColor(0); + var coord = $('.cover_heading_append').html().replace(/^\s+(.+)\s+/g,'$1') + doc.text("Full SSVC Tree "+coord,10,10); + /* top left corner */ + var tlc = 180; + var gap = 8; + /* Mark the children that should be ignored */ + var mdecision_points = ax.decision_points.filter( + x => (!(x.label in ischild))) + + for(var index=0; index < ax.decisions_table.length; index++) { + var yc = 10+gap*index ; + var fillColor = "#b0c4de"; + var drawColor = "#4682b4"; + /* Gloabl values to sigmoid_connect can also use it*/ + var m = ax.decisions_table[index].Decision + doc.setFontSize(14) + doc.setFont("courier",'bold'); + doc.setTextColor(0); + if(m in lcolors) { + doc.setTextColor(lcolors[m]); + fillColor = lcolors[m]; + // silver lining? + drawColor = "#505050"; + } + + doc.text(m,tlc+5, yc) + if(index%3 == 1) { + doc.setFont("helvetica",'bold'); + doc.setTextColor(0) + doc.setFontSize(12) + m = mdecision_points[mdecision_points.length-2]['label'] + doc.text(m,tlc-55, yc-5) + yc = 10+gap*index ; + sigmoid_connect(8,tlc-40,yc,1,m,doc) + doc.setFont("courier",'normal'); + doc.setFontSize(10); + doc.text(ax.decisions_table[0][m],tlc-10,yc-7,12) + doc.text(ax.decisions_table[2][m],tlc-10,yc+5,-12) + } + if(index%6 == 3) { + doc.setTextColor(0) + /* (r,flen,xstart,yc) */ + doc.setFont("helvetica",'bold'); + doc.setFontSize(12) + m = mdecision_points[mdecision_points.length-3]['label'] + doc.text(m,tlc-95, yc-8) + yc = 6+gap*index + sigmoid_connect(13,tlc-80,yc,0,m,doc) + doc.setFont("courier",'normal'); + doc.setFontSize(10); + doc.text(ax.decisions_table[0][m],tlc-60,yc-8,20) + doc.text(ax.decisions_table[3][m],tlc-60,yc+10,-20) + } + + if(index%12 == 6) { + doc.setTextColor(0) + doc.setFont("helvetica",'bold'); + /* (r,flen,xstart,yc) */ + doc.setFontSize(12) + m = mdecision_points[mdecision_points.length-4]['label'] + doc.text(m,tlc-130, yc-8) + yc = 6+gap*index + sigmoid_connect(26,tlc-120,yc,0,m,doc) + doc.setFont("courier",'normal'); + doc.setFontSize(10); + doc.text(ax.decisions_table[0][m],tlc-103,yc-9,45) + doc.text(ax.decisions_table[6][m],tlc-103,yc+5,-45) + } + + if(index%36 == 18) { + doc.setTextColor(0) + /* (r,flen,xstart,yc) */ + doc.setFont("helvetica",'bold'); + doc.setFontSize(12) + m = mdecision_points[mdecision_points.length-5]['label'] + doc.text(m,tlc-170, yc-5) + yc = 10+gap*index ; + sigmoid_connect(101,20,150,1,m,doc) + doc.setFontSize(10); + doc.text(ax.decisions_table[0][m],40,yc-50,75) + doc.text(ax.decisions_table[12][m],40,yc+50,-75) + } + yc = 10+gap*index ; + doc.setLineWidth(0.6); + doc.setDrawColor(drawColor); + doc.setFillColor(fillColor); + circles.push([tlc,yc,3,"FD",drawColor,fillColor]) + //doc.circle(tlc,yc,3,"FD"); + } + //doc.circle(circles[0][0],circles[0][1],circles[0][2],circles[0][3]) + circles.forEach((x) => { + doc.setDrawColor(x[4]); + doc.setFillColor(x[5]); + doc.circle(x[0],x[1],x[2],x[3]) + }); + //console.log(circles); + //console.log(typeof(doc.circle)) + doc.addPage("a4"); + var ynow = 10; + var q = 0; + doc.setFontSize(16); + doc.setFont("helvetica",'bold'); + doc.setTextColor(0); + doc.text("Full SSVC Tree "+coord+" definitions",10,10); + export_schema.decision_points.forEach(function(x,ix) { + if(ynow > 230) { + doc.addPage("a4"); + ynow = 20 + } + //return 0; + doc.setFont("helvetica",'bold'); + doc.setTextColor(0,0,0); + ynow = ynow + 10; + doc.setFontSize(14); + doc.text(x.label,20,ynow); + if(x.label in isparent) { + /* Add a statement on cummulative score*/ + doc.setFont("courier","normal"); + doc.setFontSize(12); + var p = isparent[x.label]; + var istring = "Note: This is a cummulative score of \""; + p.forEach(x => { + if('label' in x) { + var t = current_score.forEach( + (b) => { + if(x.label in b) { + istring += x.label + "\" and \""; + } + },""); + } + }) + /* Replace the string with cummulative information */ + istring = istring.slice(0,-6) +"."; + var f = istring.match(/.{1,65}(\s|$)/g); + for (var j = 0; j 230) { + doc.addPage("a4"); + ynow = 20 + } + ynow = ynow + 5 + doc.setTextColor(0x17,0xa2,0xb8); + doc.setFont("courier","bolditalic"); + doc.setFontSize(12); + if(y.label in lcolors) + doc.setTextColor(lcolors[y.label]); + var clabel = y.label[0].toUpperCase()+y.label.substr(1); + doc.text(clabel,20,ynow); + doc.setTextColor(0,0,0); + var tinfo = y.description; + var f = tinfo.match(/.{1,45}(\s|$)/g); + doc.setFont("courier",'normal'); + q = doc.getStringUnitWidth(clabel) + doc.text("=> "+f[0],20+q*5,ynow); + if(tinfo.length<= f[0].length) { + ynow = ynow + 6 + return + } + //console.log(t[i].substr(f[0].length)); + f = tinfo.substr(f[0].length).match(/.{1,65}(\s|$)/g); + for (var j = 0; j