Skip to content
Snippets Groups Projects
Commit fcf672ca authored by martiivGylden's avatar martiivGylden
Browse files

Working on metrics, and duplicates FML

parent 863b5c45
No related branches found
No related tags found
No related merge requests found
from dataclasses import dataclass
import pandas as pd
import ERFormatConstants as const
from dynamics import *
class Threat: class Threat:
"""_summary_ """_summary_
The class threat is used to classify a threat in the ER model. The class threat is used to classify a threat in the ER model.
...@@ -90,3 +96,68 @@ class Attack: ...@@ -90,3 +96,68 @@ class Attack:
def linkThreats(): def linkThreats():
# Function should link the attack to a threat # Function should link the attack to a threat
pass pass
@dataclass
class Diagram():
threats: dict
consequences : dict
attacks : dict
dynamics : dict
metrics : dict
def __init__(self) -> None:
self.threats = {}
self.consequences = {}
self.attacks = {}
self.dynamics = pd.DataFrame()
self.metrics = {}
def getThreat(self, id) -> Threat:
"""_summary_
Args:
id (_type_): _description_
Returns:
Threat: _description_
"""
threat = self.threats[id]
return threat
def getConsequence(self, id) -> Consequence:
"""_summary_
Args:
id (_type_): _description_
Returns:
Consequence: _description_
"""
consequence = self.consequences[id]
return consequence
def getAttack(self, id) -> Attack:
attack = self.attacks[id]
return attack
def getERDynamic(self, threatID) -> ERDynamic:
"""_summary_
The get ER dynamic is used to retrieve the ER dynamic component associated with a threat
This is done through the metric matrix and threat ID
1. Threat ID is used to find a row in the metric matrix which contains the threat ID,
Args:
threatID (_type_): _description_
Returns:
ERDynamic: _description_
"""
pass
def getBowtieDynamic(self, associatedId) -> BowtieDynamic:
pass
def getMetric(self) -> Metric:
pass
\ No newline at end of file
...@@ -5,16 +5,21 @@ import dynamics as dynamic ...@@ -5,16 +5,21 @@ import dynamics as dynamic
import logging as log import logging as log
import matrices as matrix import matrices as matrix
# Function will parse a csv file and extract the necessary information, this is step 1 of the parse # Function will parse a csv file and extract the necessary information, this is step 1 of the parse
def parseDiagramFile(csvFile): def parseDiagramFile(csvFile) -> component.Diagram:
df = pd.read_csv(csvFile) df = pd.read_csv(csvFile)
df.drop(["Shape Library", "Page ID", "Contained By", "Group", "Comments", "property 1"], axis=1, inplace=True) #Removing unecessary data df.drop(["Shape Library", "Page ID", "Contained By", "Group", "Comments", "property 1"], axis=1, inplace=True) #Removing unecessary data
diagram = component.Diagram()
# List containing all threats and their descriptions # List containing all threats and their descriptions
threats = {} threats = diagram.threats
consequences = {} consequences = diagram.consequences
dynamics = {} dynamics = diagram.dynamics
metrics = [] metrics = diagram.metrics
metricsMatrix = matrix.parseTable(df) #Parse the table metricsMatrix = matrix.parseTable(df) #Parse the table
threats = parseThreats(df, threats) threats = parseThreats(df, threats)
...@@ -77,7 +82,7 @@ def parseAttacks(df, attackDict): ...@@ -77,7 +82,7 @@ def parseAttacks(df, attackDict):
return attackDict return attackDict
#Parses metrics components and adds it to list #Parses metrics components and adds it to list
def parseDynamic(df, metricList, dynamicsDict): def parseDynamic(df, metricDict, dynamicsDict):
for i in range(len(df)): # Iterates through the dataframe for i in range(len(df)): # Iterates through the dataframe
if df[const.textArea1][i] == const.Dynamics: # If the component is a dynamic component if df[const.textArea1][i] == const.Dynamics: # If the component is a dynamic component
......
# Requirements for the diagram parser
This document contains the functional and non functional requirements of the application.
Additionally the document contains success criteria which are formulated from the three research questions formulated for the thesis;
- RQ1: What are important aspects of a software supply chain, how do we identify and document them?
- RQ2: What are dynamic aspects of a software supply chain, how do we identify and document them?
- RQ3: How can we maintain traceability and consistency between the software supply chain and its risk picture in a scalable and understandable manner?
## Success criteria
- By leveraging the method and application a developer will be able to identify dynamic indicators related to the found software supply chain threats, and find the different components in the software supply chain architecture related to these dynamic indicators
- The developer will be able to use the resulting scorecard of the modeled software supply chain to identify which dynamic indicators that need to be updated in order to keep maintain an accurate context
- The developer can use the scorecard to assess which components are not accurately represented by the documented indicators.
## Functional requirements
- The developer can leverage a custom library of Entity relationship components in LucidChart to annotate an architecture diagram with dynamic components
- The developer can leverage a custom library of Entity relationship components in LucidChart to annotate create a Bowtie diagram
- The application can parse a lucidChart page containing an architecture model, bowtie model and link matrix through the csv export format
- The parser needs to extract all the information in the diagrams and store it in python classes, including: Threats, Consequences, Attacks, Dynamic componetns, Indicators (Metrics), and Metric matrix
- The application must visualize threats and their related components in the architecture model
- The application must show the linking indicators between, threats, consequences and architecture components
- The application must rank the indicators based on last update to show which indicators are outdated
- The application must rank indicators based on importance, the importance is based on how many components the indicator has an impact on
## Non functional requirements
- The application will feature a user interface to visualize the parsed data
- The application will be able to handle large diagrams with many components to facilitate for scalability
- The application will only accept csv files from lucidchart as input
- The application will be able to run on as a standalone application on a local machine
- The application will only parse the diagrams if the architecture and bowtie diagram have been annotated with the custom library
## Thesis problem description
The thesis aims to innovate in the area of risk modeling through the use of bowtie diagrams by facilitating the identification and documentation of dynamic indicators related to software supply chain risk.
The goal of the thesis is to research the possibilitiy of graphical linkage between bow tie risk models and entity relationship diagrams.
This is all in an effort to facilitate dynamic risk management for software supply chains.
The main issue with dynamic risk management is the amount of work related to keeping the risk picture up to date, this can however be done using dynamic indicators which impact the different threats related to software supply chains.
The thesis proposes a method for linking bow tie risk diagrams and entity relationship diagrams through dynamic indicators.
The method will use entity relationship components to annotate bow tie risk models and architecture models with dynamic indicators.
Furthermore the method will use tables for standard indicators and attacks relevant to software supply chains.
Having leveraged the method and its components a developer is left with an updated architecture and bowtie model which contains dynamic indicators, to score the diagrams and provide insight a parser will be developed.
This parser will be able to extract the information from the diagrams and visualize the links between the bowtie model and the system architecture.
The parser will present and score the diagram based on amount of indicators and when they were updated.
Moreover the parser will aid in the identification of which relationships are not accurately represented by the documented indicators.
Method formulation and scorecard developement is being done using Technology research. This methodology splits the research into problem definition where a literature mapping was leveraged to understand state of the art.
The next step is innovation where the method and prototype is developed.
For evaluation the method and tool will be tested on two cases provided by partners.
The tool will be subject to emphirical use case driven evaluation where it is tested on the two cases.
Evaluation will be based on the defined success criteria and requirements for the application.
Preceeding the evaluation a new iteration of technology research will be started to improve the method and tool according to the evaluation.
The focus of the annotation will be on risks and aspects related to software supply chains.
The method will use specialized Entity relationship components to annotate the bow tie risk models and architecture diagram, this annotation will facilitate linkage between an entity relationship diagram of a software supply chain and the bow tie risk models associated with it.
Some examples on success criteria are:
- The developer can use the scorecard to assess which components are not accurately represented by the documented indicators.
- By leveraging the method and application a developer will be able to identify dynamic indicators related to the found software supply chain threats, and find the different components in the software supply chain architecture related to these dynamic indicators
Some examples of the tools functional requirements are:
- The application can parse a lucidChart page containing an architecture model, bowtie model and link matrix through the csv export format
- The parser needs to extract all the information in the diagrams and store it in python classes, including: Threats, Consequences, Attacks, Dynamic componetns, Indicators (Metrics), and Metric matrix
Har komponenter
Lagt til lokale metrics i hver komponent
1. Må nå lage en global metric liste FERDIG
2. Må lage ER dynamikk liste
3. Må koble dynamic komponenter til trusselkomponent
# Thesis problem description
Problem description:
The thesis aims to innovate in risk modeling through the use of bowtie diagrams and the identification and documentation of dynamic indicators of software supply chain risk.
The goal of the thesis is to research the possibilities of graphical linkage between bow tie risk models and entity relationship diagrams and to develop a method for this linkage.
This is all in an effort to facilitate dynamic risk management for software supply chains.
The thesis proposes a method for linking bow tie risk diagrams and entity relationship diagrams through dynamic indicators.
The method will use new annotations on bow tie risk models and matrices containing indicators which can be observed for both ER architecture diagrams and bow tie risk models.
To analyze the modeled diagrams and matrices, a analysis tool will be developed to facilitate the analysis and scoring of the modeled risk image.
The scoring will be based on amount of indicators observed for critical components and their status.
Method formulation and scorecard developement is being done using Technology research. This methodology splits the research into problem definition where a literature mapping was leveraged to understand state of the art.
The next step is innovation where the method and prototype is developed.
For evaluation the method and tool will be tested on two cases provided by partners.
Preceeding the evaluation a new iteration of technology research will be started to improve the method and tool according to the evaluation.
The focus of the annotation will be on risks and aspects related to software supply chains.
The method will use specialized Entity relationship components to annotate the bow tie risk models and architecture diagram, this annotation will facilitate linkage between an entity relationship diagram of a software supply chain and the bow tie risk models associated with it.
All resulting in a method which can help in determine which metrics one should observe to pick up on changes in the risk landscape of the software supply chain facilitating dynamic risk management.
Tabell:
Rad 1 to og 3 Er kolonner
Rad
\ No newline at end of file
...@@ -7,7 +7,6 @@ class DynamicComponent: ...@@ -7,7 +7,6 @@ class DynamicComponent:
def __init__(self, componentID) -> None: def __init__(self, componentID) -> None:
self.componentID = componentID self.componentID = componentID
self.metrics = [] # List of metrics for the dynamic self.metrics = [] # List of metrics for the dynamic
self.DynamicsRow = None # The row in the dynamics table the dynamic is associated with
#String only returns necessary info #String only returns necessary info
...@@ -19,16 +18,18 @@ class Metric: ...@@ -19,16 +18,18 @@ class Metric:
def __init__(self, ID, name) -> None: def __init__(self, ID, name) -> None:
#Metrics found in the dynamics tables #Metrics found in the dynamics tables
self.erID = [] # ID of the metric used to locate in dynamics matrics
self.bowtieID = [] # ID of the metric used to locate in dynamics matrics
self.ID = ID # ID of the metric used to locate in dynamics matrics self.ID = ID # ID of the metric used to locate in dynamics matrics
self.name = name # Name of the metric self.name = name # Name of the metric
self.value = None # Value of the metric
self.date = None # Date of the metric
# Metrics found in the metric table self.frequency = None # Frequency of the metric
self.measureGuide = None # Measure guide of the metric
def __str__(self) -> str: def __str__(self) -> str:
return f"Metric: {self.name}, {self.description}" return f"Metric: {self.name}, Value: {self.value} Last update: {self.date}"
class BowtieDynamic(DynamicComponent): class BowtieDynamic(DynamicComponent):
def __init__(self, componentID, type) -> None: def __init__(self, componentID, type) -> None:
...@@ -49,13 +50,14 @@ class BowtieDynamic(DynamicComponent): ...@@ -49,13 +50,14 @@ class BowtieDynamic(DynamicComponent):
return super().__str__() + f"Associated attack ID: {self.associatedAttack[const.Id].item()}" return super().__str__() + f"Associated attack ID: {self.associatedAttack[const.Id].item()}"
def associateBowtie(self, df, componentType, metricsDict: dict):
"""_summary_ """_summary_
Handles the associated dynamics for the bowtie model as they are different from the ER model Handles the associated dynamics for the bowtie model as they are different from the ER model
ER model has one type of dynamic component with metrics however, the bowtie model has three dynamic types and needs more parsing ER model has one type of dynamic component with metrics however, the bowtie model has three dynamic types and needs more parsing
than the ER model du to the modeling annotation. than the ER model du to the modeling annotation.
Abstracting this saves time Abstracting this saves time
""" """
def associateBowtie(self, df, componentType ):
componentId = self.componentID # Define the ID of the component componentId = self.componentID # Define the ID of the component
...@@ -80,12 +82,9 @@ class BowtieDynamic(DynamicComponent): ...@@ -80,12 +82,9 @@ class BowtieDynamic(DynamicComponent):
self.associatedAttack = lineTwo # ! The "line" is an attack, not a line, we add it to the associated attack field and move on self.associatedAttack = lineTwo # ! The "line" is an attack, not a line, we add it to the associated attack field and move on
return # The attack is the only component associated with the dynamic return # The attack is the only component associated with the dynamic
sourceComponent = df.loc[df[const.Id]==lineTwo[const.From].item()] sourceComponent = df.loc[df[const.Id]==lineTwo[const.From].item()]
destinationComponent = df.loc[df[const.Id]==lineTwo[const.To].item()] destinationComponent = df.loc[df[const.Id]==lineTwo[const.To].item()]
if componentType == const.ThreatDynamic: # If the component is a threat if componentType == const.ThreatDynamic: # If the component is a threat
if sourceComponent[const.textArea1].item() == const.Threat: # Checks if source or destination is the threat if sourceComponent[const.textArea1].item() == const.Threat: # Checks if source or destination is the threat
self.associatedThreat = sourceComponent self.associatedThreat = sourceComponent
...@@ -102,6 +101,43 @@ class BowtieDynamic(DynamicComponent): ...@@ -102,6 +101,43 @@ class BowtieDynamic(DynamicComponent):
self.associatedConsequence = destinationComponent self.associatedConsequence = destinationComponent
self.associatedAttack = sourceComponent self.associatedAttack = sourceComponent
self.linkMetric(df, metricsDict)
def linkMetric(self, df, metricsDict: dict):
dynamicComponent = df.loc[df[const.Id] == self.componentID] # Find all dynamics components
for i in range (4, len(dynamicComponent.columns(), 2)): # Iterate through all the metrics
if(dynamicComponent["Text Area"+str(i)] == None): # No more metrics
break
metricID = dynamicComponent.loc[dynamicComponent["Text Area"+str(i)]].item() # Find the metric ID
metricName = dynamicComponent.loc[dynamicComponent["Text Area"+str(i+1)]].item() # Find the metric ID
self.metrics.append(metricID) # ? Adds the metric to the metric list associated with the dynamic component specifically
if checkDuplicateMetrics(metricsDict, metricID) == False: # If the metric is not a duplicate
metric = Metric(metricID, metricName) # Create a new metric object
else:
metric = metricsDict[metricID]
if self.type == const.ThreatDynamic:
if checkDuplicate(metric.associatedThreat, self.associatedThreat): #* If the threat component is a duplicate
continue # * We wont add it to the metric threatList and attack list since its already there
metric.bowtieID.append(self.associatedThreat, self.associatedAttack)
elif self.type == const.ConsequenceDynamic:
if checkDuplicate(metric.associatedConsequence, self.associatedConsequence):
continue
metric.bowtieID.append(self.associatedConsequence, self.associatedAttack)
elif self.type == const.AttackDynamic:
if checkDuplicate(metric.associatedAttack, self.associatedAttack):
continue
metric.bowtieID.append(self.associatedAttack) # TODO Remember to remove duplicates later
metricsDict[metricID] = metric # ! Adds the metric to the global metric list
class ERDynamic(DynamicComponent): class ERDynamic(DynamicComponent):
def __init__(self, componentID, type, description) -> None: def __init__(self, componentID, type, description) -> None:
...@@ -118,7 +154,7 @@ class ERDynamic(DynamicComponent): ...@@ -118,7 +154,7 @@ class ERDynamic(DynamicComponent):
Function will use the dynamic component ID to find linked threats, ER components, attacks and consequences Function will use the dynamic component ID to find linked threats, ER components, attacks and consequences
This will be needed to associate the dynamics with the correct components and analyze relationships This will be needed to associate the dynamics with the correct components and analyze relationships
""" """
def associatER(self, df): def associatER(self, df, metricsDict: dict):
componentId = self.componentID # Define the ID of the component componentId = self.componentID # Define the ID of the component
#Find the lines associated with the component #Find the lines associated with the component
...@@ -145,5 +181,54 @@ class ERDynamic(DynamicComponent): ...@@ -145,5 +181,54 @@ class ERDynamic(DynamicComponent):
self.associatedERComponents.append(associatedComponent) # Add the associated component to the list of associated components self.associatedERComponents.append(associatedComponent) # Add the associated component to the list of associated components
log.info("Associated components found: ", self.associatedERComponents) log.info("Associated components found: ", self.associatedERComponents)
return
self.linkMetric(df, metricsDict)
def linkMetric(self,df, metricsDict):
dynamicComponent = df.loc[df[const.Id] == self.componentID] # Find all dynamics components
for i in range (6, len(dynamicComponent.columns(), 2)): # Iterate through all the metrics
if(dynamicComponent["Text Area"+str(i)] == None): # No more metrics
break
metricID = dynamicComponent.loc[dynamicComponent["Text Area"+str(i)]] # Find the metric ID
metricName = dynamicComponent.loc[dynamicComponent["Text Area"+str(i+1)]] # Find the metric ID
self.metrics.append(metricID) # ? Adds the metric to the metric list associated with the dynamic component specifically
if checkDuplicateMetrics(metricsDict, metricID) == False: # If the metric is not a duplicate
metric = Metric(metricID, metricName) # Create a new metric object
else:
metric = metricsDict[metricID]
for i in range(self.associatedERComponents):
erID = self.associatedERComponents[i][const.Id].item()
if checkDuplicate(metric.erID, erID): #* If the associated component is a duplicate
continue
metric.erID.append(erID)
metricsDict[metricID] = metric # ! Adds the metric to the global metric list
def checkDuplicateMetrics(metricsDict: dict, metricID: str):
"""_summary_
Function will check if the diagrams metric dict contains a metric,
with the same ID as the one which is listed in the dynamics component, if it does
"""
if metricID in metricsDict:
log.warning("Duplicate metric found: ", metricID)
return True
else:
return False
def checkDuplicate(list: list, id: str):
"""_summary_
Check if the already contains the associated component
"""
if id in list:
return True
else:
return False
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment