mal-toolbox 0.1.6__tar.gz → 0.1.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mal_toolbox-0.1.6/mal_toolbox.egg-info → mal_toolbox-0.1.8}/PKG-INFO +3 -1
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/README.md +3 -1
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8/mal_toolbox.egg-info}/PKG-INFO +3 -1
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/__init__.py +2 -2
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/model.py +103 -2
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/pyproject.toml +1 -1
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/tests/test_model.py +151 -7
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/AUTHORS +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/LICENSE +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/mal_toolbox.egg-info/SOURCES.txt +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/mal_toolbox.egg-info/dependency_links.txt +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/mal_toolbox.egg-info/requires.txt +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/mal_toolbox.egg-info/top_level.txt +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/__main__.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/attackgraph/__init__.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/attackgraph/analyzers/__init__.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/attackgraph/analyzers/apriori.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/attackgraph/attacker.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/attackgraph/attackgraph.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/attackgraph/node.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/attackgraph/query.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/default.conf +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/exceptions.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/file_utils.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/ingestors/__init__.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/ingestors/neo4j.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/language/__init__.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/language/classes_factory.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/language/compiler/__init__.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/language/compiler/mal_lexer.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/language/compiler/mal_parser.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/language/compiler/mal_visitor.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/language/languagegraph.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/translators/__init__.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/translators/securicad.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/translators/updater.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/maltoolbox/wrappers.py +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/setup.cfg +0 -0
- {mal_toolbox-0.1.6 → mal_toolbox-0.1.8}/tests/test_wrappers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mal-toolbox
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
4
4
|
Summary: A collection of tools used to create MAL models and attack graphs.
|
|
5
5
|
Author-email: Andrei Buhaiu <buhaiu@kth.se>, Giuseppe Nebbione <nebbione@kth.se>, Nikolaos Kakouros <nkak@kth.se>, Jakob Nyberg <jaknyb@kth.se>, Joakim Loxdal <loxdal@kth.se>
|
|
6
6
|
License: Apache Software License
|
|
@@ -33,6 +33,8 @@ MAL ([Meta Attack Language](https://mal-lang.org/)) models and attack graphs.
|
|
|
33
33
|
Attack graphs can be used to run simulations (see MAL Simulator) or analysis.
|
|
34
34
|
MAL Toolbox also gives the ability to view the AttackGraph/Model graphically in neo4j.
|
|
35
35
|
|
|
36
|
+
[Documentation](https://mal-lang.org/mal-toolbox/index.html)(Work in progress)
|
|
37
|
+
|
|
36
38
|
## The Language Module
|
|
37
39
|
|
|
38
40
|
The language module provides various tools to process MAL languages.
|
|
@@ -6,6 +6,8 @@ MAL ([Meta Attack Language](https://mal-lang.org/)) models and attack graphs.
|
|
|
6
6
|
Attack graphs can be used to run simulations (see MAL Simulator) or analysis.
|
|
7
7
|
MAL Toolbox also gives the ability to view the AttackGraph/Model graphically in neo4j.
|
|
8
8
|
|
|
9
|
+
[Documentation](https://mal-lang.org/mal-toolbox/index.html)(Work in progress)
|
|
10
|
+
|
|
9
11
|
## The Language Module
|
|
10
12
|
|
|
11
13
|
The language module provides various tools to process MAL languages.
|
|
@@ -99,4 +101,4 @@ To find code examples and tutorials, visit the
|
|
|
99
101
|
There are unit tests inside of ./tests.
|
|
100
102
|
Before running the tests, make sure to install the requirements in ./tests/requirements.txt with `python -m pip install -r ./tests/requirements.txt`.
|
|
101
103
|
|
|
102
|
-
To run all tests, use the `pytest` command. To run just a specific file or test function use `pytest tests/<filename>` or `pytest -k <function_name>`.
|
|
104
|
+
To run all tests, use the `pytest` command. To run just a specific file or test function use `pytest tests/<filename>` or `pytest -k <function_name>`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mal-toolbox
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
4
4
|
Summary: A collection of tools used to create MAL models and attack graphs.
|
|
5
5
|
Author-email: Andrei Buhaiu <buhaiu@kth.se>, Giuseppe Nebbione <nebbione@kth.se>, Nikolaos Kakouros <nkak@kth.se>, Jakob Nyberg <jaknyb@kth.se>, Joakim Loxdal <loxdal@kth.se>
|
|
6
6
|
License: Apache Software License
|
|
@@ -33,6 +33,8 @@ MAL ([Meta Attack Language](https://mal-lang.org/)) models and attack graphs.
|
|
|
33
33
|
Attack graphs can be used to run simulations (see MAL Simulator) or analysis.
|
|
34
34
|
MAL Toolbox also gives the ability to view the AttackGraph/Model graphically in neo4j.
|
|
35
35
|
|
|
36
|
+
[Documentation](https://mal-lang.org/mal-toolbox/index.html)(Work in progress)
|
|
37
|
+
|
|
36
38
|
## The Language Module
|
|
37
39
|
|
|
38
40
|
The language module provides various tools to process MAL languages.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# MAL Toolbox v0.1.
|
|
2
|
+
# MAL Toolbox v0.1.8
|
|
3
3
|
# Copyright 2024, Andrei Buhaiu.
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -21,7 +21,7 @@ MAL-Toolbox Framework
|
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
__title__ = 'maltoolbox'
|
|
24
|
-
__version__ = '0.1.
|
|
24
|
+
__version__ = '0.1.8'
|
|
25
25
|
__authors__ = ['Andrei Buhaiu',
|
|
26
26
|
'Giuseppe Nebbione',
|
|
27
27
|
'Nikolaos Kakouros',
|
|
@@ -28,10 +28,105 @@ logger = logging.getLogger(__name__)
|
|
|
28
28
|
|
|
29
29
|
@dataclass
|
|
30
30
|
class AttackerAttachment:
|
|
31
|
-
"""Used to attach attackers to attack step
|
|
31
|
+
"""Used to attach attackers to attack step entry points of assets"""
|
|
32
32
|
id: Optional[int] = None
|
|
33
33
|
name: Optional[str] = None
|
|
34
|
-
entry_points: list[tuple] =
|
|
34
|
+
entry_points: list[tuple[SchemaGeneratedClass, list[str]]] = \
|
|
35
|
+
field(default_factory=lambda: [])
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_entry_point_tuple(
|
|
39
|
+
self,
|
|
40
|
+
asset: SchemaGeneratedClass
|
|
41
|
+
) -> Optional[tuple[SchemaGeneratedClass, list[str]]]:
|
|
42
|
+
"""Return an entry point tuple of an AttackerAttachment matching the
|
|
43
|
+
asset provided.
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
Arguments:
|
|
47
|
+
asset - the asset to add entry point to
|
|
48
|
+
|
|
49
|
+
Return:
|
|
50
|
+
The entry point tuple containing the asset and the list of attack
|
|
51
|
+
steps if the asset has any entry points defined for this attacker
|
|
52
|
+
attachemnt.
|
|
53
|
+
None, otherwise.
|
|
54
|
+
"""
|
|
55
|
+
return next((ep_tuple for ep_tuple in self.entry_points
|
|
56
|
+
if ep_tuple[0] == asset), None)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def add_entry_point(
|
|
60
|
+
self, asset: SchemaGeneratedClass, attackstep_name: str):
|
|
61
|
+
"""Add an entry point to an AttackerAttachment
|
|
62
|
+
|
|
63
|
+
self.entry_points contain tuples, first element of each tuple
|
|
64
|
+
is an asset, second element is a list of attack step names that
|
|
65
|
+
are entry points for the attacker.
|
|
66
|
+
|
|
67
|
+
Arguments:
|
|
68
|
+
asset - the asset to add the entry point to
|
|
69
|
+
attackstep_name - the name of the attack step to add as an entry point
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
logger.debug(
|
|
73
|
+
f'Add entry point "{attackstep_name}" on asset "{asset.name}" '
|
|
74
|
+
f'to AttackerAttachment "{self.name}".'
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Get the entry point tuple for the asset if it already exists
|
|
78
|
+
entry_point_tuple = self.get_entry_point_tuple(asset)
|
|
79
|
+
|
|
80
|
+
if entry_point_tuple:
|
|
81
|
+
if attackstep_name not in entry_point_tuple[1]:
|
|
82
|
+
# If it exists and does not already have the attack step,
|
|
83
|
+
# add it
|
|
84
|
+
entry_point_tuple[1].append(attackstep_name)
|
|
85
|
+
else:
|
|
86
|
+
logger.info(
|
|
87
|
+
f'Entry point "{attackstep_name}" on asset "{asset.name}"'
|
|
88
|
+
f' already existed for AttackerAttachment "{self.name}".'
|
|
89
|
+
)
|
|
90
|
+
else:
|
|
91
|
+
# Otherwise, create the entry point tuple and the initial entry
|
|
92
|
+
# point
|
|
93
|
+
self.entry_points.append((asset, [attackstep_name]))
|
|
94
|
+
|
|
95
|
+
def remove_entry_point(
|
|
96
|
+
self, asset: SchemaGeneratedClass, attackstep_name: str):
|
|
97
|
+
"""Remove an entry point from an AttackerAttachment if it exists
|
|
98
|
+
|
|
99
|
+
Arguments:
|
|
100
|
+
asset - the asset to remove the entry point from
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
logger.debug(
|
|
104
|
+
f'Remove entry point "{attackstep_name}" on asset "{asset.name}" '
|
|
105
|
+
f'from AttackerAttachment "{self.name}".'
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Get the entry point tuple for the asset if it exists
|
|
109
|
+
entry_point_tuple = self.get_entry_point_tuple(asset)
|
|
110
|
+
|
|
111
|
+
if entry_point_tuple:
|
|
112
|
+
if attackstep_name in entry_point_tuple[1]:
|
|
113
|
+
# If it exists and not already has the attack step, add it
|
|
114
|
+
entry_point_tuple[1].remove(attackstep_name)
|
|
115
|
+
else:
|
|
116
|
+
logger.warning(
|
|
117
|
+
f'Failed to find entry point "{attackstep_name}" on '
|
|
118
|
+
f'asset "{asset.name}" for AttackerAttachment '
|
|
119
|
+
f'"{self.name}". Nothing to remove.'
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
if not entry_point_tuple[1]:
|
|
123
|
+
self.entry_points.remove(entry_point_tuple)
|
|
124
|
+
else:
|
|
125
|
+
logger.warning(
|
|
126
|
+
f'Failed to find entry points on asset "{asset.name}" '
|
|
127
|
+
f'for AttackerAttachment "{self.name}". Nothing to remove.'
|
|
128
|
+
)
|
|
129
|
+
|
|
35
130
|
|
|
36
131
|
class Model():
|
|
37
132
|
"""An implementation of a MAL language with assets and associations"""
|
|
@@ -133,6 +228,12 @@ class Model():
|
|
|
133
228
|
for association in asset.associations:
|
|
134
229
|
self.remove_asset_from_association(asset, association)
|
|
135
230
|
|
|
231
|
+
# Also remove all of the entry points
|
|
232
|
+
for attacker in self.attackers:
|
|
233
|
+
entry_point_tuple = attacker.get_entry_point_tuple(asset)
|
|
234
|
+
if entry_point_tuple:
|
|
235
|
+
attacker.entry_points.remove(entry_point_tuple)
|
|
236
|
+
|
|
136
237
|
self.assets.remove(asset)
|
|
137
238
|
|
|
138
239
|
def remove_asset_from_association(
|
|
@@ -51,6 +51,150 @@ def create_association(
|
|
|
51
51
|
|
|
52
52
|
### Tests
|
|
53
53
|
|
|
54
|
+
def test_attacker_attachment_add_entry_point(model: Model):
|
|
55
|
+
""""""
|
|
56
|
+
|
|
57
|
+
asset1 = create_application_asset(model, "Asset1")
|
|
58
|
+
asset2 = create_application_asset(model, "Asset2")
|
|
59
|
+
model.add_asset(asset1)
|
|
60
|
+
model.add_asset(asset2)
|
|
61
|
+
|
|
62
|
+
# Add attacker 1
|
|
63
|
+
attacker1 = AttackerAttachment()
|
|
64
|
+
model.add_attacker(attacker1)
|
|
65
|
+
|
|
66
|
+
attacker1.add_entry_point(asset1, 'read')
|
|
67
|
+
assert len(attacker1.entry_points) == 1
|
|
68
|
+
assert attacker1.entry_points[0][0] == asset1
|
|
69
|
+
assert attacker1.entry_points[0][1] == ['read']
|
|
70
|
+
|
|
71
|
+
attacker1.add_entry_point(asset1, 'access')
|
|
72
|
+
assert len(attacker1.entry_points) == 1
|
|
73
|
+
assert attacker1.entry_points[0][0] == asset1
|
|
74
|
+
assert attacker1.entry_points[0][1] == ['read', 'access']
|
|
75
|
+
|
|
76
|
+
# Try to add already existing entry point
|
|
77
|
+
attacker1.add_entry_point(asset1, 'access')
|
|
78
|
+
assert len(attacker1.entry_points) == 1
|
|
79
|
+
assert attacker1.entry_points[0][0] == asset1
|
|
80
|
+
assert attacker1.entry_points[0][1] == ['read', 'access']
|
|
81
|
+
|
|
82
|
+
attacker1.add_entry_point(asset2, 'access')
|
|
83
|
+
assert len(attacker1.entry_points) == 2
|
|
84
|
+
assert attacker1.entry_points[1][0] == asset2
|
|
85
|
+
assert attacker1.entry_points[1][1] == ['access']
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_attacker_attachment_remove_entry_point(model: Model):
|
|
89
|
+
""""""
|
|
90
|
+
|
|
91
|
+
asset1 = create_application_asset(model, "Asset1")
|
|
92
|
+
asset2 = create_application_asset(model, "Asset2")
|
|
93
|
+
model.add_asset(asset1)
|
|
94
|
+
model.add_asset(asset2)
|
|
95
|
+
|
|
96
|
+
# Add attacker 1
|
|
97
|
+
attacker1 = AttackerAttachment()
|
|
98
|
+
model.add_attacker(attacker1)
|
|
99
|
+
|
|
100
|
+
attacker1.add_entry_point(asset1, 'read')
|
|
101
|
+
attacker1.add_entry_point(asset1, 'access')
|
|
102
|
+
attacker1.add_entry_point(asset2, 'access')
|
|
103
|
+
|
|
104
|
+
assert len(attacker1.entry_points) == 2
|
|
105
|
+
assert attacker1.entry_points[0][0] == asset1
|
|
106
|
+
assert attacker1.entry_points[0][1] == ['read', 'access']
|
|
107
|
+
assert attacker1.entry_points[1][0] == asset2
|
|
108
|
+
assert attacker1.entry_points[1][1] == ['access']
|
|
109
|
+
|
|
110
|
+
attacker1.remove_entry_point(asset1, 'read')
|
|
111
|
+
assert len(attacker1.entry_points) == 2
|
|
112
|
+
assert attacker1.entry_points[0][0] == asset1
|
|
113
|
+
assert attacker1.entry_points[0][1] == ['access']
|
|
114
|
+
assert attacker1.entry_points[1][0] == asset2
|
|
115
|
+
assert attacker1.entry_points[1][1] == ['access']
|
|
116
|
+
|
|
117
|
+
# Try to remove inexistent entry point, but the asset is still present in
|
|
118
|
+
# the list of entry points
|
|
119
|
+
attacker1.remove_entry_point(asset1, 'read')
|
|
120
|
+
assert len(attacker1.entry_points) == 2
|
|
121
|
+
assert attacker1.entry_points[0][0] == asset1
|
|
122
|
+
assert attacker1.entry_points[0][1] == ['access']
|
|
123
|
+
assert attacker1.entry_points[1][0] == asset2
|
|
124
|
+
assert attacker1.entry_points[1][1] == ['access']
|
|
125
|
+
|
|
126
|
+
attacker1.remove_entry_point(asset1, 'access')
|
|
127
|
+
assert len(attacker1.entry_points) == 1
|
|
128
|
+
assert attacker1.entry_points[0][0] == asset2
|
|
129
|
+
assert attacker1.entry_points[0][1] == ['access']
|
|
130
|
+
|
|
131
|
+
# Try to remove inexistent entry point, where the asset is no longer in
|
|
132
|
+
# the list of entry points
|
|
133
|
+
attacker1.remove_entry_point(asset1, 'access')
|
|
134
|
+
assert len(attacker1.entry_points) == 1
|
|
135
|
+
assert attacker1.entry_points[0][0] == asset2
|
|
136
|
+
assert attacker1.entry_points[0][1] == ['access']
|
|
137
|
+
|
|
138
|
+
attacker1.remove_entry_point(asset2, 'access')
|
|
139
|
+
assert len(attacker1.entry_points) == 0
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def test_attacker_attachment_remove_asset(model: Model):
|
|
143
|
+
""""""
|
|
144
|
+
|
|
145
|
+
asset1 = create_application_asset(model, "Asset1")
|
|
146
|
+
asset2 = create_application_asset(model, "Asset2")
|
|
147
|
+
model.add_asset(asset1)
|
|
148
|
+
model.add_asset(asset2)
|
|
149
|
+
|
|
150
|
+
attacker1 = AttackerAttachment()
|
|
151
|
+
model.add_attacker(attacker1)
|
|
152
|
+
attacker2 = AttackerAttachment()
|
|
153
|
+
model.add_attacker(attacker2)
|
|
154
|
+
|
|
155
|
+
attacker1.add_entry_point(asset1, 'read')
|
|
156
|
+
attacker1.add_entry_point(asset1, 'access')
|
|
157
|
+
attacker1.add_entry_point(asset2, 'access')
|
|
158
|
+
|
|
159
|
+
attacker2.add_entry_point(asset1, 'read')
|
|
160
|
+
attacker2.add_entry_point(asset2, 'read')
|
|
161
|
+
attacker2.add_entry_point(asset2, 'access')
|
|
162
|
+
|
|
163
|
+
assert len(attacker1.entry_points) == 2
|
|
164
|
+
assert attacker1.entry_points[0][0] == asset1
|
|
165
|
+
assert attacker1.entry_points[0][1] == ['read', 'access']
|
|
166
|
+
assert attacker1.entry_points[1][0] == asset2
|
|
167
|
+
assert attacker1.entry_points[1][1] == ['access']
|
|
168
|
+
|
|
169
|
+
assert len(attacker2.entry_points) == 2
|
|
170
|
+
assert attacker2.entry_points[0][0] == asset1
|
|
171
|
+
assert attacker2.entry_points[0][1] == ['read']
|
|
172
|
+
assert attacker2.entry_points[1][0] == asset2
|
|
173
|
+
assert attacker2.entry_points[1][1] == ['read', 'access']
|
|
174
|
+
|
|
175
|
+
model.remove_asset(asset2)
|
|
176
|
+
# All of the entry points of the asset removed should be gone, but the
|
|
177
|
+
# other assets should not be impacted.
|
|
178
|
+
assert len(attacker1.entry_points) == 1
|
|
179
|
+
assert attacker1.entry_points[0][0] == asset1
|
|
180
|
+
assert attacker1.entry_points[0][1] == ['read', 'access']
|
|
181
|
+
|
|
182
|
+
assert len(attacker2.entry_points) == 1
|
|
183
|
+
assert attacker2.entry_points[0][0] == asset1
|
|
184
|
+
assert attacker2.entry_points[0][1] == ['read']
|
|
185
|
+
|
|
186
|
+
# Try to remove inexistent entry point, where the asset is no longer in
|
|
187
|
+
# the list of entry points
|
|
188
|
+
attacker1.remove_entry_point(asset2, 'access')
|
|
189
|
+
assert len(attacker1.entry_points) == 1
|
|
190
|
+
assert attacker1.entry_points[0][0] == asset1
|
|
191
|
+
assert attacker1.entry_points[0][1] == ['read', 'access']
|
|
192
|
+
|
|
193
|
+
assert len(attacker2.entry_points) == 1
|
|
194
|
+
assert attacker2.entry_points[0][0] == asset1
|
|
195
|
+
assert attacker2.entry_points[0][1] == ['read']
|
|
196
|
+
|
|
197
|
+
|
|
54
198
|
def test_model_add_asset(model: Model):
|
|
55
199
|
"""Make sure assets are added correctly"""
|
|
56
200
|
|
|
@@ -600,17 +744,17 @@ def test_model_attacker_to_dict(model: Model):
|
|
|
600
744
|
attacker_dict = ret[1]
|
|
601
745
|
assert attacker_dict.get('name') == attacker.name
|
|
602
746
|
|
|
603
|
-
#
|
|
604
|
-
|
|
747
|
+
# entry_points_dict has asset IDs as keys
|
|
748
|
+
entry_points_dict = attacker_dict.get('entry_points')
|
|
605
749
|
|
|
606
750
|
# attacker should be attached to p1, therefore p1s
|
|
607
|
-
# id should be a key in the
|
|
608
|
-
assert p1.id is not None and
|
|
609
|
-
assert p1.id in
|
|
751
|
+
# id should be a key in the entry_points_dict
|
|
752
|
+
assert p1.id is not None and entry_points_dict
|
|
753
|
+
assert p1.id in entry_points_dict
|
|
610
754
|
|
|
611
|
-
# The given steps should be inside the
|
|
755
|
+
# The given steps should be inside the entry_point of
|
|
612
756
|
# the attacker for asset p1
|
|
613
|
-
assert
|
|
757
|
+
assert entry_points_dict[p1.id]['attack_steps'] == attack_steps
|
|
614
758
|
|
|
615
759
|
|
|
616
760
|
def test_serialize(model: Model):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|