The first element with a slightly changed syntax and semantics is the AllOf. Figure 4.7 illustrates the difference structures. On the left side is an excerpt of our policy metamodel, and on the right side, the XACML metamodel. However, since the overall semantics for the policy::AllOf stayed the same, as in representing a conjunction for the target definition, the transformation is easily possible. The differences to our metamodel are only some left-out elements. Equation 4.1 illustrates the transformation rules. XACML expects a target definition for every PolicySet, Policy and Rule. Our model encapsulates this in the policy::AllOf. If there was no policy::AllOf element, an empty xacml::Target is created, such as at line 3 or 6 in Listing 4.2. If there exists at least one policy::AllOf like in line 24 from Listing 4.1, for each policy::Allof a xacml::AnyOf is created. The xacml::AnyOf then has one xacml::AllOf, which contains the Match elements from our model. Every policy::Match is transformed to xacml::Match elements. These can be multiple elements since not every policy::Match can be reduced to one xacml::Match (see MatchTransformation). For our target definition in line 24 from Listing 4.1, the transformation results look like the target starting from line 9 from Listing 4.2.

The next custom elements are the match elements. We provide four matches EntityMatch, MethodMatch, GenericMatch, XMLMatch. The transformation for the first three elements is illustrated in Figure 4.8. For each match, the transformation is separated by a horizontal line. The common ground for

the three matches is that they are contained by an AllOf element. In addition, the transformation always creates xacml::Match elements with corresponding xacml::AttributeValue elements for the reference values and xacml::AttributeDesignator for the selection of the attributes. As an alternative, XACML would also allow using a AttributeSelector in a match. However, the AttributeSelector is optional and, therefore might not be available in all implementations. In addition, the usage might be more complicated since it uses XPath expressions [207] to identify the attributes. Therefore, we choose the variant with the AttributeDesignator. We repeated this design decision also in other transformations, where there is a choice between AttributeDesignator and AttributeSelector. We will now explain each transformation in more detail.

The policy::EntityMatch is used to identify an architectural element, such as a ResourceContainer or AssemblyContext. The simplified identification of these elements happens by using the id and the name of the architectural element. Each element is an Entity in PCM and therefore needs to have these attributes. The id and name are from the type string. Hence, the datatypes in the XACML elements are strings. The xacml::AtributeValue sets the reference value, and the xacml::AttributeDesignator selects the values from the request. The attribute is selected based on the category from the policy::EntityMatch. The Category in xacml::AtributeDesignator is directly taken from the policy::Entitymatch. The AttributeID is the name for the category extended with "id". For instance, for the category resource, the id would look like "resource:resource-id". Because the reference value with the xacml::AttributeValue and the attribute selection from the request with the xacml::AtributeDesignator both have the datatype string, we use the string-equal as the compare functions. It compares two strings for equality and is set by the MatchID in xacml::Match.

The policy::MethodMatch transformation is separated in two cases depending on the concrete subclass of the contained policy::MethodSpecification. For both cases, the transformation results into two xacml::Match elements. The first is to identify the instance of the service, and the second is to identify the service. Splitting the selection into two matches is not problematic since the conjunction of the matches guarantees that both matches always need to be fulfilled for the target selection. The transformation with the policy::ServiceSpecification consists of two parts. The first part is to identify the instantiated component where the service is running, and the second part is for the identification of the service. The first xaml::Match is

**Figure 4.8.:** EntityMatch, MethodMatch and GenericMatch transformation

for the component selection and is similar to the transformation with the poliy::EntityMatch with the exception that the entity is replaced by its child element AssemblyContext representing only an instantiated component and the direct setting of the resource category. The second xacml::Match is used for the identification of the service. For the service, we choose the string datatype again. Therefore, the MatchID is again string-equal. In our case, we choose to identify a service by its id. Therefore, we use the Signature.id as the value for the reference value. XACML provides a special category for actions performed on the system. In our case, we see a service also as an action. In our transformation, the service is also stored in the action category. Hence, the Category in the xacml::AtrributeDesignator is selecting the action category by using "attribute-category:action". The AttributeId is then the suggested attribute used by XACML to identify an action. An example of this transformation can be found in Listing 4.2 starting from line 12. The first match elements describe the service selection, and the second match (starting from line 16) the component selection.

In the case with a policy::ConnectionSpecification, the xacml::Match for the service selection is the same as in the case with the policy::Service-Specification. However, in the xacml::AttributeValue contained by the other xacml::Match, the value is replaced by the id and name of the connector from the policy::ConnectionSpecification. The other elements stay the same.

For the policy::GenericMatch transformation, the MatchID is determined by the selected operation from policy::GenericMatch. The xacml::Attribute-Designator.category is also directly taken from the original element. The datatypes, the actual reference value, and the AttributeId are derived from the policy::GenericMatch.value

The last match transformation is the XMLMatch. Here, software architects already specify a match in XACML. Therefore, we do not need to transform it to an XACML statement. Yet, we still need to add it at the right position in the XACML model. One possible solution could be that we just add the textual description in the output XACML file. However, in this case, we would need to somehow store the information where to add the XACML strings and also consider the correct syntax for adding an element. In addition, the internal XACML model would be incomplete, and only the serialized XML file would be a complete model. This is especially for referenced values not good. Therefore, we choose to first parse the XACML statement with the Java

**Figure 4.9.:** SimpleAttributeSelection transformation

Marshaller, which results in a XACML model of the statement. This model is then added to the internal XACML model during the transformation.

The transformations for Policy, Rule, VariableDefinitions, VariableReferences, FunctionReferences, AttributeDesignator, and Apply are straightforward. It is copying the values from our policy metamodel to the matching value in XACML.

The custom element XMLString is transformed in the same way as XMLMatch by using the Java Marshaller.

The policy::SimpleAttributeSelection basically encapsulates the condition to check for an attribute. The transformation creates the XACML elements along the description of the bag comparison in XACML [132, A.3.12]. The basic idea is to use an xacml::Apply, and its parameters are a xacml::Function, a xacml::AttributeValue and a xacml::AtributeDesignator to select the bag from the request attributes.

The attributes from xacml::Apply are derived from the following. For the FunctionID, depending on the only value, either Any-Of or All-Of is chosen. The difference is that for Any-Of, there could be different values in the bag derived from the xacml::AttributeDesignator. In the case of All-Of, all values need to be the reference value. An example of this behaviour is that a requestor has multiple roles. Depending on the only value, it is allowed to have multiple roles for a requestor, or it is forbidden. The Description is derived from the name. The compare function is set within the xacml::Function with the value FunctionID to string-equal. This compares the bag values to the reference value (xacml::AttributeValue). The xacml::AttributeValue.Datatype and xacml::AttributeValue.value is derived from the policy::SimpleAttributeSelection.attribute. The third

parameter is the bag selection by the xacml::AttributeDesignator. The Category can be directly derived from the category from the original element. The AttributeId and Datatype can be derived as with the xacml::Attribute-Value from the attribute. The Issuer is an optional attribute. It indicates the origin of an attribute. In our case, we set it if the attribute contains an EntityAttribute. Then it is set to the id of the architectural element issuing/producing the attribute.

An example of this transformation can be found in Listing 4.2 with the apply element starting from line 26. Starting from line 32, it shows an example where an issuer is used. The issuer is the id of the entity which generates the attribute. In our case, it is the AssemblyContext for the MachineComponent. We can see that the same id is used during the match in line 17.

Besides the policy transformation, the second transformation type is the access request transformation. The transformation is exemplarily illustrated in the lower parts at Figure 4.5. At the start, the PDP loads our transformed XACML model. The analysis then creates based on the software architecture and the policy model a request. The request is already structured according to a XACML request. Hence, it assigns attributes to the different categories. However, the attributes still use our policy metamodel. In the next step, the request is transformed to a valid XACML request. An example is shown in Listing 4.3. Then the PDP can evaluate the request, and based on the result, the analysis builds the PDRResult model. The metamodel for this is illustrated in Figure 4.10. This structure is useful since it decouples the request from the request evaluation. It enables us to replace the used PDP with any other XACML compatible PDP. We will now explain the necessary steps in more detail.

During the request creation, we assign the requestor's context and the requested architectural element to the categories subject (for the requestor), environment, resource (for the requested element) and action. Some of these attributes are already preassigned during the attribute creation, and others are dynamically derived, such as the resource. Afterwards, we have a list of UsageSpecifications for each category.

The next step is to transform the list to an XACML request similar to the request in Listing 4.3. For this, we transfer each attribute, similar to the policy transformation for an XACML element. Listing 4.3 illustrates the request for the technician to access the machine. The subject attributes are listed starting from line 2. In our case, this is the role with Technician. The resource **Listing 4.2:** Simplified XACML file for the technician scenario from the running example

```
1 <PolicySet xmlns="core:schema:wd-17" PolicySetId="_d7xFEZSjEeyvBd3n0aDE-g" Version="0.0.1"
      Ç PolicyCombiningAlgId="policy-combining-algorithm:deny-unless-permit">
2 <Description>Policies for MaintenanceSystem</Description>
3 <Target/>
4 <Policy PolicyId="__-SiIbQGEeyBBMZUdAqcvg" Version="0.0.1"
         Ç RuleCombiningAlgId="rule-combining-algorithm:deny-unless-permit">
5 <Description>Machine</Description>
6 <Target/>
7 <Rule RuleId="_BcIZILQHEeyBBMZUdAqcvg" Effect="Permit">
8 <Description>Technican Access</Description>
9 <Target>
1 0 <AnyOf>
11 <AllOf>
1 2 <Match MatchId="function:string-equal">
1 3 <AttributeValue DataType="string">_HZ11cJSREeyOldzBRFqWVw
                           Ç </AttributeValue>
1 4 <AttributeDesignator Category="attribute-category:action"
                           Ç AttributeId="action:action-id" DataType="string"/>
1 5 </Match>
1 6 <Match MatchId="function:string-equal">
1 7 <AttributeValue DataType="string">_4lwccJSYEeyjlrv9ryW3Zw
                           Ç Assembly_MachineComponent</AttributeValue>
1 8 <AttributeDesignator Category="attribute-category:resource"
                           Ç AttributeId="resource:resource-id" DataType="string"/>
1 9 </Match>
20 </AllOf>
21 </AnyOf>
22 </Target>
23 <Condition>
24 <Apply FunctionId="function:and">
25 <Description>aName</Description>
26 <Apply FunctionId="function:any-of">
27 <Description>aName</Description>
2 8 <Function FunctionId="function:string-equal"/>
29 <AttributeValue DataType="string">Technican</AttributeValue>
3 0 <AttributeDesignator Category="subject"
                        Ç AttributeId="_f4Ph0rGMEeyLRdjos_zQbg" DataType="string"/>
31 </Apply>
32 <Apply FunctionId="function:any-of">
33 <Description>aName</Description>
3 4 <Function FunctionId="function:string-equal"/>
35 <AttributeValue DataType="string">Failure</AttributeValue>
3 6 <AttributeDesignator Category="attribute-category:resource"
                        Ç AttributeId="_S5hooLGMEeyLRdjos_zQbg" DataType="string"
                        Ç Issuer="_4lwccJSYEeyjlrv9ryW3Zw"/>
37 </Apply>
3 8 </Apply>
39 </Condition>
4 0 </Rule>
41 </Policy>
42 </PolicySet>
```

**Listing 4.3:** Generated XACML request for the technician scenario

attributes are listed starting from line 8. The first attribute is the machine states with Failure, which resonates from the Machine. Hence, it contains the Issuer with the Machine's ID. The second attribute is the Machine. The third attribute category is the action, starting from line 16. It contains the ID of the called service. The PDP then uses the described policy in Listing 4.2, matches the request on it, and then evaluates it. In our case, since the Machine and Service matches the target for the Rule ("\_BcIZILQHEeyBBMZUdAqcvg"), the condition is evaluated. The conditions evaluate to Permit since the role and machine state match the expected values.

This decision of the PDP must be then transferred to the analyses. To transfer the result, we develop a simple data exchange metamodel, illustrated in Figure 4.10. The PDPResult encapsulates the access decision with the decision. A decision can be analogues to XACML either PERMIT, DENY, INDETERMINATE, NOT\_APPLICABLE. PERMIT and DENY directly follow from the rule effect. INDETERMINATE is, when the PDP cannot decide a concrete rule. This can be, for instance, if an error happens or there are multiple contradicting effects. NOT\_APPLICABLE indicates that no rule could be applied for the request from the PDP. In addition to the decision, the PDPResult stores also with the policyIdentifiers a String list with the identifiers involved in

**Figure 4.10.:** Result model for PDP decisions

the policy decision. For instance, with our example request (Listing 4.3) and policy (Listing 4.2) this is "\_\_-SiIbQGEeyBBMZUdAqcvg". These identifiers are not useful for the analysis itself. However, they help to interpret the results of an analysis since they enable the tracing of a decision back to the involved policies. In addition, they are helpful during the debugging of the analyses.

## **4.3. Considering Vulnerabilities in Software Architecture Models**

**org.palladiosimulator.pcm.confidentiality.context.xacml.pdp.result** policyIdentifiers:String [0..\*] This section describes our modelling concept for vulnerabilities in software architecture. Together with the metamodels for attacks (c.f. Section 4.4), and attackers (c.f. Section 4.5), it forms our contribution C2. The contribution C2 answers together with contribution C1 our research question RQ2.1 and both build the foundation to answer the research question RQ2.2. We introduced the vulnerability metamodel in Walter et al. [211]. Afterwards, we extended the metamodel in Walter et al. [212] for further security properties and in Kirschner et al. [94] we extended the metamodel to support the automatic extraction of security properties.

Besides the access control policies, other properties influence the security of a system. For instance, the vulnerabilities of a system can be used to compromise a system and affect its overall security. Vulnerabilities can be found in different architectural elements, such as the components or deployed network resources. Usually, a system can contain known vulnerabilities, such as Log4Shell [130]. Log4Shell can enable attackers to exploit arbitrary code

and thereby enable them to compromise an architectural element. In addition to the known vulnerabilities, a system contains unknown vulnerabilities. In the case of unknown vulnerabilities, security experts often determine potential security threats, for instance, with threat models. However, a vulnerability alone is not enough to determine the security influence since the exploitation often depends on the context and properties of a vulnerability. For instance, the access control approach can prohibit the exploitation or enable an exploit. Therefore, it is necessary to model vulnerabilities together with their properties. These models can then be used during the analyses to decide whether they can be exploited. For specifying models with a welldefined syntax, we developed a metamodel and integrated the metamodel in PCM.

In this section, we will first describe in Section 4.3.1 the requirements, which guided the development of the metamodel. Afterwards, we describe our vulnerability identifiers in Section 4.3.2. In Section 4.3.3, we describe our vulnerability metamodel and the integration into PCM in Section 4.3.4. Section 4.3.5 describes an approach to automatically derive vulnerabilities.

#### **4.3.1. Requirements for Modelling Vulnerabilities**

During our work, we identified different additional requirements besides the purpose to express vulnerabilities, the exploitation of vulnerabilities and attackers. These additional requirements guided the metamodel development and helped us to identify important properties. We derived the requirements iteratively based on our work in different research projects, related work and vulnerabilities databases. As a starting point, we used our initial case studies [11, 169, 12] and existing vulnerability description from databases, such as the NVD [131] or CAPEC [38]. We iteratively developed the metamodel and redefined the requirements based on found use cases and scenarios. In the following, we will first list our identified requirements and afterwards discuss the concrete reasoning. Our final set of requirements are:

VR3 Security experts should be able to reuse knowledge about existing concepts for the definition of vulnerabilities.

The first requirement VR1 describes similar to AR1 that we need to annotate vulnerabilities on different layers in the software architecture. This is necessary since vulnerabilities can be found on different levels of abstraction. We started the metamodel to describe vulnerabilities only for the components of a system. This is very common and are also performed by other approaches, such as CVE. For instance, the Log4Shell [130] vulnerability is a software vulnerability. It can be annotated in ADLs to existing components and then represents a vulnerable component. Yet, ADLs like PCM differ between instantiated components (AssemblyContext in PCM) and component types (e.g. BasicComponent in PCM). Also, for a vulnerability, a differentiation is useful since some vulnerabilities only apply to certain configurations. Here, the instantiated components can be used to differentiate between different configurations, which might be vulnerable or not. Therefore, it is important to differ between the type and the instance level and the modelling approach should consider these differences. However, during our work, we also identified the need to consider other architectural layers, such as the network resources and the hardware resources. For instance, vulnerabilities, such as Meltdown [105] or Spectre [95] are hardware vulnerabilities. Therefore, it is necessary to consider vulnerabilities also in other architectural elements besides the software components. In addition, there can be different abstraction layers for a software architecture. For instance, the operating system can be modelled like in our running example as a ResourceContainer and not as a separate component.

VR2 describes that the vulnerability model contains concrete vulnerabilities like the Log4Shell vulnerability. Concrete vulnerabilities are known and described in existing databases, such as the NVD. Different studies, such as a study by Unit 42<sup>7</sup> or a report by the UK government [84] show that software contains known vulnerabilities or outdated software, which again usually contains known vulnerabilities. These studies show the need to consider known vulnerabilities because they are a real problem and exist. Therefore, we added the first part regarding the known vulnerabilities to

<sup>7</sup> J. Greig. 96% of third-party container applications deployed in cloud infrastructure contain known vulnerabilities: Unit 42. en. Oct. 2021. url: https://www.zdnet.com/article/96-of-thirdparty- container- applications- deployed- in- cloud- infrastructure- contain- knownvulnerabilities-unit-42/ (visited on 04/03/2023).

our requirement VR2. We derived the second part of the requirement based on the fact, that not all attacks are known. Either because we are still in an early development phase, where concrete aspects are unknown, for instance, if no implementation exists or the concrete hardware is not yet chosen. In other cases, it can be that so far no vulnerabilities have been identified in the system. In these cases, security experts often perform a threat analysis for the system and identify possible threats in the system. These threats are often not concrete in the sense that they describe concrete exploits. They describe an abstract concept of how to compromise an architectural element. For instance, the CWE concept enumerates multiple possible weaknesses, such as no input validation [113] or the usage of hard-coded credentials [116]. However, considering these threats as vulnerabilities is beneficial because it enables security experts to analyse the system and give an early estimation of potential security incidents. For us, these threats represent non-concrete vulnerabilities. Therefore, we added them as part of the requirement VR2.

The last requirement VR3 describes the reuse of knowledge and concepts by security experts. There exist databases which document security vulnerabilities, such as the NVD or various private company sites like, e.g., for Ubuntu<sup>8</sup> or the Microsoft Security Response Center<sup>9</sup> . These services provide similar classifications for vulnerabilities and experts usually are familiar with the classifications. Using similar concepts can help an expert since it saves effort to learn a completely new concept. In our case, we see concepts as similar if they contain the same attributes and these attributes are derived similarly. For instance, a commonly used concept of vulnerability databases is CVSS. This concept contains the attribute attack vector with the meaning that it classifies the location from which a vulnerability can be exploited. Based on our requirement, we expect that if the metamodel also has an attribute attack vector, the semantics would be the same or similar. Another advantage of having a similar concept is that the knowledge about classified vulnerabilities can be reused. The classification of a new vulnerability is hard and many different aspects like the complexity or the impact need to be considered. One example for the complexity of the classification is the vulnerability in our running example (c.f. Chapter 3). During our work on this thesis, the used vulnerability CVE-2021-28374 was reclassified [129]. This shows that

<sup>8</sup> CVE reports. url: https://ubuntu.com/security/cves (visited on 01/17/2023).

<sup>9</sup> Security Update Guide. url: https://msrc.microsoft.com/update- guide/vulnerability (visited on 01/17/2023).

for some vulnerabilities, the classification is not easy. Hence, reusing the knowledge of the databases can reduce the effort to classify complicated vulnerabilities. However, for reusing these values, our metamodel needs to use similar values. Therefore, we choose VR3 as a requirement.

### **4.3.2. Modelling Identifiers for Vulnerabilities**

During the modelling and the analysis, we need to identify a vulnerability. One possibility to identify a vulnerability is to reuse existing identifiers or classifications. In our case, we choose to reuse the concepts CWE and CVE. These are commonly used concepts to identify weaknesses and vulnerabilities. We use CVEs to identify concrete vulnerabilities. For many known vulnerabilities CVEs exist. For the non-concrete vulnerabilities, we use CWEs. These are used to categorize common security weaknesses in hardware and software.

We integrated these concepts into our metamodel. Figure 4.11 illustrates the elements involved in the identification. The common parent element is the abstract AttackCategory. A CWE is encapsulated by the CWEID. The actual category is stored in the cweID as a String. An example value can be "CWE-312" which represents the "Cleartext Storage of Sensitive Information" [114]. CWE also is hierarchical with multiple parents and children. For instance, CWE-312 has, among others, CWE 922 with "Insecure Storage of Sensitive Information" [117] as a parent. It also has multiple children, such as CWE-313 or CWE-314. This relationship to other CWEs can be set by the parents and children attributes.

The CVEID encapsulates a CVE identifier. The value is stored in the cveID as a string, similar to the CWE. For example, the vulnerability in our running example would be stored as "CVE-2021-28374" [129]. A CVE also has often relating CWEs. In our case, we choose to model this not in the identifiers, but it is encoded in later introduced elements.

### **4.3.3. Modelling Vulnerabilities**

For modelling different vulnerabilities in the architectural model, we developed a vulnerability metamodel. The key idea of the metamodel is to reuse existing knowledge about vulnerabilities and their classifications. Therefore,

**Figure 4.11.:** Category metamodel elements based on [211]

we analysed different existing classifications and descriptions, such as CWE, CVE and CVSS.

Figure 4.12 illustrates an excerpt of the vulnerability metamodel. The grey elements are existing elements from PCM. The metamodel contains two types of vulnerabilities: CVEVulnerability and the CWEVulnerability. The first is built on the concept of CVEs and the second is based on CWEs. They share the same parent classes. One parent class is the abstract CWEBased-Vulnerability. It encapsulates the reference to the CWEs with its id attribute. Both vulnerabilities share this since a CVE matches to CWE-categories. For instance, the vulnerability "CVE-2021-28374" in our running example has the CWE "CWE-312". In some cases, there can be more than one CWE for a CVE. Hence, the id can have multiple CVEIDs.

Remark: During the writing of the thesis, the CWE class from the vulnerability in the running example was remapped to CWE-712 [129]. In our thesis, we continue to use the old classification.

The impact and further properties of a vulnerability are described in the abstract Vulnerability. It is also a parent element for the CVEVulnerability and the CWEVulnerability. We differ in the attributes similar to CVSS between attributes describing the exploitability and attributes describing the impact [44]. Both attributes are either based on the description of relevant attributes from vulnerability databases and security incidents or are based on the Base Metric Group from the CVSS calculation [44]. However, we do

**Figure 4.12.:** Vulnerability metamodel elements based on [211]

not use from CVSS the scoring. We only use the metrics used for the scoring calculation. It is also not necessary to use CVSS to gather the necessary values. Other similar approaches, such as Common Weakness Scoring System (CWSS) [112], can be used as long they share similar properties. Reusing these values is beneficial since determining the metrics and classifying a vulnerability is complicated and with the reuse, we can reduce the effort of manually determining the attributes. In addition, using a possible familiar description fulfils VR3. To get a better understanding, which elements are derived from CVSS, we mark them with an asterisk (\*) at their initial description. We will start first the description with the exploitability attributes and afterwards describe the impact:

CVSS metric. However, during the analyses, we only differ between authorised and non-authorised. Hence, Low and Special are considered as one element since PCM currently does not support different authorisation levels.

Besides the attributes describing the vulnerability's exploitability, the metamodel also contains the impact of a vulnerability. The impact of confidentiality can differ. For instance, the vulnerability in our running example can lead to the loss of credentials. Other vulnerabilities might not have the same result. Our impact attributes are:

• confidentialityImpact\*: Based on the CVSS metric, the enumeration ConfidentialityImpact describes how the vulnerability affects the confidentiality of the architectural element. The metamodel differs as in CVSS between None, Medium, and High. In our case, we use these values to indicate whether data from an architectural element can be stolen by exploiting the vulnerability. This assumes that all data is considered to some extent confidential. As for the extraction, we do not differ between Medium or High. Both elements lead to an extraction. This is based on the fact that the PCM currently does not differ between confidentiality levels. However, in the future, it might be possible. Therefore, we keep the differentiation and in addition, our modelling sticks closer to the existing standard metric from CVSS.

does not automatically result in a confidentiality impact since data could be encrypted like with end-to-end encryption [121].

• gainedAttributes: This attribute describes that, by exploiting a vulnerability, the attacker could gain the listed attributes. This attribute is derived from public descriptions of security incidents and databases. For instance, the vulnerability in our running example states in the description that it can leak credentials [129]. Based on this description, an expert can then assign with our metamodel which credentials they are. In our case, we model credentials as a list of UsageSpecifications. In this way, it is consistent with the access control metamodel (c.f. Section 4.2).

Many of these attributes are also system independent. This means that experts only need to create the model once and the model can be transferred to other software architectures. In general, all the CVSS based attributes are system independent. In addition, the role and takeOver is system independent. Nevertheless, there could be certain instances where it is not possible. This is similar to the CVSS specifications, which allows for customisation since sometimes a vulnerability is dependent on the concrete configuration. However, in these cases, the experts can adapt the model to their liking. In contrast, the gainedAttributes is system dependent since it contains the concrete credentials for a system. Usually, the access control model is specific to the concrete system. Nevertheless, in some cases, it is possible to transfer the access control model or at least the role/attribute model. In these cases, the attribute is considered system independent.

A Vulnerability is connected to different architectural elements. The vulnerability metamodel supports the annotation of a BasicComponent, CompositeComponent, ResourceContainer, LinkingResource, AssemblyContext, and MethodSpecification. In Figure 4.12, we marked the annotation with dashed lines with open arrows and the name vulnerable. We use this special syntax to indicate that the annotation is more complex and will be explained later on. However, for simplicity reasons, we want to show here the architectural elements. The different elements cover different layers with ResourceContainers as hardware layers or AssemblyContext for logical ones. Hence, it covers also VR1. So far, not every analysis supports every architectural element. Especially, the CompositeComponent is not supported by any attack analyses. However, for completeness, we add it to the vulnerability model. Future versions of the attack analyses may support it.

**Listing 4.4:** Simplified textual representation of the vulnerability model instance from the running example

```
1 CVEVulnerability {
2 cveID CVEID{
3 cveID: "CVE−2021−28374"
4 },
5 cweID CWEID{
6 cweID: "312"
7 },
8 attackVector: Network,
9 privileges: None,
1 0 attackComplexity: Low,
11 userInteraction: None,
1 2 confidentialityImpact: High,
1 3 integrityImpact: None,
1 4 availablityImpact: None,
1 5 takeOver: true,
1 6 gainedAttributes: {admin},
1 7 }
```
An example model instance is illustrated in Listing 4.4. It is a textual representation of the vulnerability "CVE-2021-2874" from our running example. We first have the CVE and corresponding CWE category. These values can be directly read from the NVD homepage.  These values can be directly extracted from the CVSS vector. The vector for our vulnerability looks like "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N" [129]. The vector consist of pairs with types and values. Each pair is separated by a slash ("/"). The first pair defines the used CVSS version. Afterwards, the different base metrics are described. For instance, AV:N stands for Attack Vector: Network and states that the attack vector is network. Based on the vector, these properties can be filled. The last two elements in our model instance are filled based on the description of the vulnerability and on the individual modelled system. In our case, this is that the component can be compromised by the vulnerability and that the vulnerability can leak the admin attribute.

### **4.3.4. Integration in Palladio**

Up to now, we cannot annotate existing PCM elements with our vulnerabilities. In Figure 4.12, the annotation is only hinted by the dashed line, but the concrete realisation is not given. However, the annotation is necessary because, without it, it is unclear which vulnerability belongs to which architectural element. Therefore, it is necessary to integrate the vulnerabilities into the PCM.

The main concept for the PCM integration is that we want to extend existing architectural elements with the Vulnerability property. Strittmatter [192] describes this behaviour as a Metamodel Extension. He proposed in his work different mechanisms to realize a model extension. In our case, we chose the method "Referencing with External Container" [192, p. 109]. This decision is mainly based on technical reasons. The inheritance approach would be technically feasible as well. However, the editor creation would be much more cumbersome because of the internal PCM configuration. The other extension mechanism over profiles was technical not reliable. The referencing approach works on a technical level reliable and adds the benefit that the vulnerability package itself is independent of the used ADL.

Figure 4.13 illustrates the integration into PCM. The integration is contained within a separate metamodel package to separate the PCM-specific elements and the non-PCM-specific elements. The main concept is that we form a link between our new metamodel elements and the architectural elements. The abstract class SystemIntegration stores the link to our new metamodel elements. It contains one PCMElement. PCMElement reflects the PCM integration. It inherits from RepositoryElement, ResourceEnvironmentElement, System-Component (indirectly), and SystemElement the association to architectural elements. Therefore, the metamodel supports the extension of the following architectural elements: CompositeComponent, BasicComponent, ResourceContainer, LinkingResource, AssemblyContext, and MethodSpecification.

The extension or annotation for the architectural elements is specified by the subclasses from the SystemIntegration. This element links the architectural element with the annotation. There are three concrete subclasses:

• VulnerabilitySystemIntegration references a Vulnerability and links the selected archiectural element to the selected Vulnerability.

#### **4.3.5. Automatic Derivation of Vulnerabilities**

Remark: In the previous sections and in the sections afterwards, I was the lead contributor. In this subsection, we discuss a shared contribution. For the extension of the attack propagation analysis and the corresponding metamodel extension to support the automatic derivation, I was the lead contributor. The shared contribution is the identification of the vulnerabilities and the automatic vulnerability model creation based on our vulnerability metamodel. Figure 4.14 illustrates this by using the grey background for artefacts where I am the lead contributor and black for artefacts where I was the co-contributor.

Since the vulnerability metamodel elements are based on commonly used approaches and some of these attributes are publicly available in databases, it is possible to automate the derivation of some vulnerabilities.

In a publication [94], which I co-authored, we investigated the automatic derivation of vulnerabilities for existing source code. This is combined by an architecture recovery approach [93] from the co-authors of the paper.

The developed approach is illustrated in Figure 4.14. The basic concept is that a static code analysis extracts from the build configuration the dependencies. In our case, we use Snyk<sup>10</sup> as a static analysis. The analysis then compares the dependencies to their list of vulnerable components and returns for each build artefact a list of security vulnerabilities. Our new approach (black box in Figure 4.14) then uses these security vulnerabilities and extracts the CVE from it. Based on the extracted CVE, it queries the NVD via its Rest-API for the CVSS metric. It then creates a vulnerability model by using our vulnerability metamodel.

For mapping the created vulnerability to PCM elements, we used the architecture recovery approach from Kirschner [93] with his trace link model. The trace link creates a link between the build artefact and the recovered components. So far, this approach is limited to BasicComponents. Other artefacts, such as the ResourceContainers or LinkingResources, cannot be recovered.

After creating the vulnerability model and linking it to the recovered components, the security experts have to enrich the model to use our attack propagation analysis. They need to create the missing architectural model, such as Assembly, Deployment and ResourceEnvironment. In addition, they need to enrich the model with access control information and, if necessary, adapt the vulnerability model. The adaption can be necessary since the NVD uses a more general version of a CVSS, and it might vary for different configurations.

Using this approach can help to reduce the effort for identifying existing vulnerabilities and modelling these. However, it does not help with unknown vulnerabilities. However, in the future, the approach might be extended to support these. In Kirschner et al. [94], we discuss the accuracy of the approach regarding different case studies.

## **4.4. Considering Attacks in Software Architecture Models**

This section covers the modelling concept for attacks in software architectures. It is part of our contribution C2 together with the vulnerability metamodel

<sup>10</sup> url: https://snyk.io/ (visited on 11/02/2021).

**Figure 4.14.:** Approach for automatic extraction of vulnerabilities based on [94]

(c.f. Section 4.3) and attacker metamodel (c.f. Section 4.5). The contribution C2 and C1 answer our research question RQ2.1. In addition, the contribution C2 is part of the foundation to answer research question RQ2.2. We published this metamodel part in Walter et al. [211].

The previous sections described the vulnerability metamodel and how it enables an architect to assign vulnerabilities to architectural elements. The vulnerabilities already have information about how to exploit them and what the impact of the exploitation is. However, the actual exploitation is not described or modelled. The exploitation is usually performed through an attack. In our modelling, these attacks represent also the activities a malicious user can perform to exploit a vulnerability. Therefore, we call these also the capabilities of an attacker.

In this section, we will first describe the requirements for our attack metamodel in Section 4.4.1. Afterwards, we describe in Section 4.4.2 our attack metamodel.

#### **4.4.1. Requirements for Modelling Attacks**

Like in the previous modelling sections, we identified different requirements, which guided the development of our metamodel. As previously done, we will first list the identified requirements and afterwards discuss the reasoning. Our identified requirements are the following.

**Figure 4.15.:** Attack metamodel elements based on [211]

**attacker.attackSpecification** The first requirement can be derived from our intended purpose of our attack modelling. The purpose of the attack part of our metamodel is to express attacks exploiting the modelled vulnerabilities. Therefore, it is necessary to be compatible to our vulnerability metamodel because security experts need to use the modelled vulnerabilities. Hence, ATR1 states that the attack needs to be compatible with the described vulnerability metamodel elements. Otherwise, there is no connection between the modelled attacks and vulnerabilities.

The second requirement ATR2 can be derived based on ATR1 and the similar requirement VR2 from the vulnerability metamodel. Because the vulnerability metamodel contains concrete and non-concrete vulnerabilities, the attacks need to handle concrete and non-concrete attacks. Another benefit of supporting non-concrete attacks is to express groups of attacks and therefore ease the modelling since not every single attack needs to be modelled.

#### **4.4.2. Modelling Attacks**

The capabilities of attackers are modelled as different attacks they can perform. The attacks are also represented in our developed metamodel. Figure 4.15 shows the involved metamodel elements.

The basic idea is to reuse the concepts from CVE and CWE again. These concepts are already used in the vulnerability part and widely adopted in the security domain for vulnerabilities. For simplicity reasons, we explicitly decided against using attack modelling concepts like the Common Attack Pattern Enumerations and Classifications (CAPEC) [38]. While these dedicated attacker description can be useful, they were not necessary for our analyses and would, in our eyes, only complicate the model creation. Therefore, we chose to use a more simplistic approach and reuse the CVE and CWE parts. This results in our two concrete attack elements which are the CVEAttack and the CWEAttack. Each element has an id attribute representing a reference to their respective id element. The id can be used later to match whether the attack could exploit a vulnerability. The CVEAttack can only exploit vulnerabilities with the same CVEID. This represents the possibility to model concrete attacks. The CWEAttack models the capability to exploit groups of attacks. A CWEAttack can exploit a vulnerability with the same CWEID. In addition, it can exploit all vulnerabilities with a child CWEIDs from its CWEID and all vulnerabilities with their CVEID belonging either to its CWEID or any child CWEID. For instance, an attack with the CWEID "CWE-312" can exploit among others CWEVulnerabilties with "CWE-312", "CWE-313", "CWE-314". In addition, it also can exploit among others the CVEVulnerability "CVE-2021-28374". By using the attacks in this way, we also use fulfil ATR2 and ATR1 since the concrete CVEVulnerabilities and the non-concrete CWEVulnerabilities can be exploited by our attack metamodel elements.

Each attack inherits from CategoryAttack and Attack. The CategoryAttack encapsulates all attacks, which are based on a categorisation. Currently, these are the only attacks, the metamodel supports. The Attack is the abstract element for all attacks. It defines a boolean operation which can check whether a Vulnerability can be exploited by an Attack.

## **4.5. Considering Attackers in Software Architecture Models**

This section explains our metamodel for attackers in software architectures. It is part of our contribution C2 together with the vulnerability metamodel (c.f. Section 4.3) and attack metamodel (c.f. Section 4.4). The contribution C2

**Figure 4.16.:** Attacker propagation metamodel elements based on [211]

and C1 answer our research question RQ2.1. In addition, the contribution C2 is part of the foundation to answer research question RQ2.2.

credentials:UsageSpecification [0..\*] So far our metamodel can express the vulnerabilities and the attacker capabilities required for exploitation. In combination with the access control metamodel from Section 4.2, a software architect can also model the access control policies. However, the metamodel does not cover so far dedicated malicious users. In our metamodel, we call these malicious users attackers. In our case, attackers have capabilities and knowledge. Capabilities are for us the attacks they can perform and knowledge is useful information they have about the system, such as credentials.

In this section, we will first describe a dedicated attacker for attack propagations in Section 4.5.1. Afterwards, we describe in Section 4.5.2 an attacker for filtering different attack paths.

### **4.5.1. Modelling Attackers for Attack Propagation**

The first attacker type is for an attack propagation. The main concept is that an attacker has an initial starting point in the architecture. Based on this starting point the attacker can propagate to other elements by using their knowledge and capabilities. This behaviour is similar to insider attacks or system breaches, where the attacker propagates from one breach point through the system. We initially published this attacker in Walter et al. [211].

Figure 4.16 illustrates the metamodel elements for this attacker type. The central element is the Attacker. The capabilities of the attacker are explic-

**Figure 4.17.:** Attacker propagation instance for the running example

itly and implicitly modelled. The explicit capabilities are the Attacks. An Attacker can have multiple or none Attacks. The implicit capabilities are the capability to use the knowledge of credentials and automatically compromise components on compromised hardware. For the first, the knowledge is modelled as a list of UsageSpecifications representing credentials.

The start point is represented by contained SystemComponents and Resource-EnvironmentElements. These are reference elements into the PCM (c.f. Section 4.3.4). The start point can cover multiple elements, for instance, in case of multiple breach points.

A possible attacker for our running example can look as in Figure 4.17. This model describes a scenario, where an attacker somehow got access to the Terminal and uses it as a starting point for an attack on the system. In this case, the Attacker has no initial knowledge about credentials, but can perform a CWEAttack for "CWE-312". This attack describes, that an attacker can use credentials stored in cleartext. Hence, we assume it is a reasonable capability an attacker might have. The start point for the attacker is set by the SystemComponent which references the Terminal component.

#### **4.5.2. Modelling Attackers for Filtered Attack Paths**

The first attacker type is useful if the security expert has already decided on a starting point and the skill set of the attacker, for instance, with insider attacks or system breaches. However, if the security experts are interested in whether, for a certain architecture, an attack path exists and the concrete capabilities of the attacker are unknown, then our second attacker type can be used. This attacker type is initially published in Walter et al. [212].

**Figure 4.18.:** Attacker with filtered attack paths metamodel elements

The second type is cornered around attack paths and filtering of these. Figure 4.18 illustrates the metamodel elements. In contrast to the previous attacker model, the knowledge and the capabilities are not explicitly modelled. The metamodel only defines restrictions for the space of capabilities and knowledge. These restrictions are called FilterCriterion. The abstract FilterCriterion is contained by the SurfaceAttacker, representing our second attacker type. A SurfaceAttacker can have multiple or none FilterCriterions. In addition, the SurfaceAttacker defines a target for the attack paths by referencing a PCMElement. While the model allows any of the referenced architectural elements, the analysis only supports AssemblyContexts. The start points for the attack paths are determined by the analysis unless a filter explicitly selects one.

The FilterCriterions can be used to select attack paths. This selection is necessary since multiple different attack paths can lead to the targeted element. We have five concrete elements for the criterion. They are separated between criteria regarding the used vulnerabilities in the attack path with the abstract VulnerabilityFilter and criteria regarding the path in general. We will first explain the general filters and then the ones related to the vulnerabilities.

• MaximumPath: This filter sets a maximum length for an attack path. Usually, attack paths in a large system can contain multiple elements and get very huge. Therefore, also the calculation for every attack path increases. However, in some cases, experts want faster results and therefore restrict the solution space to attack paths with a maximum

path length. In other cases, experts are interested only in short paths since they are only interested in a subsystem around the targeted element. Also, related approaches, such as Polatidis et al. [148, 147], use a similar filter criterion and define it as one of their requirements.

The second type of filters is modelled around the properties of the used vulnerabilities. The common upper element is the VulnerabilityFilter. These filters are:

	- Confidentiality impact: None < Low < High
	- Integrity impact: None < Low < High
	- Availability impact: None < Low < High
	- Attack vector: Network < AdjacentNetwork < Local
	- Attack complexity: Low < High
	- Privileges: None < Low < Special
	- User interaction: None < Required

**Figure 4.19.:** Attacker instance with filters for the running example

In general, all these filters can help to reduce the solution space for identified attack paths and therefore reduce the calculation time. In addition, they can help to identify relevant attack paths. The number of architectural elements as a starting point in larger systems can be big. Therefore, the number of attack paths can be big. Security experts might not be able to identify the relevant ones. However, the filter option can help to identify the relevant ones.

An example scenario for our running example is illustrated in Figure 4.19. It describes a scenario where security experts are interested in attack paths from the Terminal to the ProductStorage without the initial knowledge about the root credentials. For this, we use a AttackerSurface with two filters. The first is the CredentialFilter for the root credential. The second is the StartFilter, which selects by using a PCMElement the Terminal. The target is set by a contained PCMElement to the ProductStorage.

## **5. Analysing Software Architectures for Potential Security Incidents**

The introduced metamodel provides security experts with the means to model access control properties, vulnerabilities, attacks and attacker and annotate them to software architectural elements. The pure modelling of these properties does not help to identify potential security incidents. However, the modelling can be used as a documentation and act as a foundation for analysing the software architecture regarding potential security incidents. This analysis can happen manually by experts, which study the modelled properties and can decide based on their knowledge and experience what incidents can arise. Hence, the results of the manual analysis depend on the knowledge of the experts. Even more in larger and more complex system architectures, it gets harder for experts to get a complete understanding of the system. In these cases an automatic analysis can help to get more complete results.

In this work, we developed three different automated security analyses based on our introduced metamodels. The first analysis is described in Section 5.1. It uses our contribution C1. The analysis forms our contribution C3 and answers our research question RQ1.2. The contributions is a scenario-based usage analysis for access control policies. Based on a usage scenario, we analyse whether service calls are possible with the current policy model or whether violations are identified.

The second analysis is an attack propagation analysis. It builds up on our contributions C1 and C2. The attack propagation analysis is our contribution C4.1. The contribution answers the research question RQ2.2 regarding the attack propagation. The analysis investigates the propagation from an attacker starting from an initial architectural element and using vulnerabilities and access control policies to compromise new architectural elements. It uses

a dedicated attacker model (c.f. Section 4.5.1) with knowledge and concrete capabilities. This analysis is described in Section 5.2.

In Section 5.3, we describe the third analysis. It calculates potential attack paths to a targeted architectural element. It uses our contributions C1 and C2. The third analysis is our contribution C4.2 and answers our research question RQ2.2 regarding the attack paths. The used attacker model (c.f. Section 4.5.2) provides different filter criteria to restrict the design space of the attacker.

### **5.1. Scenario-Based Access Usage Analysis**

This section introduces our scenarios-based access usage analysis, which is built up on our contribution C1. The analysis is our contribution C3 and answers our research question RQ1.2. This analysis is built up on our publication Walter et al. [214].

Understanding the impact of access control policies is complicated. The access in context-based access control policies like in our ABAC-based access control metamodel can depend on various different attributes, which change dynamically. For instance, in our running example the access to the scenarios depends on the dynamically changing state of the machine. Understanding the access decision and potential impact is getting in larger systems even more complicated, where service calls are often delegated between different components and involve different services or users. One approach to estimate the impact is by analysing the intended usage in different scenarios and identifying potential access violations. Similar approaches are performed by Seifermann et al. [168] for data flow analysis and Boltz et al. [32] for handling uncertainty in an access control data flow analysis. Verma et al. [204] call similar approaches experimental validation. In our work, we use a similar approach using different scenarios with system calls and access control policies. These scenarios represent the intended usage or misusage of the system by users. We developed a scenario-based access usage analysis, which investigates whether the intended usage or misusage represented by the scenarios is possible with the current access control policies. For realising this, we extended the scenarios with context information (c.f. Section 4.2.4) and our developed analysis investigates for each modelled service in a scenario whether it is possible or not with the current context of the scenario. The analysis determines the result based on the specified access control policies. The result is a list of potential access violations and can help to identify potential security incidents.

### **5.1.1. Process for Analysing Scenario-based Access Control Policies**

Our RQ1.2 investigates how we can identify whether certain scenarios are possible with the given software architecture and access control policies or not. Because of the focus on scenarios and access control policies, we decided to develop a scenario-based access analysis.

The main concept of the scenario-based access analysis is to analyse whether different usage scenarios are possible with the modelled access control policies. In PCM, the usage is modelled in the usage model with different UsageScenarios. PCM defines, that the UsageScenarios are modelled by the Domain Expert [154, p. 24]. The Domain Expert has knowledge about the intended use cases and how users use or intend to use a system. In our extension, we will keep this role. The other roles defined by PCM, such as the Component Developer or Software Architect, are summarized in our process as the role Software Architect. As previously described, we assume that the Software Architects cover the modelling of the software architecture. The different roles are important for the general design of the software architecture. However, for the explanation of our process, they are not that important. As introduced in the motivation, we also define the new role Security Expert to the predefined PCM roles. The Security Expert has knowledge about the specification of access control policies and about requirements for confidentiality. Similar approaches, such as the data flow analysis by Seifermann [166] or the process for alignment of access control roles by Pilipchuk [143], also define the role of security experts, who models security-related properties in PCM. Similar to the related approaches, our role is responsible for the access control properties and the definition of attributes. In contrast to the other approaches, the role also helps in the definition of misusage scenarios.

Figure 5.1 illustrates our intended process for a new software project (greenfield development). The process syntax is based on an extended UML activity diagram syntax. We have the three described roles Security Expert, Software Architect, and Domain Expert, each indicated by its respective icon. For each activity (boxes with round corners), we assign the involved

**Figure 5.1.:** Process for using the access usage in a new system. Icon Source: Font Awesome by Dave Gandy — http://fontawesome.io

roles by putting their icon on it. The involved artefacts are the generated models (boxes with sharp corners).

The process starts by defining the initial software architecture through the Software Architects. They define the components, system, deployment and hardware resources. They can model these manually or if artefacts already exist, use existing reengineering approaches, such as SoMoX [25], Monschein et al. [119], or Kirschner [93].

Afterwards, all roles are involved in the creation of the attribute model. This is performed by all three roles since it requires knowledge from each role. The attribute model covers the different user roles. These depend on the role model from the Security Expert, but they need the knowledge from the Domain Expert, who knows which users will use the system and what properties they have. In addition, the attribute model will involve properties emitted from different components, such as the machine state in our running example. This system knowledge stems from the Software Architects. Hence, they are involved. The attribute model and the software architecture are then used by the Security Expert to create the access control policies.

The Domain Experts define based on the software architecture and the attributes the different usage scenarios. They use the software architecture to identify the service calls used by a user and the attribute model to describe the context during a scenario. The context can be a user's role or a machine state.

**Figure 5.2.:** UsageScenario for the running example with the technician accessing the log data of the machine during a failure state

Figure 5.2 illustrates a modelled usage scenario based on our running example. PCM follows here the syntax of UML activity diagrams. A UsageScenario contains a start and end point. Between them, different activities are performed. In our case, it is a call to the access service of the system. In PCM, these system calls are specified by the EntryLevelSystemCall. A usage scenario is not limited to one EntryLevelSystemCall like in our example but can contain multiple ones to different services of the system. The context for the scenario is set by the attributes for the whole scenario as illustrated by the comment (box connected with the dashed line) in Figure 5.2. In the figure, we use the comment box only as a simplified representation. In the approach, the context is a dedicated model element (c.f. Section 4.2.4). The modelled scenario in Figure 5.2 illustrates a context where the requestor has the role technician and the machine is in a failure state.

Besides the scenarios, which model the intended usage of a system, our access analysis also supports misusage scenarios. Similar to the concept of misuse cases [177] and mal-activity diagrams [176], they model usage scenarios, which should be prohibited. The idea is that the modelled policies are not only evaluated against the intended usage but also evaluated whether they can prohibit misusage. For instance, a misusage scenario in our running example can be that the service technician tries to access the machine without

**Figure 5.3.:** MisusageScenario for the running example with the technician accessing the log data of the machine

a failure state. Figure 5.3 illustrates this scenario. In contrast to the previous scenario, the machine state is missing and the annotation Misusage is added. The annotation is represented by a UML comment (dashed lines) and marked with a stereotype declaration of «Misusage» in Figure 5.3. The usage of the comment box is only used as a simplified representation in the figure. The approach uses a dedicated model element (c.f. Section 4.2.4). The annotation marks the usage scenario as a misusage scenario. The usage and misusage scenarios are created by the Domain Expert together with the Security Expert. Both roles should be involved since the Domain Expert can provide insights about the usage and the Security Expert about identifying misusage.

The last step is the potential adaption of the system after the analysis is performed. The input for the last activity are all created models. However, we left this out for a better readability of the figure. All three roles investigate, whether the results of the analysis are sufficient. If the results are sufficient, the process ends. If not, they can adapt the models to get the desired results.

This process should not be considered a strict procedure. It should act more as a showcase and guideline on how our analysis is integrated into the component-based development process defined by PCM. For instance, some activities can also be done in parallel or each role can be further defined, like a security expert for policy design and misusage detection. It is also

possible to adapt the process in evolution processes or iterative development processes. A simple adaption could be that the definition is only an adaption or the remodelling of an existing approach.

### **5.1.2. Analysing Scenarios for Access Violations**

After the specification of the software architecture, the access control policies, the attributes and the scenarios, the access usage analysis can analyse each scenario for access violations. The analysis can detect for each scenario and each contained system call access violations.

The conceptual idea for our analysis is to analyse the service calls regarding access violations. We determine the service calls based on the usage scenarios which describe the initial service calls a user performs. Afterwards, our analysis follows the initial service calls and identifies all following service calls. For each of the following service calls, the analysis determines the current context and checks whether the context is sufficient to access the called service. In the end, the analysis has a list of services and the access decision. Based on this list, the analysis can determine whether a usage scenario is possible or not. In the following, we describe the analysis in more detail and give insights about the implementation. We slightly simplify the explanation of the implemented access usage analysis to make it easier to follow. However, we will give insights about the simplification and the complete implementation is available in our dataset [208].

The analysis is described using the metamodel elements from Chapter 4. Using the metamodel elements for the implementation allows us to reuse the same algorithm for different system instances. Instances of these metamodel elements can be mapped to sets. These sets are then representing the elements. For example, all service instances can be grouped into a set. In this section, we only define a simplified set containing only the relevant sets for the scenariobased access usage analysis. In the later section, we extend these sets for the other analysis. We define the following sets:

Based on these sets, we can define different boolean functions. Each function checks certain metamodel properties. In case the conditions are met, each function returns true otherwise false. The different parameters can be overloaded. Each function is defined first by the name, then by the parameters. Afterwards, a logical expression is following, describing the check conditions. In the following, we will first introduce the function and its definition and then will provide an optional description.

Besides the different boolean checks for the different conditions, we also need a function, which provides a set of the connected services.

$$\text{connectedServer}(\text{s}): \text{s} \in S \to \text{next} \subseteq S: \begin{cases} \text{next} \subseteq \text{S}, & \text{service \\_s calls \\_next} \\ & \text{other \\_serves} \\ \mathcal{O}, & \text{no other \\_serves is \\_s} \\ & \text{called by \\_s} \end{cases}$$

The idea of the function is that it provides a set of services which are called by the passed service parameter. The analysis requires this because services can delegate calls to other services.

Based on the defined sets and functions, we illustrate the analysis for one usage scenario in Algorithm 1. In case multiple usage scenarios should be analysed, the algorithm can be repeatable called. The algorithm expects the attributes with the set A, a usage scenario with the parameter scenario, and the services with the set S. In the case of our analysis, the usage scenario needs to be annotated as discussed in Section 4.2.4. In the end, the algorithm returns the result for the scenario, and it contained service calls, which is a tuple of the access decision and the service.

Algorithm 1 Simplified Scenario-Based Access Usage Analysis

```
1: procedure accessUsageAnalysis(,  ∈  , )
2:  ∶= ∅
3: for all  ∈  do
4:  ∶= { ∈  ∣ (,  )}
5: if  = ∅ then
6:  ∶= { ∈  ∣ (, )}
7: end if
8:  =  ∪ (   (, ), )
9:  = ( )
10: for all  ∈  do
11:  =  ∪ (, , ,)
12: end for
13: end for
14: return
15: end procedure
```
The first step in Algorithm 1 (l. 2f) is to initialise the result set. The algorithm initialises it as an empty set. Later on, the algorithm will fill it iteratively with tuples of service instances and access decisions. The next step (l. 3) is to iterate over all the services in the scenario. As described in Section 5.1.1, a scenario can contain multiple calls to services. In the case of PCM these service calls from a usage scenario are called EntryLevelSystemCalls. The next step is to identify the context for the service call. The context is the attributes assigned to the scenario or the service call in the usage scenario (c.f. Section 4.2.4). In the algorithm, we first derive in l. 4 the context set for the called service. If this set is empty, we select the context of the usage scenario. This checking for an alternative context enables us to override the general context of a usage scenario. However, the design decision of directly replacing the context if one is modelled comes with the drawback that an empty context for a service cannot override the context of a usage scenario. An alternative design decision, which use, for instance, a dedicated flag for overriding would solve this problem. We choose to use the simpler approach because it does not require additional modelling elements.

After the algorithm determined the context, it checks whether the current context has access to the selected service (l. 8). Very simplified, the function checks whether the current context is enough to access the service. Math-

ematical formulized, it checks whether ( ∩ ) = where ⊆ describing the context of the call and ⊆ describing the policy protecting the service. In the actual implementation, this decision is made by the PDP. There, we need to create a XACML request as described in Section 4.2.5 and then query the PDP. Because of the usage of XACML the access decision is in the implementation also much more complicated. In our description, we described only a basic feature. In reality, the PDP cannot perform a simple set comparison in all cases because XACML can have arbitrary comparison functions for the requested set. We refer for a more detailed explanation to our limitations (c.f. Section 7.4 — Access Control Model) and the XACML documentation [132]. After determining the access, we save the result together with the service in the result set.

Often a service calls other services. These services then again call other services. Hence, a service call in a usage scenario has something like a call stack of following service calls. This is similar to regular programming, where functions can call other functions, thereby, creating a call stack. Each of these service calls can have access control protection. Therefore, the analysis needs also to analyse the subsequent service calls for violations. We realise this analysis of the subsequent service calls by first identifying the directly called services. Afterwards, we iterate over the called services and call for each one the analyseService. Then, we add the return to the result set and return it in the end.

#### Algorithm 2 Simplified Analysis of Service Calls

```
1: procedure analyseService( ∈ ,  ∈ ,  ⊆ ,)
2:  ∶= { ∈  ∣ (, , )}
3: if  ≠ ∅ then
4:  ∶=
5: end if
6:  =  ∪ (   (, ), )
7:  = ()
8: for all  ∈  do
9:  =  ∪ (, , ,)
10: end for
11: return
12: end procedure
```
The analyseService is described in Algorithm 2. The parameters are the current service to analyse represented by s, the calling service represented by the parameter predecessor, the current context, which consists of attributes represented by the parameter context, and the set of all attributes represented by A. The first step in the function is to determine the context for the service call. The context can be either the same context as the predecessor or it is overridden by AttributeProviders (c.f. Section 4.2.4). For determining the context, we need to consider the current service and the predecessor service because, based on our modelling, the context is defined on the relation between the two services. In the case a new context is available for the service, we set the new context () as the context. The rest of the function is similar to the Algorithm 1 for the service calls from a usage scenario. We check whether the context grants access to the selected service and save the outcome in the result set. Then, we identify possible called services and recursively analyse these services.

In the end, Algorithm 1 and Algorithm 2 have recursively analysed all the service calls within a usage analysis and return the result set. The set contains the access decision for each service calls.

After obtaining the result for a usage scenario, we iterate over the result and check whether all contained service calls' results are possible. If this is the case, we mark the scenario as passed and continue with the next scenario. This process is repeated until no more scenarios exist. In the end, the analysis determined for each scenario, whether it is passed or not.

Remark: For simplicity reasons, we assumed during the explanation that the access decision true is the case when access is possible and false is the case when access is denied. The actual implementation by the PDP uses a more fine-grained result (c.f. Section 4.2.5). In the implementation, Permit represents the boolean true value from our description and all the other possible results are false.

#### **5.1.3. Analysing Misusage Scenarios for Access Violations**

The misusage scenarios are the scenarios containing the unwanted usage of the system. Due to our modelling decision to reuse the existing scenarios for the misusage, we can reuse most of the aspects from the scenario-based access usage analysis. The main modelling difference is that we annotate

**Figure 5.4.:** Result metamodel for the access usage analysis

a usage scenario with Missusage (c.f. Section 4.2.4). The meaning is that the scenario should not be possible. We define a scenario as impossible if it contains at least one service call which is denied.

**ServiceSpecification** This comes with the drawback that we cannot explicitly check whether certain service calls are impossible. The analysis always determines the pass decision for the full scenario. However, this problem can be circumvented by using smaller scenarios where the number of called services is smaller. Despite this drawback, the benefit is that from the technical side, we can reuse the previously described scenario-based access analysis (c.f. Section 5.1.2). For each marked misusage scenario, the analysis performs Algorithm 1. Afterwards, the analysis also iterates over the result. In contrast to the non-misusage scenario, we mark the scenario only as passed if at least one access result is false (meaning Deny in the implementation). Otherwise, the scenario is marked as not passed. This way, it stores the same result as for the other scenarios, and we can reuse most parts of the analysis.

#### **5.1.4. Result Model for the Access Usage Analysis**

In this section, we describe the result model for the access usage analysis. The result model is the output of the analysis. It can be used in the adaption step of our process to decide whether the system is satisfying or not. We choose to define the result models also by a metamodel.

Figure 5.4 illustrates the metamodel for the analysis results. The root container element is the AnalysisResult. It contains for each usage and misusage scenario a ScenarioOutput. As attributes, it has a reference to the Usage-Scenario in PCM it represents, a boolean flag indicating whether it is a misusage scenario or not, and a boolean flag indicating whether the scenario is passed or not. It is a misusage scenario if the misusage attribute is true. Otherwise, it is a usage scenario. The scenario is passed, when the passed attribute is true.

Each ScenarioOutput contains a list of OperationOutputs. These are the different access decision results for the called services in a scenario. It is based on the result from Algorithm 1. Each OperationOutput has a string list with policy IDs and the decision of the PDP is stored in decision. The datatype is the same as the result model for the PDP decision (c.f. Section 4.2.5 and Figure 4.10). Besides these elements, it contains an optional ServiceSpecification to represent the called system services. The access decision for the EntryLevelSystemCall is encapsulated by the references to various PCM elements. These are an OperationSignature, a list of AssemblyContext, a Connector and an ExternalCallAction. These are necessary to identify the actual called service on the instance level and not on the type level as in the EntryLevelSystemCall.

Figure 5.5 illustrates the result model for our running example. It shows an excerpt of our tooling with the available editors. The upper half shows an EMF tree editor for a result model. We see the different ScenarioOutputs and whether they are passed (indicated by true). The first ScenarioOutput is the scenario where the service technician accesses the machine during a failure state. This further information can be found in the lower half of Figure 5.5 in the Property View (indicated with the text Properties). Each ScenarioOutput contains then the OperationOutput with the access decision. In the first case, it is Permit. The software architect, security expert or domain expert can then use this result model. They can click on the different elements and see more detailed information from the metamodel. This can help them to decide whether the architecture, together with the access control policies, is suitable for the intended usage or not. If they decide it is not useful, the information provided by the result model could be a first starting point for changes.

#### 5. Analysing Software Architectures for Potential Security Incidents

**Figure 5.5.:** Analysis result model for the running example

## **5.2. Attack Propagation Analysis**

In this section, we introduce our attack propagation analysis. It builds up on our contributions C1 and C2. The analysis is our contribution C4.1 and covers the first part of the research question RQ2.2. The other part is answered by C4.2. We originally published the analysis in Walter et al. [211] and extended or used it in other publications [209, 213, 94].

Our second type of analysis is settled around an attack propagation based on the software architecture. The access analysis (C3) works well for scenarios where only access control properties are relevant. It can consider malicious users with the misusage scenarios, but the analysis is limited to the intended control flow of services. More complex scenarios, which do not work along the control flow of the system, cannot be modelled and analysed. For instance, in our running example, an attacker tries to propagate from the Terminal directly to the StorageServer. In doing so, the attacker would not follow the different service calls in the system. In this dependence on the intended control flow, the attacker behaviour in C3 is similar to an honest-but-curious or semi-honest attacker behaviour [139] in protocol design, meaning that attackers cannot deviate from the original protocol. Here, the intended control flow can be seen as a protocol. To support this deviation from the control flow, we need another type of analysis, which can propagate along other structural properties.

Another aspect not considered in the access analysis is the impact of vulnerabilities and their interplay with access control policies. A software system can contain multiple vulnerabilities which attackers may exploit. However, often it is unclear whether attackers can actually exploit them. For instance, a vulnerability might not be reachable for an attack or the attacker needs certain privileges to exploit them. In addition, it is often unclear what the impact on the overall system is. It might be that an attacker can only compromise non-essential parts of the system or very confidential data is affected. For instance, in our running example, the ProductStorage is considered very critical compared to the other components. In other words, compromising the ProductStorage is worse than the compromisation of the other components. Therefore, compromising it has a more significant impact than compromising another component. Another aspect of the impact is whether a vulnerability enables the easier propagation of an attacker, either by exploiting another vulnerability or by providing credentials for architectural elements.

We will first explain in Section 5.2.1 the process for using our attack propagation analysis. Afterwards, we explain the analysis process in Section 5.2.2. The difference between the two sections is that the first describes the analysis from a user view, and the second describes the internal steps the analysis needs to perform to analyse a system. We describe how we identify the affected data in Section 5.2.3. This concept of the extraction is then used in our attack propagation. The concept and the algorithm of the attack propagation is introduced in Section 5.2.4. The analysis creates a dedicated result model,

**Figure 5.6.:** Process for using the attack propagation in a new system. Icon Source: Font Awesome by Dave Gandy — http://fontawesome.io

which is based on a result metamodel we developed. We introduce this result metamodel in Section 5.2.5.

### **5.2.1. Process for Analysing Attack Propagations with the Software Architecture**

Similar to the access usage analysis, we describe an exemplary process for using the attack propagation analysis. The process is illustrated in Figure 5.6. The attack propagation does not use the usage models, which are created by the Domain Expert. Hence, in this process Domain Experts are not necessary. Nevertheless, for other PCM analyses, they are required. We kept the role of Software Architect the same but modified the Security Expert's responsibilities. In this analysis, the role is also responsible for vulnerabilities, in addition to the definition of access control properties. This further differentiates the role Security Expert from similar roles in related PCM-based security analyses.

The first three steps in the process are identical to the process from the access usage analysis. This is beneficial since the different models can be reused between the different analyses. This can reduce the modelling effort since only one Architectural Model, Attribute Model and Access Control Policy Model for both analyses needs to be modelled.

The fourth step is to create the vulnerability model based on the proposed metamodel (c.f. Section 4.3.3) by the Security Expert. This process can be manual or semi-automated. For the manual part, Security Experts can use existing databases or use their experience to model them. For the semiautomated part, they can use our developed approach in Kirschner et al. [94] (c.f. Section 4.3.5).

The next step is the creation of the attacker model by the Security Expert. Here, the security expert can define the attack and the propagation attacker based on our metamodels elements for attacks (c.f. Section 4.4.2) and the propagation attacker (c.f. Section 4.5).

The last step is the system adaptation based on the analysis results. The analysis evaluates the architecture and identifies affected architectural elements from an attack propagation. Based on these results, the Security Expert and Software Architect can change the created models to mitigate certain attacks. By mitigating attacks, they can reduce the potential set of affected architectural elements. Mitigation tactics are, for instance, stricter access control policies, exchanging vulnerable architectural elements with non-vulnerable ones or introducing mitigation approaches for certain vulnerabilities, such as using a Firewall to limit the access to the elements. They can also decide that the results are sufficient for the system. For instance, such cases are if either no attack propagation is possible or the system can only be compromised by very rare and costly attack types.

The resulting attack paths are specific to the given architecture. However, the approach and some models can be reused for other component-based architectures. We elaborate on the potential reuse in the evaluation (c.f. Section 7.2.4). Similar to the process of the access usage, this process should act as a guideline and does not need to be followed strictly. For instance, some steps could be done in parallel or performed by multiple persons with the same role. Examples of this additional separation could be using dedicated security experts for access control policies and vulnerabilities.

#### **5.2.2. Attack Propagation Process**

The actual analysis process is then straightforward. We illustrate it in Figure 5.7. The process is split into different steps, which process the data. This happens similarly to the workflow definition of other PCM analyses. The first step is to load the different models. Here, we can reuse already existing PCM workflow actions.

Afterwards, we roll out the vulnerabilities to the instance level. Our metamodel allows the annotation of BasicCompoents and AssemblyContexts. The first is an annotation on the type level. However, the analysis requires the vulnerabilities on the instance level. We needed the type-level integration for the automatic derivation of vulnerabilities (c.f. Section 4.3.5). The handling of the type levels can be realized by extending the vulnerability look-up in the analysis itself. This would require an additional vulnerability check that additionally checks the BasicComponent for vulnerabilities. In our case, we decided against it, because it requires code changes within the analysis and negatively affects the runtime for the analysis itself. Therefore, we provided a new roll-out phase in our analysis workflow. This step annotates all the AssemblyContexts with a vulnerable BasicComponent with the vulnerabilities of the BasicComponent. This provides the analysis with the vulnerable Basic-Components without modifying the internal analysis behaviour. A drawback is that during the analysis, it is unclear whether vulnerability originates from a BasicComponent or the AssemblyContext. However, this information can be manually deduced by checking whether the corresponding BasicComponent of an AssemblyContext is vulnerable with the same vulnerability.

After the roll-out of the vulnerabilities from the BasicComponents to the AssemblyContexts, we transform the access control model into XACML policies (c.f. Section 4.2.5) and load these into our PDP. Afterwards, we execute the attack propagation analysis. The last step is to save the result model. Here, the user can choose between an EMF-based output and an additional graph representation.

#### **5.2.3. Data Extraction**

Besides the identification of affected architectural elements, also the identification of potentially stolen information is relevant for estimating the impact of attacks. This is especially relevant for considering the confidentiality because if attackers get access to data, it can be a confidentiality issue. For instance, if the stolen data contains sensitive information such as credit card data or other personal data, the confidentiality can be violated. Examples of attacks with stolen credit card data are, for instance, the attack on HomeDepot<sup>1</sup> or Target<sup>2</sup> . However, also other data can be considered confidential, such as in our running example, the data managed by the ProductStorage. In our case, information consists of different aspects, such as information about the software architecture or the managed data in an architecture. In this section, we focus on the last aspect, the managed data.

The managed data is usually described in PCM as parameters and return values of services. Other approaches, such as Werle et al. [217] or Seifermann [166], extended the data capabilities of PCM with more data-specific operations. However, as their foundation, they still use the parameters and return values of operations. Hence, we choose in this work also to use this datamodel. The benefit is that we use an established modelling technique in PCM. In addition, it eases the reuse of existing architectural models. The drawback is that we are limited to services for the data extraction. Hence, data is only indirectly modelled for components or hardware devices since components provide services and components are deployed on hardware resources. Even more, network resources have no data at all. In contrast, in reality, network elements like switches or routers can have some minimal data and even more they could see exchanged data over the network. However, this might not be too critical since it can be assumed that most of the critical data is stored or processed in services. In addition, some of the additional data, which can have an influence on the confidentiality or be beneficial for the attackers, are separately modelled. For instance, credentials are modelled

<sup>1</sup> J. Finkle et al. Home Depot breach bigger than Target at 56 million cards. Sept. 18, 2014. url: https://www.reuters.com/article/us-home-depot-dataprotection-idUSKBN0HD2J420140 918 (visited on 06/06/2023).

<sup>2</sup> B. Krebs. Inside Target Corp., Days After 2013 Breach. Sept. 21, 2015. url: https://kreb sonsecurity.com/2015/09/inside- target- corp- days- after- 2013- breach/ (visited on 09/01/2021).

by the AttributeProviders. These can also be assigned to network elements, hardware resources or components.

Our analysis assumes that an attacker has complete control of the data if they either compromise an architectural element or exploit a vulnerability with a Medium or High confidentiality impact. If this is the case for a service, we extract the data by using the parameters with which it is called and the return values of external calls for service calls. For an affected component, we calculate it for every service provided by the component and for an affected resource container, we calculate it for each component deployed on it.

The extracted data can be used to estimate the criticality of an attack propagation. For instance in Walter et al. [209], we combined the extracted data with a data flow analysis to estimate the criticality of the affected data. There, our attack propagation provided the affected data, and the data flow analysis provided an estimation of criticality for each data object.

### **5.2.4. Analysing Attack Propagations**

The core of the attack propagation analysis is the propagation algorithm. It illustrates how attackers could propagate through a system by performing attacks on vulnerabilities and exploiting access control properties. The propagation concept is built up on the KAMP approach [36]. KAMP has been already successfully used together with the PCM [155, 156]. As previously described, the core idea in KAMP is to propagate change requests by defined propagation rules over the structural elements of a software architecture (c.f. Section 2.1.3). The approach focuses on change propagations during maintenance tasks and not like our work on attack propagation. Nevertheless, we assume that the basic propagation concept is similar to our approach because the propagation in KAMP follows along the structural connection of the software architecture. It creates iteratively the transitive closure of the affected elements. This iterative process is repeated till no new elements are affected by the propagation. The same behaviour can be observed by attacks, which follow along the connected architectural elements. Instances for such connections are the deployment relationship between hardware devices and components or the network connections between hardware devices. As previously described, the attacker also propagates the attacks until no new element is affected, meaning no new element is compromised. However, our

attack propagations approach differs in the following aspect from the existing KAMP approach:

The first difference is based on the maintenance focus in KAMP. The existing propagation rules do not consider the possible propagation on component instances. They are written for the type level of components, such as BasicComponents. In contrast, in our work, we need to consider the propagation on the instance level because, in our case, an attacker compromises the instances of the components. Therefore, we also annotate our vulnerabilities mainly on the AssemblyContexts which represent instances of components. Therefore, we needed to define new propagation types and propagation rules. Nevertheless, there can be cases where the propagation of attackers on types is useful, such as in supply chain attacks where attackers compromise the type itself. However, these attacks and propagations are out of the scope for our thesis.

The second difference is the usage of dynamic conditions in the propagation rules. In our propagation, we have dynamic properties, such as the knowledge of the attackers or the roles of compromised elements which change during a propagation. However, these dynamic changing properties can affect the result and need to be considered in the propagation rules. For instance, attackers can gain new knowledge about an attribute. This can enable the attackers to compromise a previously uncompromisable element. Therefore, our propagation rules need to consider these dynamic attributes in the propagation.

Because of these two differences, we cannot reuse the existing propagation rules and need to adapt the propagation framework. Our adaptation consists of the newly added propagation types for attacks and new propagation rules. In addition, we slightly adjusted the workflow to include our metamodels. Overall, we defined 19 new propagation rules considering the different propagation mechanisms of attackers. We explain these rules later in more detail during the explanation of the attack propagation (c.f. Algorithm 3 and Algorithm 4).

In the following, we describe a slightly simplified version of the implemented attack propagation, which is easier to follow. The main difference to the actual implementation is the gained attributes. We will describe the difference in the

part about gained aspects in more detail. Similar like the previous scenariobased access usage analysis, the attack propagation is described using the metamodel elements from Chapter 4. As previously mentioned using the metamodel elements for the algorithm allows us to reuse the same attack propagation algorithm for different system instances. As in Section 5.1.2, we map instances of these metamodel elements to sets. These sets are then representing the elements. For instance, all AssemblyContexts elements are a set. In this section, we extend the previously in Section 5.1.2 defined sets. We add only the set necessary for our attack propagation. We add the following sets:

Like in Section 5.1.2, we define different boolean functions based on these sets. We also reuse the introduced functions from Section 5.1.2. Each function checks certain metamodel properties. In case the conditions are met, each function returns true otherwise false. The different parameters can be overloaded. Each function is defined first by the name, then by the parameters. Afterwards, a logical expression is following, describing the check conditions. In the following, we will first introduce the function and its definition and then will provide an optional description.

Checks whether the component is connected to the component by checking whether both components are in the same network. This can be done by using the LinkingResources and checking whether both components are not marked with NonGlobalCommunication (c.f. Section 4.3.4).

• 2(,) ∶= , ∈ ∧ ( connected by Assembly-Connector with ∨ 2(,)) Checks whether two components are connected. Components are connected, if there is a AssemblyConnector between them or they are globally connected over a LinkingResource.

Besides the different boolean checks for the different conditions, we also need a function to map two architectural elements to an AttackVector. We define it as the function . It takes two architectural elements () and returns the AttackVector ( ). The AttackVector is Local if the two elements are in a deployment relationship, e.g., is deployed on or vice versa. If both elements are in the same network, meaning they are connected with the same LinkingResource (c.f. and Section 4.3.3), it returns AdjacentNetwork. Otherwise, the value is Network.

$$Aut(\mathfrak{x}, y): AE \times AE \to ATV := \begin{cases} Local, & \text{deployment.}\\ AdjacentNetwork, & \text{in the same network.}\\ Network, & \text{otherwise.} \end{cases}$$

The attack propagation algorithm is then described in Algorithm 3 and Algorithm 4. For space reasons, we needed to split the algorithm into two parts. The main concept for the attack propagation is that it iteratively calculates the transitive closure of the directly attacked and indirectly attacked architectural elements. In addition, an attacker can gain new knowledge regarding the credentials (here attributes) in each iteration. The algorithm's termination condition is that no changes occur in the current iteration. This behaviour is based on KAMP. Hence, the structure was partly given by the foundational approach.

Besides the software architecture annotated with vulnerabilities and access control policies the input for Algorithm 3 is:

through Social Engineering attacks like Phishing or other attacks, which we do not consider in the analysis itself. However, the results of these attacks can be considered as knowledge. In addition, the initial knowledge can be empty. During the analysis, attackers can gain additional knowledge.

• : A set of Attacks describing the capabilities of an attacker.

The output of the algorithm is a set of affected architectural elements ( ).

The first step in the algorithm is to assign the set to , which is the return value. Afterwards, it determines the roles of the initial compromised elements. Then the algorithm calculates iteratively the transitive closure of the compromised elements. It terminates if no new elements are affected in an iteration step, i.e., the attacker did not compromise a new element or gained no new knowledge. We determined the termination criteria by investigating which affected/compromised element can lead to potentially new propagations. In other words, compromised elements can open new attack paths for an attacker. The first criterion is affected architectural elements. An attacker can use these to reach new architectural elements which were previously not reachable. For instance, in our running example, the ProductStorage is not directly reachable from every component. However, an attacker can reach it by first compromising the StorageServer. The second criterion is the knowledge of an attacker. Adding new knowledge can also open new attack possibilities for an attacker. For instance, a non-vulnerable component can only be compromised by credentials, despite that it is reachable. However, by getting the knowledge about the credentials, an attacker could compromise it. Hence, we added this as a termination criterion. In theory, the role also would need to be termination criteria since if it changes, there could be new vulnerabilities an attacker could exploit. However, in our case, the role assignment is coupled to an architectural element, and an attacker can gain a role only by compromising an architectural element. Hence, when there is a new compromised role, there is also always a new compromised architectural element. Therefore, both compromisations happen in the same iteration step, and we can consider only the architectural element compromisation since the role compromisation is also covered.

After checking the termination criteria, the algorithm calculates the propagation steps, starting from line 5 in Algorithm 3. We calculate the propagation from each architectural element type to the other types and for each propagation type (vulnerability or credential). The separation between architectural

Algorithm 3 Simplified attack propagation algorithm 1/3 (continued in Algorithm 4)

Algorithm 4 Simplified attack propagation algorithm 2/3 (continued from Algorithm 3)

Algorithm 5 Simplified attack propagation algorithm 3/3 (continued from Algorithm 4)

element types and propagation rules is beneficial because it enables a separation of the different propagation concerns. Another possibility could be the combination of propagation rules. However, then a propagation rule would not be responsible for only one propagation step, which can violate the coding principle of Single Responsibility [107, p. 95ff]. The propagation calculation is very similar for each. In all cases, we first identify the connected elements. Afterwards, we determine whether the attack can compromise the connected elements and, therefore, propagate to the connected elements. Here, we need to differentiate between two types. We decided to separate the propagation types because the handling of the different propagation types is different for each type. Hence, the separated rules are easier to define and should also be easier to maintain. The first type is the propagation by vulnerabilities. In this propagation, the algorithm checks whether the architectural element is vulnerable, the attack vector matches to the required attack vector from the vulnerability, the required roles are already compromised, the attacker has the correct authorisation level, and the attacker has a matching attack capability. If these are all fulfilled, then the attacker can propagate to the connected element. Hence, it is compromised. The second propagation type is the propagation by using credentials, i.e., exploiting the access control policies with gained attributes. Here, the algorithm verifies whether the attacker has the suitable attributes for accessing the connected element. The different propagation sets also indicate by their name the type and the involved elements. The last character indicates whether it is a vulnerability propagation by using V or by using C if it uses credentials. The involved types are shown by using the abbreviations symbols for the involved set. The first abbreviation illustrates the source type from which the propagation happens, and the second is the target type. For instance, for the first set

 (l. 5 in Algorithm 3) it is AssemblyContext (AC) to AssemblyContext (AC) by using a Vulnerability (V).

In the following, the different propagation sets for each architectural element type and propagation type are calculated. Based on the description, we give them an order. Nevertheless, the order is changeable. By changing the order, obviously, the propagation within a loop iteration might be different. For instance, if the propagation of AssemblyContexts is handled after the LinkingResources. However, the results should stay the same because the changed compromised elements are only considered in the next step. Even if the changed compromised elements are directly considered, this is no problem because the missed propagation steps are redone during the next loop iteration.

The first propagation set (l. 5) represents the propagation between AssemblyContexts by exploiting a vulnerability. It first identifies all connected components and then whether they are vulnerable to the current properties of the attacker. The second set (l. 6) calculates the same, but uses the credentials. The third ( , l. 7) and fourth (, l. 8) are the propagation from an AssemblyContext to the ResourceContainer, which deploys the AssemblyContext by using first vulnerabilities and secondly credentials. (l. 9) and (l. 10) are the propagation from AssemblyContexts to connected ResourceContainers using vulnerabilities and credentials. These sets do not cover the deployment relationship. We separated them since they are slightly different cases for the implementation. (l. 11) and (l. 12) are the propagation from AssemblyContexts to LinkingResources. The next two sets are (l. 13) and (l. 14) representing the propagation to connected services.

The algorithm is then continued in Algorithm 4 with the sets for the propagation from LinkingResources. The first two are (l. 15) and (l. 16) propagating to AssemblyContexts. The next two sets are (l. 17) and (l. 18) representing the propagation from LinkingResources to connected ResourceContainers. The next group of sets cover the propagation from hardware resources (ResourceContainer). The first set (l. 19) is the propagation from a ResourceContainer to a local AssemblyContext. Local means in our case, that the AssemblyContext is deployed on the ResourceContainer. In this case, we assume that the deployed AssemblyContexts are always compromised. The next propagation is the propagation to remote AssemblyContexts. These are AssemblyContexts not deployed on

the ResourceContainers. This propagation is done by (l. 20) and (l. 21). (l. 22) and (l. 23) are the propagations from ResourceContainers to LinkingResources. The set (l. 24) is the union of all propagation sets, which result in AssemblyContexts. The algorithm uses this set to calculate the propagation set for the services. These are the services from all affected AssemblyContexts.

Afterwards, the overall propagation sets for this iteration step are calculated. The next step is to determine the new set (l. 26). This set should contain, in the end, only newly affected elements so that we can use it as one of the termination conditions. If it also contains old elements, the algorithm does not terminate. Then we build the union of the new compromised elements and the old elements and assign it to the return value. In the next step, we update the attacker's knowledge and store the new knowledge in (l. 28). This set also contains only newly compromised attributes, which we archive by removing already-known attributes from the set. The algorithm updates the knowledge by identifying for the compromised architectural elements, which grant attributes. For simplicity reasons, we left out the second part of the knowledge update. In our implementation, we also store the traces for each compromisation, i.e., the source, the used attack and the used vulnerability or attributes. Based on this trace, we can also exploit in the implementation the gainedAttribute attribute from a Vulnerability. Hence, the result is more detailed. The last step is updating the compromised roles in the system. Here, the algorithm determines for each newly compromised element whether it acts as a role or not. Determining these sets is repeated till the termination criteria are fulfilled. In that case, the set is returned, which contains the affected/compromised elements.

Based on the returned affected elements, we then can extract the affected data as described in Section 5.2.3.

We are now applying this concept to our running example. As a starting point, we select the Terminal and give the attacker the capability to perform attacks based on CWE-312 [114]. As knowledge, we select no initial knowledge about credentials. In Figure 5.8, we exemplary illustrate the propagation process as a graph. The nodes with only a label represent the compromised architectural elements. Nodes starting with Role: indicate attributes. The nodes with a component name and a method name indicate a server. For instance, Terminal: access is the access service from the Terminal. The other nodes containing a datatype are the extracted dataobjects, i.e., the

parameter and return values from the services. The edges contain the reason for the compromisation. This is either the used vulnerability, attribute or using one of our assumptions (indicated by implicit). If we now perform our attack propagation, the first affected element is the Terminal as the start point. Afterwards, the analysis checks each connected element for vulnerabilities or if we can use credentials. In the example, the only vulnerable connected element is the TerminalServer, and the attacker has so far no credentials they can use. The vulnerability of the TerminalServer is as previously described CVE-2021-28374 [129] and can leak the admin credentials. Also, our attacker has the capability CWE-312 [114], which is the correct capability to exploit the vulnerability. In addition, the analysis checks whether the attack vector is compatible. In this case, it is since the required one is Network (based on the CVSS) and the attacker has also Network. The next step is to check whether authorization is necessary or not. Based on the CVSS description, no authorization is necessary. Hence our attacker can fulfil this requirement. The last step is to verify whether a specific system role is necessary to exploit the vulnerability. In our case, we modelled it without that requirement since also the description does not mention it. In summary, the attacker fulfils all the necessary properties and can exploit the vulnerability. Since the vulnerability also leaks the Admin attribute, the attacker gains the knowledge of the Admin attribute.

In the next step, the analysis then checks all connected elements to the TerminalServer and Terminal. In this case, there are no new vulnerable elements available. However, with the knowledge gained from the previous step, the attack can get access to the StorageServer and MachineController. Other elements are not affected, and also no new knowledge is gained in this step.

In the next step, then the attack can propagate to the AssemblyContexts deployed on the StorageServer and MachineController resulting in the compromisation of the ProductStorage, ProductionDataStorage, Machine. Additionally, all the services provided by these components are compromised. Otherwise, no new elements are compromised or knowledge is gained.

In the next and last step, the analysis checks whether it can compromise any new elements or gain new knowledge. However, there are no new compromisations or knowledge, so the propagation terminates. Afterwards, the analysis also extracts the compromised data.

Terminal

**Figure 5.8.:**

Resulting attack propagation

 graph for the running example with the starting point

**Figure 5.9.:** Result and seed metamodel elements for the attack propagation analysis

### **5.2.5. Result Model for Attack Propagation**

Based on the attack propagation analysis, software architects can have two result models. The first and mandatory result is a EMF-based model, which contains similar to a list of all affected elements. The second optional result is a graph like Figure 5.8.

**Modifications** The result metamodel is based on the Modification Mark metamodel from KAMP [36]. An excerpt of our metamodel is illustrated in Figure 5.9. The root element is the KAMP4AttackModificationRepository. It contains the start configuration (called seed in KAMP) and the result of a propagation. The seed is modelled with the KAMP4AttackSeedModifications. It contains a AttackerSelection, which references a Attacker. By selecting this as a seed, we configure the input for the attack propagation analysis since the Attacker contains the start point, the capabilities and the knowledge of an attacker (c.f. Section 4.5.1).

The result of the analysis is modelled with a CredentialChanged. It contains the child classes of the abstract element ModifyEntity, which represents a changed element in the original KAMP approach and a compromised element

in our approach. It has a boolean flag toolDerived indicating whether the element is derived from the analysis or not. For instance, the starting points are, in our case, not toolDerived. The affectedElement is the element which is compromised. In the figure, we choose to represent it as Entity. In the actual metamodel, this is bound to the concrete subclasses by EMF Generics. The last attribute is the causingElement. This is a list of EObject and contains the reason for the compromisation. This allows an architect to trace the compromisation back to a concrete reason. It contains the original component and the reason for the compromisation, i.e. the vulnerability or the used credentials.

The subclasses contain the reference to the architectural model elements. Each represents some elements an attacker compromised or the attacker itself. There are the six subclasses for compromised elements:

The DatamodelAttacker encapsulates the extracted data for the result metamodel. It contains the referenceName, which is the parameter name, and the dataType, which uses the defined PCM datatypes. These types are BOOL, BYTE, CHAR, DOUBLE, INT, LONG, STRING, CollectionDataType for collections/arrays, and CompositeDataType for custom data elements consisting of the other elements. The source element shows from where the element was compromised and method describes the service to which the parameter or return value belongs. The context attribute describes the involved components.

Figure 5.10 shows an instance of the result model in our developed tooling. The result model is for our running example. The tree editor (upper half of the figure) contains under the CredentialChange the list of compromised elements. The excerpt contains CompromisedResource elements, CompromisedAssembly elements and a ContextChange. The selected element is the CompromisedResource for the StorageServer. A software architect or security expert can see the details in the Properties views (lower half of the

#### 5. Analysing Software Architectures for Potential Security Incidents

**Figure 5.10.:** Attack propagation result example for the running example in Eclipse

figure). First, it shows the affected element, in this case, the StorageServer. It shows the reason (causing elements). In this case, the attack originates from the TerminalServer and uses the Admin credential. In addition, a software architect or security expert can see the ID of the element and that the analysis created the element (Toolderived).

The second optionally result model is the graph presentation as shown in Figure 5.8. While the first model can show detailed information regarding the compromised elements, it is quite hard to understand the connection between compromised elements. The second model makes this easier with its graph representation. However, the graph is only a graphical representation without connections to the models. We create it by transforming each compromised element into two nodes connected with an edge. The first node is the source, the second node is the affected element, and the edge is named after the reason for the compromisation. Afterwards, we export these as a dot file, and Graphviz<sup>3</sup> connects the different edges and prints it. The graphical representation then helps to understand the connections between the attacks and compromised elements.

<sup>3</sup> Graphviz. url: https://graphviz.org/ (visited on 02/07/2023).

Software architects or security experts can then use the results to secure the system. For instance, in our running example, they can mitigate the attack by updating the Terminal to a non-vulnerable version. However, sometimes they cannot update the system, for instance, because of incompatibilities in the new version or if the Terminal is a legacy system which is already out of support. In these cases, a solution could be to change the access control policies for the other devices, so they require different attributes than the Terminal provides. Another possibility could be if they want to protect only the ProductStorage to deploy it to another more secured network and server. Overall, these are only some of the possible solutions. While our approach does not provide these solutions, it can help software architects or security experts to come to these solutions by showing the potential propagation of attackers through the system.

## **5.3. Targeted Attack Graph Analysis**

In this section, we describe the attack graph analysis and attack path identification. The analysis uses our contributions C1 and C2. It is our contribution C4.2 and answers together with C4.1 our research question RQ2.2. We originally published the analysis in Walter et al. [212].

Our third type of analysis is an attack graph analysis. It creates an attack graph and can identify potential attack paths. In the previous attack analysis, we focussed on the propagation of attackers with concrete capabilities and knowledge. The result of the previous analysis is a concrete attack propagation graph. However, in some cases the concrete capabilities of attackers are unknown, or it is not relevant which elements an attacker can compromise, but rather whether there is an attack path to a concrete element. For instance, in our running example, a security expert might not be interested that the Machine is attacked, but more interested in whether the highly confidential ProductStorage can be attacked. In these cases, security experts or software architects can use our third analysis.

We will first explain in Section 5.3.1 the process of using this analysis and then in Section 5.3.2 the technical process. Afterwards, we explain in Section 5.3.3 the attack graph creation. This graph is then used to identify attack paths, as described in Section 5.3.4. In the end, we describe the result model of the analysis.

**Figure 5.11.:** Process for analysing attack graphs

#### **5.3.1. Process for Analysing Attack Graphs based on the Software Architecture**

Similar to the access usage analysis and attack propagation analysis, we describe an exemplary process for using the attack graph analysis. The process is illustrated in Figure 5.11. The process has the same roles as the attack propagation process (c.f. Section 5.2.1) and nearly the same steps.

The process also starts with the definition of the software architecture by software architects. Afterwards, the security experts define, based on the input from the software architects, the used attributes. The software architect is necessary because they know which attributes are available in the system due to the used components. These attributes are then used by the security experts in the specification of access control policies. The security experts also define the vulnerability model. So far, the steps are identical to the attack propagation process. Here, even the models can be reused. However, the next step differs from the attack propagation. In the previous process, the security experts need to define the concrete attacks and assign them to an attacker. In this case, the security experts do not define the concrete capabilities but define filters and assign them to attackers.

In the last step, the involved roles can again adapt the system to prevent potential security incidents. Security Expert and Software Architect can

**Figure 5.12.:** Targeted Attack Graph analysis process steps

change the created models to mitigate certain attacks and break attack paths. Like in the attack propagation, mitigation tactics could be stricter access control policies, exchanging vulnerable architectural elements with nonvulnerable ones or introducing mitigation approaches for certain vulnerabilities. Besides introducing mitigation steps, they can also decide that the results are sufficient since, for instance, the involved attacks are very complicated or rare.

#### **5.3.2. Attack Graph Analysis Process**

The analysis process for the targeted attack graph is very similar to the process described for the attack propagation (c.f. Section 5.2.2). The first two steps (loading models, roll-out vulnerabilities) are identical and we reuse the same implementation. The next two parts are new. The Create Attack Graph step creates, based on the modelled software architecture, access control policies, vulnerabilities and filter criteria, an attack graph. The attack graph contains information on how attackers can compromise architectural elements. In the next step, the analysis uses the attack graph to identify attack paths leading to the targeted element. After the identification of the attack paths, the last step is to save the attack paths as the results of the analysis. For this part, we reuse existing concepts from PCM.

#### **5.3.3. Creating an Attack Graph**

The first part of our analysis is to create an attack graph based on the software architecture. The attack graph describes how attackers can compromise architectural elements. It is the foundation to determine the potential attack paths of attackers.

The graph creation is illustrated with Algorithm 6. In this part, we reuse the sets and functions defined in Section 5.2. The algorithm takes the software architecture, the vulnerabilities, the access control properties and the filter criteria and creates a multidimensional network, which is sometimes also

described as a labelled multigraph [41, p. 69]. This can be described as = (, , ) where are the vertices, the edges and is the dimension [41, p. 69]. In our case, we define:

In other words, this means that our graph consists of architectural elements as vertices. The edges are a triplet. The first two values are the vertices between the edge. The last one describes the type of edge. The graph does not allow a self-loop. In our case, attackers can only take over the next architectural element in three cases:

In order for us to describe our attack graph creation, we need to define additionally the set = {1, . . . , }, which is the set to describe the filter criteria. Besides the filter criteria set, we need these additional functions:

After defining the required sets and functions, we describe the Algorithm 6 in more detail. The input sets of the algorithm are , , , , and . The output is the graph = ( , , ) where = . In other words, it takes the architectural elements, vulnerabilities, access control policies, filters, and dimensions and calculates an attack graph.

The first step of the algorithm is to initialise and . is at the beginning empty, and is a set of all architectural elements. The next goal is to iteratively create the edges and fill with them. For this, we iterate over every architectural element and then identify for each element its neighbours (l. 5). The neighbours are all architectural elements, which are connected somehow to architectural elements. We consider them connected if one of the functions checking for a connection return true.

```
Algorithm 6 Simplified Attack Graph Creation
  Input: , , , ,
  Output  = ( , , )
1: procedure attackGraphCreation
2:  =
3:  = ∅
4: for all  ∈  do
5: ℎ = { ∈  ∣  ≠  ∧ ((, ) ∨
     (, ) ∨ 2(, ) ∨
     2(, ) ∨ 2(, ) ∨
     2(, ) ∨ 2(, ) ∨
     2(, ) ∨ (, ) ∨ -
     (, ) ∨ (, )}
6: for all  ∈ ℎ do
7: if (,) then
8:  =  ∪ {(,,)}
9: continue
10: end if
11:  = { ∈  ∣    (,)}
12: if  ≠ ∅ then
13: for all  ∈  do
14:  =  ∪ (,, )
15: end for
16: end if
17:
        ′ = { ∈  ∣ (, ) ∧
       ((,), ) ∧ (, )}
18: if  ≠ ∅ then
19: for all  ∈
               ′ do
20:  =  ∪ {(,, )}
21: end for
22: end if
23: end for
24: end for
25: end procedure
```
Afterwards, the algorithm checks whether an attacker can exploit this connection. The first check is for the deployment relationship. If the neighbour k is deployed on the current architectural element, the algorithm adds an implicit edge. For instance, in our running example, there is an edge with implicit between the MachineController and Machine. If it is a deployment relationship, the algorithm continues with the next neighbour. Otherwise, the algorithm checks whether an access control policy protects the neighbour. If the neighbour is protected, the algorithm creates an edge for each policy. The same is repeated for the vulnerabilities. There, the algorithm first determines whether the vulnerability is applicable. It also considers whether the attack vector of the vulnerability is suitable for the exploitation. Besides checking the exploitability, the algorithm also checks whether the vulnerability is filtered. This takes advantage of the VulnerabilityFilter from Section 4.5.2. For example, an ExploitFilter with a selected high complexity would produce an attack graph that includes only vulnerabilities with low attack complexity. This is useful in scenarios where the software architects only want to consider attacks with a low level of complexity, for instance, to avoid unskilled attackers. A side benefit of the filtering in the graph creation is that the created graph gets smaller. A smaller graph means a smaller problem size for the latter path finding algorithms. Hence, it speeds up the process of finding attack paths. However, a possible drawback is that the created attack graph is not general but specific to the used VulnerabilityFilters. This could reduce the usability of the attack graph and might increase the overall performance in certain scenarios. For instance, if the filter criteria vary much and the filter criteria only remove a small number of nodes. Here, a solution could be the introduction of a parameter to give system architects the option to choose when a filter should be applied. This inclusion of the filter criteria can be integrated before the filter application, and then the filter must be added to the path finding. After checking the filter and exploitability, the algorithm creates for each vulnerability an edge. This is repeated for each neighbour and for each architectural element. In the end it then returns the attack graph as = (, , ).

An example of an attack graph is given in Figure 5.13. It shows the corresponding attack graph for our running example. The nodes are the architectural elements. The edges illustrate how an attacker can compromise the connected element. Edges based on the policy are indicated by the attribute name necessary for the policy. For instance, the edge between Terminal and MachineController is labelled with Admin and means that the Admin attribute

**Figure 5.13.:** Resulting attack graph for the running example without filters

is required. The edges which exploit the CVE-2021-28374 [129] are labelled for simplicity reasons only with Vulnerability since other vulnerabilities do not exist. An exemplary edge is the edge between LocalNetwork and the TerminalServer labelled with Vulnerability. The last type of edges is labelled with implicit, indicating the exploitation of a deployment relationship. Here, an example can be the edge between the StorageServer and ProductionDataStorage.

Now to see the effects of our filtering option, we assume that the vulnerability has a High complexity, and we would filter for only Low attack complexity. This would result in the attack graph as illustrated in Figure 5.14. While in this case, it does not change the number of nodes, the number of edges is reduced. The seven edges containing the vulnerability are removed. Hence, the graph contains slightly fewer elements, which a path finding algorithm can take. This size reduction can reduce the runtime for finding an attack path.

#### **5.3.4. Identifying Attack Paths**