From 38b7b7809c5d44c851ec7874d4de17c2da44fc22 Mon Sep 17 00:00:00 2001 From: izar tarandach Date: Thu, 13 Nov 2025 13:13:43 -0500 Subject: [PATCH] BREAKING CHANGE - removing sqldump - #295 --- CHANGELOG.md | 6 + README.md | 4 +- docs/pytm/index.html | 776 ++++++++++++++++++++++--------------- docs/pytm/report_util.html | 92 ++--- docs/threats.md | 52 +++ pyproject.toml | 1 - requirements.txt | 1 - setup.py | 2 +- 8 files changed, 546 insertions(+), 388 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40d79811..4f47e28f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# Unreleased + +## Breaking changes + +- Removed SQLite dump functionality (`--sqldump` option) and associated `pydal` dependency + # 1.2.0 ## Breaking changes diff --git a/README.md b/README.md index dad22575..ddd1a7e9 100644 --- a/README.md +++ b/README.md @@ -73,15 +73,13 @@ lower overhead and more convenient alternative to the OCI container approach. All available arguments: ```text -usage: tm.py [-h] [--sqldump SQLDUMP] [--debug] [--dfd] [--report REPORT] +usage: tm.py [-h] [--debug] [--dfd] [--report REPORT] [--exclude EXCLUDE] [--seq] [--list] [--describe DESCRIBE] [--list-elements] [--json JSON] [--levels LEVELS [LEVELS ...]] [--stale_days STALE_DAYS] optional arguments: -h, --help show this help message and exit - --sqldump SQLDUMP dumps all threat model elements and findings into the - named sqlite file (erased if exists) --debug print debug messages --dfd output DFD --report REPORT output report using the named template file (sample diff --git a/docs/pytm/index.html b/docs/pytm/index.html index 3d0dcff9..31745abc 100644 --- a/docs/pytm/index.html +++ b/docs/pytm/index.html @@ -2,18 +2,32 @@ - - + + pytm API documentation - - - - - - + + + + + + - - + +
@@ -22,84 +36,14 @@

Package pytm

-
- -Expand source code - -
__all__ = [
-    "Action",
-    "Actor",
-    "Assumption",
-    "Boundary",
-    "Classification",
-    "TLSVersion",
-    "Data",
-    "Dataflow",
-    "Datastore",
-    "DatastoreType",
-    "Element",
-    "ExternalEntity",
-    "Finding",
-    "Lambda",
-    "Lifetime",
-    "load",
-    "loads",
-    "Process",
-    "Server",
-    "SetOfProcesses",
-    "Threat",
-    "TM",
-]
-
-import sys
-
-from .json import load, loads
-from .pytm import (
-    TM,
-    Action,
-    Actor,
-    Assumption,
-    Boundary,
-    Classification,
-    Data,
-    Dataflow,
-    Datastore,
-    DatastoreType,
-    Element,
-    ExternalEntity,
-    Finding,
-    Lambda,
-    Lifetime,
-    Process,
-    Server,
-    SetOfProcesses,
-    Threat,
-    TLSVersion,
-    var,
-)
-
-
-def pdoc_overrides():
-    result = {"pytm": False, "json": False, "template_engine": False}
-    mod = sys.modules[__name__]
-    for name, klass in mod.__dict__.items():
-        if not isinstance(klass, type):
-            continue
-        for i in dir(klass):
-            if i in ("check", "dfd", "seq"):
-                result[f"{name}.{i}"] = False
-            attr = getattr(klass, i, {})
-            if isinstance(attr, var) and attr.doc != "":
-                result[f"{name}.{i}"] = attr.doc
-    return result
-
-
-__pdoc__ = pdoc_overrides()
-

Sub-modules

+
pytm.flows
+
+
+
pytm.report_util
@@ -115,7 +59,6 @@

Functions

def load(fp)
-

Load a TM object from an open file containing JSON.

Expand source code @@ -127,12 +70,12 @@

Functions

raise ValueError("Failed to decode JSON input as TM") return result
+

Load a TM object from an open file containing JSON.

def loads(s)
-

Load a TM object from a JSON string s.

Expand source code @@ -144,6 +87,7 @@

Functions

raise ValueError("Failed to decode JSON input as TM") return result
+

Load a TM object from a JSON string s.

@@ -152,10 +96,9 @@

Classes

class Action -(value, names=None, *, module=None, qualname=None, type=None, start=1) +(*args, **kwds)
-

Action taken when validating a threat model.

Expand source code @@ -167,6 +110,7 @@

Classes

RESTRICT = "RESTRICT" IGNORE = "IGNORE"
+

Action taken when validating a threat model.

Ancestors

  • enum.Enum
  • @@ -175,15 +119,15 @@

    Class variables

    var IGNORE
    -
    +

    The type of the None singleton.

    var NO_ACTION
    -
    +

    The type of the None singleton.

    var RESTRICT
    -
    +

    The type of the None singleton.

@@ -192,7 +136,6 @@

Class variables

(name, **kwargs)
-

An entity usually initiating actions

Expand source code @@ -211,6 +154,7 @@

Class variables

super().__init__(name, **kwargs) TM._actors.append(self)
+

An entity usually initiating actions

Ancestors

  • pytm.pytm.Element
  • @@ -219,7 +163,6 @@

    Instance variables

    var data
    -

    pytm.Data object(s) in outgoing data flows

    Expand source code @@ -232,10 +175,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    pytm.Data object(s) in outgoing data flows

    var inputs
    -

    incoming Dataflows

    Expand source code @@ -248,10 +191,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    incoming Dataflows

    var isAdmin
    -
    Expand source code @@ -264,10 +207,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var outputs
    -

    outgoing Dataflows

    Expand source code @@ -280,10 +223,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    outgoing Dataflows

    var port
    -

    Default TCP port for outgoing data flows

    Expand source code @@ -296,10 +239,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Default TCP port for outgoing data flows

    var protocol
    -

    Default network protocol for outgoing data flows

    Expand source code @@ -312,6 +255,7 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Default network protocol for outgoing data flows

@@ -320,8 +264,6 @@

Instance variables

(name, **kwargs)
-

Assumption used by an Element. -Used to exclude threats on a per-element basis.

Expand source code @@ -338,13 +280,17 @@

Instance variables

def __init__(self, name, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) - self.name = name + self.name = name + + def __str__(self): + return self.name
+

Assumption used by an Element. +Used to exclude threats on a per-element basis.

Instance variables

var description
-

An additional description of the assumption

Expand source code @@ -357,10 +303,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

An additional description of the assumption

var exclude
-

A list of threat SIDs to exclude for this assumption. For example: INP01

Expand source code @@ -373,10 +319,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

A list of threat SIDs to exclude for this assumption. For example: INP01

var name
-
Expand source code @@ -389,6 +335,7 @@

Instance variables

return self return self.data.get(instance, self.default)
+
@@ -397,7 +344,6 @@

Instance variables

(name, **kwargs)
-

Trust boundary groups elements and data with the same trust level.

Expand source code @@ -458,6 +404,7 @@

Instance variables

parent = parent.inBoundary return result
+

Trust boundary groups elements and data with the same trust level.

Ancestors

  • pytm.pytm.Element
  • @@ -468,7 +415,6 @@

    Methods

    def parents(self)
    -
    Expand source code @@ -481,15 +427,15 @@

    Methods

    parent = parent.inBoundary return result
    +
class Classification -(value, names=None, *, module=None, qualname=None, type=None, start=1) +(*args, **kwds)
-

An enumeration.

Expand source code @@ -502,6 +448,56 @@

Methods

SECRET = 4 TOP_SECRET = 5
+

Create a collection of name/value pairs.

+

Example enumeration:

+
>>> class Color(Enum):
+...     RED = 1
+...     BLUE = 2
+...     GREEN = 3
+
+

Access them by:

+
    +
  • attribute access:
  • +
+
+
+
+

Color.RED +

+
+
+
+
    +
  • value lookup:
  • +
+
+
+
+

Color(1) +

+
+
+
+
    +
  • name lookup:
  • +
+
+
+
+

Color['RED'] +

+
+
+
+

Enumerations can be iterated over, and know how many members they have:

+
>>> len(Color)
+3
+
+
>>> list(Color)
+[<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]
+
+

Methods can be added to enumerations, and members can have their own +attributes – see the documentation for details.

Ancestors

  • pytm.pytm.OrderedEnum
  • @@ -511,27 +507,27 @@

    Class variables

    var PUBLIC
    -
    +

    The type of the None singleton.

    var RESTRICTED
    -
    +

    The type of the None singleton.

    var SECRET
    -
    +

    The type of the None singleton.

    var SENSITIVE
    -
    +

    The type of the None singleton.

    var TOP_SECRET
    -
    +

    The type of the None singleton.

    var UNKNOWN
    -
    +

    The type of the None singleton.

@@ -540,7 +536,6 @@

Class variables

(name, **kwargs)
-

Represents a single piece of data that traverses the system

Expand source code @@ -611,11 +606,11 @@

Class variables

except ValueError: pass
+

Represents a single piece of data that traverses the system

Instance variables

var carriedBy
-

Dataflows that carries this piece of data

Expand source code @@ -628,10 +623,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Dataflows that carries this piece of data

var classification
-

Level of classification for this piece of data

Expand source code @@ -644,19 +639,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Level of classification for this piece of data

var credentialsLife
-

Credentials lifetime, describing if and how -credentials can be revoked. One of: -* NONE - not applicable -* UNKNOWN - unknown lifetime -* SHORT - relatively short expiration date, with an allowed maximum -* LONG - long or no expiration date -* AUTO - no expiration date but can be revoked/invalidated automatically -in some conditions -* MANUAL - no expiration date but can be revoked/invalidated manually -* HARDCODED - cannot be invalidated at all

Expand source code @@ -669,10 +655,19 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Credentials lifetime, describing if and how +credentials can be revoked. One of: +* NONE - not applicable +* UNKNOWN - unknown lifetime +* SHORT - relatively short expiration date, with an allowed maximum +* LONG - long or no expiration date +* AUTO - no expiration date but can be revoked/invalidated automatically +in some conditions +* MANUAL - no expiration date but can be revoked/invalidated manually +* HARDCODED - cannot be invalidated at all

var description
-
Expand source code @@ -685,10 +680,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+
var format
-
Expand source code @@ -701,13 +696,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+
var isCredentials
-

Does the data contain authentication information, -like passwords or cryptographic keys, with or without expiration date. -Should always be encrypted in transmission. If stored, they should be hashed -using a cryptographic hash function.

Expand source code @@ -720,10 +712,13 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Does the data contain authentication information, +like passwords or cryptographic keys, with or without expiration date. +Should always be encrypted in transmission. If stored, they should be hashed +using a cryptographic hash function.

var isDestEncryptedAtRest
-

Is data encrypted at rest at dest

Expand source code @@ -736,11 +731,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Is data encrypted at rest at dest

var isPII
-

Does the data contain personally identifyable information. -Should always be encrypted both in transmission and at rest.

Expand source code @@ -753,10 +747,11 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Does the data contain personally identifyable information. +Should always be encrypted both in transmission and at rest.

var isSourceEncryptedAtRest
-

Is data encrypted at rest at source

Expand source code @@ -769,11 +764,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Is data encrypted at rest at source

var isStored
-

Is the data going to be stored by the target or only processed. -If only derivative data is stored (a hash) it can be set to False.

Expand source code @@ -786,10 +780,11 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Is the data going to be stored by the target or only processed. +If only derivative data is stored (a hash) it can be set to False.

var name
-
Expand source code @@ -802,10 +797,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+
var processedBy
-

Elements that store/process this piece of data

Expand source code @@ -818,6 +813,7 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Elements that store/process this piece of data

@@ -826,7 +822,6 @@

Instance variables

(source, sink, name, **kwargs)
-

A data flow from a source to a sink

Expand source code @@ -913,6 +908,7 @@

Instance variables

for d in self.data )
+

A data flow from a source to a sink

Ancestors

  • pytm.pytm.Element
  • @@ -921,14 +917,13 @@

    Class variables

    var severity
    -
    +

    The type of the None singleton.

    Instance variables

    var data
    -

    pytm.Data object(s) in incoming data flows

    Expand source code @@ -941,10 +936,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    pytm.Data object(s) in incoming data flows

    var dstPort
    -

    Destination TCP port

    Expand source code @@ -957,10 +952,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Destination TCP port

    var implementsCommunicationProtocol
    -
    Expand source code @@ -973,10 +968,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var isResponse
    -

    Is a response to another data flow

    Expand source code @@ -989,10 +984,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Is a response to another data flow

    var note
    -
    Expand source code @@ -1005,10 +1000,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var order
    -

    Number of this data flow in the threat model

    Expand source code @@ -1021,10 +1016,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Number of this data flow in the threat model

    var protocol
    -

    Protocol used in this data flow

    Expand source code @@ -1037,10 +1032,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Protocol used in this data flow

    var response
    -

    Another data flow that is a response to this one

    Expand source code @@ -1053,10 +1048,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Another data flow that is a response to this one

    var responseTo
    -

    Is a response to this data flow

    Expand source code @@ -1069,10 +1064,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Is a response to this data flow

    var sink
    -
    Expand source code @@ -1085,10 +1080,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var source
    -
    Expand source code @@ -1101,10 +1096,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var srcPort
    -

    Source TCP port

    Expand source code @@ -1117,10 +1112,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Source TCP port

    var tlsVersion
    -

    TLS version used.

    Expand source code @@ -1133,10 +1128,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    TLS version used.

    var usesSessionTokens
    -
    Expand source code @@ -1149,10 +1144,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var usesVPN
    -
    Expand source code @@ -1165,6 +1160,7 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Methods

    @@ -1173,7 +1169,6 @@

    Methods

    def display_name(self)
    -
    Expand source code @@ -1183,12 +1178,12 @@

    Methods

    return self.name return "({}) {}".format(self.order, self.name)
    +
    def hasDataLeaks(self)
    -
    Expand source code @@ -1201,6 +1196,7 @@

    Methods

    for d in self.data )
    +
@@ -1209,7 +1205,6 @@

Methods

(name, **kwargs)
-

An entity storing data

Expand source code @@ -1281,6 +1276,7 @@

Methods

), )
+

An entity storing data

Ancestors

  • pytm.pytm.Asset
  • @@ -1290,7 +1286,6 @@

    Instance variables

    var hasWriteAccess
    -
    Expand source code @@ -1303,10 +1298,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var isSQL
    -
    Expand source code @@ -1319,10 +1314,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var isShared
    -
    Expand source code @@ -1335,10 +1330,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var onRDS
    -
    Expand source code @@ -1351,10 +1346,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var storesLogData
    -
    Expand source code @@ -1367,11 +1362,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var storesPII
    -

    Personally Identifiable Information -is any information relating to an identifiable person.

    Expand source code @@ -1384,10 +1378,11 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Personally Identifiable Information +is any information relating to an identifiable person.

    var storesSensitiveData
    -
    Expand source code @@ -1400,16 +1395,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var type
    -

    The -type of Datastore, values may be one of: -* UNKNOWN - unknown applicable -* FILE_SYSTEM - files on a file system -* SQL - A SQL Database -* LDAP - An LDAP Server -* AWS_S3 - An S3 Bucket within AWS

    Expand source code @@ -1422,15 +1411,21 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    The +type of Datastore, values may be one of: +* UNKNOWN - unknown applicable +* FILE_SYSTEM - files on a file system +* SQL - A SQL Database +* LDAP - An LDAP Server +* AWS_S3 - An S3 Bucket within AWS

class DatastoreType -(value, names=None, *, module=None, qualname=None, type=None, start=1) +(*args, **kwds)
-

An enumeration.

Expand source code @@ -1445,6 +1440,56 @@

Instance variables

def label(self): return self.value.lower().replace("_", " ")
+

Create a collection of name/value pairs.

+

Example enumeration:

+
>>> class Color(Enum):
+...     RED = 1
+...     BLUE = 2
+...     GREEN = 3
+
+

Access them by:

+
    +
  • attribute access:
  • +
+
+
+
+

Color.RED +

+
+
+
+
    +
  • value lookup:
  • +
+
+
+
+

Color(1) +

+
+
+
+
    +
  • name lookup:
  • +
+
+
+
+

Color['RED'] +

+
+
+
+

Enumerations can be iterated over, and know how many members they have:

+
>>> len(Color)
+3
+
+
>>> list(Color)
+[<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]
+
+

Methods can be added to enumerations, and members can have their own +attributes – see the documentation for details.

Ancestors

  • enum.Enum
  • @@ -1453,23 +1498,23 @@

    Class variables

    var AWS_S3
    -
    +

    The type of the None singleton.

    var FILE_SYSTEM
    -
    +

    The type of the None singleton.

    var LDAP
    -
    +

    The type of the None singleton.

    var SQL
    -
    +

    The type of the None singleton.

    var UNKNOWN
    -
    +

    The type of the None singleton.

    Methods

    @@ -1478,7 +1523,6 @@

    Methods

    def label(self)
    -
    Expand source code @@ -1486,6 +1530,7 @@

    Methods

    def label(self):
         return self.value.lower().replace("_", " ")
    +
@@ -1494,7 +1539,6 @@

Methods

(name, **kwargs)
-

A generic element

Expand source code @@ -1696,6 +1740,7 @@

Methods

self.severity = sevs[sev.lower()] return
+

A generic element

Subclasses

  • pytm.pytm.Actor
  • @@ -1707,14 +1752,13 @@

    Class variables

    var severity
    -
    +

    The type of the None singleton.

    Instance variables

    var assumptions
    -

    Assumptions about the element. These optionally allow to exclude threats with the given SIDs.

    Expand source code @@ -1727,10 +1771,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Assumptions about the element. These optionally allow to exclude threats with the given SIDs.

    var controls
    -
    Expand source code @@ -1743,10 +1787,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var description
    -
    Expand source code @@ -1759,10 +1803,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var findings
    -

    Threats that apply to this element

    Expand source code @@ -1775,10 +1819,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Threats that apply to this element

    var inBoundary
    -

    Trust boundary this element exists in

    Expand source code @@ -1791,10 +1835,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Trust boundary this element exists in

    var inScope
    -

    Is the element in scope of the threat model

    Expand source code @@ -1807,10 +1851,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Is the element in scope of the threat model

    var levels
    -

    List of levels (0, 1, 2, …) to be drawn in the model.

    Expand source code @@ -1823,10 +1867,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    List of levels (0, 1, 2, …) to be drawn in the model.

    var maxClassification
    -

    Maximum data classification this element can handle.

    Expand source code @@ -1839,10 +1883,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Maximum data classification this element can handle.

    var minTLSVersion
    -

    Minimum TLS version required.

    Expand source code @@ -1855,10 +1899,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Minimum TLS version required.

    var name
    -
    Expand source code @@ -1871,11 +1915,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var overrides
    -

    Overrides to findings, allowing to set -a custom response, CVSS score or override other attributes.

    Expand source code @@ -1888,10 +1931,11 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Overrides to findings, allowing to set +a custom response, CVSS score or override other attributes.

    var sourceFiles
    -

    Location of the source code that describes this element relative to the directory of the model script.

    Expand source code @@ -1904,6 +1948,7 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +

    Location of the source code that describes this element relative to the directory of the model script.

    Methods

    @@ -1912,7 +1957,6 @@

    Methods

    def checkTLSVersion(self, flows)
    -
    Expand source code @@ -1920,12 +1964,12 @@

    Methods

    def checkTLSVersion(self, flows):
         return any(f.tlsVersion < self.minTLSVersion for f in flows)
    +
    def crosses(self, *boundaries)
    -

    Does self (dataflow) cross any of the list of boundaries

    Expand source code @@ -1954,12 +1998,12 @@

    Methods

    return True return False
    +

    Does self (dataflow) cross any of the list of boundaries

    def display_name(self)
    -
    Expand source code @@ -1967,12 +2011,12 @@

    Methods

    def display_name(self):
         return self.name
    +
    def enters(self, *boundaries)
    -

    does self (dataflow) enter into one of the list of boundaries

    Expand source code @@ -1981,12 +2025,12 @@

    Methods

    """does self (dataflow) enter into one of the list of boundaries""" return self.source.inBoundary is None and self.sink.inside(*boundaries)
    +

    does self (dataflow) enter into one of the list of boundaries

    def exits(self, *boundaries)
    -

    does self (dataflow) exit one of the list of boundaries

    Expand source code @@ -1995,12 +2039,12 @@

    Methods

    """does self (dataflow) exit one of the list of boundaries""" return self.source.inside(*boundaries) and self.sink.inBoundary is None
    +

    does self (dataflow) exit one of the list of boundaries

    def inside(self, *boundaries)
    -

    is self inside of one of the list of boundaries

    Expand source code @@ -2015,12 +2059,12 @@

    Methods

    return True return False
    +

    is self inside of one of the list of boundaries

    def oneOf(self, *elements)
    -

    Is self one of a list of Elements

    Expand source code @@ -2035,6 +2079,7 @@

    Methods

    return True return False
    +

    Is self one of a list of Elements

@@ -2043,7 +2088,6 @@

Methods

(name, **kwargs)
-

An asset with outgoing or incoming dataflows

Expand source code @@ -2054,6 +2098,7 @@

Methods

def __init__(self, name, **kwargs): super().__init__(name, **kwargs)
+

An asset with outgoing or incoming dataflows

Ancestors

  • pytm.pytm.Asset
  • @@ -2063,7 +2108,6 @@

    Instance variables

    var hasPhysicalAccess
    -
    Expand source code @@ -2076,6 +2120,7 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
@@ -2084,8 +2129,6 @@

Instance variables

(*args, **kwargs)
-

Represents a Finding - the element in question -and a description of the finding

Expand source code @@ -2181,11 +2224,12 @@

Instance variables

def __str__(self): return f"'{self.target}': {self.description}\n{self.details}\n{self.severity}"
+

Represents a Finding - the element in question +and a description of the finding

Instance variables

var assumption
-

The assumption, that caused this finding to be excluded

Expand source code @@ -2198,10 +2242,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

The assumption, that caused this finding to be excluded

var condition
-

Threat condition

Expand source code @@ -2214,10 +2258,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Threat condition

var cvss
-

The CVSS score and/or vector

Expand source code @@ -2230,10 +2274,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

The CVSS score and/or vector

var description
-

Threat description

Expand source code @@ -2246,10 +2290,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Threat description

var details
-

Threat details

Expand source code @@ -2262,10 +2306,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Threat details

var element
-

Element this finding applies to

Expand source code @@ -2278,10 +2322,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Element this finding applies to

var example
-

Threat example

Expand source code @@ -2294,10 +2338,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Threat example

var id
-

Finding ID

Expand source code @@ -2310,10 +2354,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Finding ID

var mitigations
-

Threat mitigations

Expand source code @@ -2326,10 +2370,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Threat mitigations

var references
-

Threat references

Expand source code @@ -2342,15 +2386,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Threat references

var response
-

Describes how this threat matching this particular asset or dataflow is being handled. -Can be one of: -* mitigated - there were changes made in the modeled system to reduce the probability of this threat occurring or the impact when it does, -* transferred - users of the system are required to mitigate this threat, -* avoided - this asset or dataflow is removed from the system, -* accepted - no action is taken as the probability and/or impact is very low

Expand source code @@ -2363,10 +2402,15 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Describes how this threat matching this particular asset or dataflow is being handled. +Can be one of: +* mitigated - there were changes made in the modeled system to reduce the probability of this threat occurring or the impact when it does, +* transferred - users of the system are required to mitigate this threat, +* avoided - this asset or dataflow is removed from the system, +* accepted - no action is taken as the probability and/or impact is very low

var severity
-

Threat severity

Expand source code @@ -2379,10 +2423,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Threat severity

var target
-

Name of the element this finding applies to

Expand source code @@ -2395,10 +2439,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Name of the element this finding applies to

var threat_id
-

Threat ID

Expand source code @@ -2411,6 +2455,7 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Threat ID

@@ -2419,7 +2464,6 @@

Instance variables

(name, **kwargs)
-

A lambda function running in a Function-as-a-Service (FaaS) environment

Expand source code @@ -2470,6 +2514,7 @@

Instance variables

def _shape(self): return "rectangle; style=rounded"
+

A lambda function running in a Function-as-a-Service (FaaS) environment

Ancestors

  • pytm.pytm.Asset
  • @@ -2479,7 +2524,6 @@

    Instance variables

    var environment
    -
    Expand source code @@ -2492,10 +2536,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var implementsAPI
    -
    Expand source code @@ -2508,10 +2552,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var onAWS
    -
    Expand source code @@ -2524,15 +2568,15 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
class Lifetime -(value, names=None, *, module=None, qualname=None, type=None, start=1) +(*args, **kwds)
-

An enumeration.

Expand source code @@ -2556,6 +2600,56 @@

Instance variables

def label(self): return self.value.lower().replace("_", " ")
+

Create a collection of name/value pairs.

+

Example enumeration:

+
>>> class Color(Enum):
+...     RED = 1
+...     BLUE = 2
+...     GREEN = 3
+
+

Access them by:

+
    +
  • attribute access:
  • +
+
+
+
+

Color.RED +

+
+
+
+
    +
  • value lookup:
  • +
+
+
+
+

Color(1) +

+
+
+
+
    +
  • name lookup:
  • +
+
+
+
+

Color['RED'] +

+
+
+
+

Enumerations can be iterated over, and know how many members they have:

+
>>> len(Color)
+3
+
+
>>> list(Color)
+[<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]
+
+

Methods can be added to enumerations, and members can have their own +attributes – see the documentation for details.

Ancestors

  • enum.Enum
  • @@ -2564,31 +2658,31 @@

    Class variables

    var AUTO
    -
    +

    The type of the None singleton.

    var HARDCODED
    -
    +

    The type of the None singleton.

    var LONG
    -
    +

    The type of the None singleton.

    var MANUAL
    -
    +

    The type of the None singleton.

    var NONE
    -
    +

    The type of the None singleton.

    var SHORT
    -
    +

    The type of the None singleton.

    var UNKNOWN
    -
    +

    The type of the None singleton.

    Methods

    @@ -2597,7 +2691,6 @@

    Methods

    def label(self)
    -
    Expand source code @@ -2605,6 +2698,7 @@

    Methods

    def label(self):
         return self.value.lower().replace("_", " ")
    +
@@ -2613,7 +2707,6 @@

Methods

(name, **kwargs)
-

An entity processing data

Expand source code @@ -2634,6 +2727,7 @@

Methods

def _shape(self): return "circle"
+

An entity processing data

Ancestors

  • pytm.pytm.Asset
  • @@ -2647,7 +2741,6 @@

    Instance variables

    var allowsClientSideScripting
    -
    Expand source code @@ -2660,10 +2753,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var codeType
    -
    Expand source code @@ -2676,10 +2769,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var environment
    -
    Expand source code @@ -2692,10 +2785,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var implementsAPI
    -
    Expand source code @@ -2708,10 +2801,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var implementsCommunicationProtocol
    -
    Expand source code @@ -2724,10 +2817,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var tracksExecutionFlow
    -
    Expand source code @@ -2740,6 +2833,7 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
@@ -2748,7 +2842,6 @@

Instance variables

(name, **kwargs)
-

An entity processing data

Expand source code @@ -2767,6 +2860,7 @@

Instance variables

def _shape(self): return "circle"
+

An entity processing data

Ancestors

  • pytm.pytm.Asset
  • @@ -2776,7 +2870,6 @@

    Instance variables

    var usesCache
    -
    Expand source code @@ -2789,10 +2882,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var usesSessionTokens
    -
    Expand source code @@ -2805,10 +2898,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var usesVPN
    -
    Expand source code @@ -2821,10 +2914,10 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
    var usesXMLParser
    -
    Expand source code @@ -2837,6 +2930,7 @@

    Instance variables

    return self return self.data.get(instance, self.default)
    +
@@ -2845,7 +2939,6 @@

Instance variables

(name, **kwargs)
-

An entity processing data

Expand source code @@ -2857,6 +2950,7 @@

Instance variables

def _shape(self): return "doublecircle"
+

An entity processing data

Ancestors

  • pytm.pytm.Process
  • @@ -2866,10 +2960,9 @@

    Ancestors

class TLSVersion -(value, names=None, *, module=None, qualname=None, type=None, start=1) +(*args, **kwds)
-

An enumeration.

Expand source code @@ -2884,6 +2977,56 @@

Ancestors

TLSv12 = 6 TLSv13 = 7
+

Create a collection of name/value pairs.

+

Example enumeration:

+
>>> class Color(Enum):
+...     RED = 1
+...     BLUE = 2
+...     GREEN = 3
+
+

Access them by:

+
    +
  • attribute access:
  • +
+
+
+
+

Color.RED +

+
+
+
+
    +
  • value lookup:
  • +
+
+
+
+

Color(1) +

+
+
+
+
    +
  • name lookup:
  • +
+
+
+
+

Color['RED'] +

+
+
+
+

Enumerations can be iterated over, and know how many members they have:

+
>>> len(Color)
+3
+
+
>>> list(Color)
+[<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]
+
+

Methods can be added to enumerations, and members can have their own +attributes – see the documentation for details.

Ancestors

  • pytm.pytm.OrderedEnum
  • @@ -2893,35 +3036,35 @@

    Class variables

    var NONE
    -
    +

    The type of the None singleton.

    var SSLv1
    -
    +

    The type of the None singleton.

    var SSLv2
    -
    +

    The type of the None singleton.

    var SSLv3
    -
    +

    The type of the None singleton.

    var TLSv10
    -
    +

    The type of the None singleton.

    var TLSv11
    -
    +

    The type of the None singleton.

    var TLSv12
    -
    +

    The type of the None singleton.

    var TLSv13
    -
    +

    The type of the None singleton.

@@ -2930,8 +3073,6 @@

Class variables

(name, **kwargs)
-

Describes the threat model administratively, -and holds all details during a run

Expand source code @@ -2978,7 +3119,7 @@

Class variables

doc="""How to handle duplicate Dataflow with same properties, except name and notes""", ) - assumptions = varStrings( + assumptions = varAssumptions( [], required=False, doc="A list of assumptions about the design/model.", @@ -3017,18 +3158,21 @@

Class variables

raise UIError( e, f"while trying to open the the threat file ({self.threatsFile})." ) - - for i in threats_json: - TM._threats.append(Threat(**i)) + active_threats = (threat for threat in threats_json if "DEPRECATED" not in threat) + for threat in active_threats: + TM._threats.append(Threat(**threat)) def resolve(self): finding_count = 0 excluded_finding_count = 0 findings = [] excluded_findings = [] + # We just need the assumptions with SIDs to exclude + global_assumptions = [a for a in self.assumptions if len(a.exclude) > 0] elements = defaultdict(list) for e in TM._elements: if not e.inScope: + e.findings = findings continue override_ids = set(f.threat_id for f in e.overrides) @@ -3049,7 +3193,7 @@

Class variables

continue _continue = False - for assumption in e.assumptions: # type: Assumption + for assumption in e.assumptions + global_assumptions: # type: Assumption if t.id in assumption.exclude: excluded_finding_count += 1 f = Finding(e, id=str(excluded_finding_count), threat=t, assumption=assumption) @@ -3446,6 +3590,8 @@

Class variables

db.close()
+

Describes the threat model administratively, +and holds all details during a run

Static methods

@@ -3453,28 +3599,12 @@

Static methods

-
- -Expand source code - -
@classmethod
-def reset(cls):
-    cls._flows = []
-    cls._elements = []
-    cls._actors = []
-    cls._assets = []
-    cls._threats = []
-    cls._boundaries = []
-    cls._data = []
-    cls._threatsExcluded = []
-

Instance variables

var assumptions
-

A list of assumptions about the design/model.

Expand source code @@ -3487,10 +3617,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

A list of assumptions about the design/model.

var description
-

Model description

Expand source code @@ -3503,10 +3633,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Model description

var excluded_findings
-

Threats found for elements of this model, that were excluded on a per-element basis, using the Assumptions class

Expand source code @@ -3519,10 +3649,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Threats found for elements of this model, that were excluded on a per-element basis, using the Assumptions class

var findings
-

Threats found for elements of this model

Expand source code @@ -3535,10 +3665,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Threats found for elements of this model

var ignoreUnused
-

Ignore elements not used in any Dataflow

Expand source code @@ -3551,10 +3681,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Ignore elements not used in any Dataflow

var isOrdered
-

Automatically order all Dataflows

Expand source code @@ -3567,10 +3697,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Automatically order all Dataflows

var mergeResponses
-

Merge response edges in DFDs

Expand source code @@ -3583,10 +3713,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Merge response edges in DFDs

var name
-

Model name

Expand source code @@ -3599,11 +3729,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Model name

var onDuplicates
-

How to handle duplicate Dataflow -with same properties, except name and notes

Expand source code @@ -3616,10 +3745,11 @@

Instance variables

return self return self.data.get(instance, self.default)
+

How to handle duplicate Dataflow +with same properties, except name and notes

var threatsFile
-

JSON file with custom threats

Expand source code @@ -3632,6 +3762,7 @@

Instance variables

return self return self.data.get(instance, self.default)
+

JSON file with custom threats

Methods

@@ -3640,7 +3771,6 @@

Methods

def process(self)
-
Expand source code @@ -3656,12 +3786,12 @@

Methods

sys.stderr.write(erromsg) sys.exit(127)
+
def report(self, template_path)
-
Expand source code @@ -3698,12 +3828,12 @@

Methods

return self._sf.format(template, **data)
+
def resolve(self)
-
Expand source code @@ -3713,9 +3843,12 @@

Methods

excluded_finding_count = 0 findings = [] excluded_findings = [] + # We just need the assumptions with SIDs to exclude + global_assumptions = [a for a in self.assumptions if len(a.exclude) > 0] elements = defaultdict(list) for e in TM._elements: if not e.inScope: + e.findings = findings continue override_ids = set(f.threat_id for f in e.overrides) @@ -3736,7 +3869,7 @@

Methods

continue _continue = False - for assumption in e.assumptions: # type: Assumption + for assumption in e.assumptions + global_assumptions: # type: Assumption if t.id in assumption.exclude: excluded_finding_count += 1 f = Finding(e, id=str(excluded_finding_count), threat=t, assumption=assumption) @@ -3756,12 +3889,12 @@

Methods

for e, findings in elements.items(): e.findings = findings
+
def sqlDump(self, filename)
-
Expand source code @@ -3825,6 +3958,7 @@

Methods

db.close()
+
@@ -3833,7 +3967,6 @@

Methods

(**kwargs)
-

Represents a possible threat

Expand source code @@ -3894,19 +4027,18 @@

Methods

return None return eval(self.condition)
+

Represents a possible threat

Class variables

var target
-
+

The type of the None singleton.

Instance variables

var condition
-

a Python expression that should evaluate -to a boolean True or False

Expand source code @@ -3919,10 +4051,11 @@

Instance variables

return self return self.data.get(instance, self.default)
+

a Python expression that should evaluate +to a boolean True or False

var description
-
Expand source code @@ -3935,10 +4068,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+
var details
-
Expand source code @@ -3951,10 +4084,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+
var example
-
Expand source code @@ -3967,10 +4100,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+
var id
-
Expand source code @@ -3983,10 +4116,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+
var likelihood
-
Expand source code @@ -3999,10 +4132,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+
var mitigations
-
Expand source code @@ -4015,10 +4148,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+
var prerequisites
-
Expand source code @@ -4031,10 +4164,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+
var references
-
Expand source code @@ -4047,10 +4180,10 @@

Instance variables

return self return self.data.get(instance, self.default)
+
var severity
-
Expand source code @@ -4063,6 +4196,7 @@

Instance variables

return self return self.data.get(instance, self.default)
+

Methods

@@ -4071,7 +4205,6 @@

Methods

def apply(self, target)
-
Expand source code @@ -4081,6 +4214,7 @@

Methods

return None return eval(self.condition)
+
@@ -4088,13 +4222,13 @@

Methods

- \ No newline at end of file + diff --git a/docs/pytm/report_util.html b/docs/pytm/report_util.html index 4cd12109..363e8735 100644 --- a/docs/pytm/report_util.html +++ b/docs/pytm/report_util.html @@ -2,18 +2,32 @@ - - + + pytm.report_util API documentation - - - - - - + + + + + + - - + +
@@ -22,49 +36,6 @@

Module pytm.report_util

-
- -Expand source code - -
class ReportUtils:
-    @staticmethod
-    def getParentName(element):
-        from pytm import Boundary
-        if (isinstance(element, Boundary)):
-            parent = element.inBoundary
-            if (parent is not None):
-                return parent.name
-            else:
-                return str("")
-        else:
-            return "ERROR: getParentName method is not valid for " + element.__class__.__name__
-
-
-    @staticmethod
-    def getNamesOfParents(element):
-        from pytm import Boundary
-        if (isinstance(element, Boundary)):
-            parents = [p.name for p in element.parents()] 
-            return parents 
-        else:
-            return "ERROR: getNamesOfParents method is not valid for " + element.__class__.__name__
-
-    @staticmethod
-    def getFindingCount(element):
-        from pytm import Element
-        if (isinstance(element, Element)):
-            return str(len(list(element.findings)))
-        else:
-            return "ERROR: getFindingCount method is not valid for " + element.__class__.__name__
-
-    @staticmethod
-    def getElementType(element):
-        from pytm import Element
-        if (isinstance(element, Element)):
-            return str(element.__class__.__name__)
-        else:
-            return "ERROR: getElementType method is not valid for " + element.__class__.__name__
-
@@ -79,7 +50,6 @@

Classes

class ReportUtils
-
Expand source code @@ -123,13 +93,13 @@

Classes

else: return "ERROR: getElementType method is not valid for " + element.__class__.__name__
+

Static methods

def getElementType(element)
-
Expand source code @@ -142,12 +112,12 @@

Static methods

else: return "ERROR: getElementType method is not valid for " + element.__class__.__name__
+
def getFindingCount(element)
-
Expand source code @@ -160,12 +130,12 @@

Static methods

else: return "ERROR: getFindingCount method is not valid for " + element.__class__.__name__
+
def getNamesOfParents(element)
-
Expand source code @@ -179,12 +149,12 @@

Static methods

else: return "ERROR: getNamesOfParents method is not valid for " + element.__class__.__name__
+
def getParentName(element)
-
Expand source code @@ -201,6 +171,7 @@

Static methods

else: return "ERROR: getParentName method is not valid for " + element.__class__.__name__
+
@@ -208,7 +179,6 @@

Static methods