Пример #1
0
    def test_duplicate_boundary_names_have_different_unique_names(self):
        object_1 = Boundary("foo")
        object_2 = Boundary("foo")

        object_1_uniq_name = _uniq_name(object_1.name, object_1.uuid)
        object_2_uniq_name = _uniq_name(object_2.name, object_2.uuid)

        self.assertNotEqual(object_1_uniq_name, object_2_uniq_name)
Пример #2
0
    def test_defaults(self):
        tm = TM("my test tm", description="aa", isOrdered=True)

        internet = Boundary("Internet")
        cloud = Boundary("Cloud")

        user = Actor("User", inBoundary=internet)
        server = Server("Server")
        db = Datastore("DB", inBoundary=cloud)
        db.type = DatastoreType.SQL
        func = Datastore("Lambda function", inBoundary=cloud)

        request = Dataflow(user, server, "request")
        response = Dataflow(server, user, "response", isResponse=True)
        user_query = Dataflow(user, db, "user query")
        server_query = Dataflow(server, db, "server query")
        func_query = Dataflow(func, db, "func query")

        default_target = ["Actor", "Boundary", "Dataflow", "Datastore", "Server"]
        testCases = [
            {"target": server, "condition": "target.oneOf(Server, Datastore)"},
            {"target": server, "condition": "not target.oneOf(Actor, Dataflow)"},
            {"target": request, "condition": "target.crosses(Boundary)"},
            {"target": user_query, "condition": "target.crosses(Boundary)"},
            {"target": server_query, "condition": "target.crosses(Boundary)"},
            {"target": func_query, "condition": "not target.crosses(Boundary)"},
            {"target": func_query, "condition": "not target.enters(Boundary)"},
            {"target": func_query, "condition": "not target.exits(Boundary)"},
            {"target": request, "condition": "not target.enters(Boundary)"},
            {"target": request, "condition": "target.exits(Boundary)"},
            {"target": response, "condition": "target.enters(Boundary)"},
            {"target": response, "condition": "not target.exits(Boundary)"},
            {"target": user, "condition": "target.inside(Boundary)"},
            {"target": func, "condition": "not any(target.inputs)"},
            {
                "target": server,
                "condition": "any(f.sink.oneOf(Datastore) and f.sink.type == DatastoreType.SQL "
                "for f in target.outputs)",
            },
        ]

        self.assertTrue(tm.check())

        for case in testCases:
            t = Threat(SID="", target=default_target, condition=case["condition"])
            self.assertTrue(
                t.apply(case["target"]),
                "Failed to match {} against {}".format(
                    case["target"],
                    case["condition"],
                ),
            )
Пример #3
0
def makeBoundary(boundary_json):
    boundary_dict = copy.deepcopy(boundary_json)
    boundary = Boundary(boundary_dict.pop('name'))
    for k, v in boundary_dict.items():
        if k == 'description':
            boundary.description = v
        elif k == 'inBoundary':
            # should only do this when we have all the boundary objects in a dict. otherwise
            # this will have an error.
            continue
        elif k == 'Options':
            for option, v_ in v.items():
                replaceAttribute(boundary, option, v_)
    return boundary
Пример #4
0
    def test_duplicate_boundary_names_have_different_unique_names(self):
        random.seed(0)
        object_1 = Boundary("foo")
        object_2 = Boundary("foo")

        object_1_uniq_name = object_1._uniq_name()
        object_2_uniq_name = object_2._uniq_name()

        self.assertNotEqual(object_1_uniq_name, object_2_uniq_name)
        self.assertEqual(object_1_uniq_name, "boundary_foo_acf3059e70")
        self.assertEqual(object_2_uniq_name, "boundary_foo_88f2d9c06f")
#!/usr/bin/env python3

from pytm.pytm import TM, Server, Datastore, Dataflow, Boundary, Actor, Lambda

tm = TM("my test tm")
tm.description = "another test tm"

Web = Boundary("Internal Web")
external_web = Boundary("External Web")

user = Actor("App-y-Tenant")

app = Server("Mobile App")

buy_api = Server("Buy<br/>API-y")
buy_api.inBoundary = Web

rent_api = Server("Rent<br/>API-y")
rent_api.inBoundary = Web

alert_api = Server("Alert<br/>API-y")
alert_api.inBoundary = Web

cloud = Server("Phone Provider Cloud")
cloud.inBoundary = external_web
alert_api_to_cloud = Dataflow(alert_api, cloud, "push")
cloud_to_app = Dataflow(cloud, app, " ")

db_b = Datastore("Oracle Table B")
db_b.inBoundary = Web
buy_api_to_db = Dataflow(buy_api, db_b, " ")
Пример #6
0
#!/usr/bin/env python3

import random

from pytm.pytm import TM, Actor, Boundary, Dataflow, Datastore, Lambda, Server

# make sure generated diagrams do not change, makes sense if they're commited
random.seed(0)


tm = TM("my test tm")
tm.description = "This is a sample threat model of a very simple system - a web-based comment system. The user enters comments and these are added to a database and displayed back to the user. The thought is that it is, though simple, a complete enough example to express meaningful threats."
tm.isOrdered = True
tm.mergeResponses = True

internet = Boundary("Internet")
server_db = Boundary("Server/DB")
vpc = Boundary("AWS VPC")

user = Actor("User")
user.inBoundary = internet

web = Server("Web Server")
web.OS = "Ubuntu"
web.isHardened = True
web.sanitizesInput = False
web.encodesOutput = True
web.authorizesSource = False

db = Datastore("SQL Database")
db.OS = "CentOS"
Пример #7
0
# Data Storages
identity_db = Datastore("Identity - Mongo Atlas DB")
token_blacklist_db = Datastore("Token Blacklist DB - Mongo Atlas DB")
resources_db = Datastore("Resources - Mongo Atlas DB")
s3_bucket = Datastore("AWS S3 Bucket - Persistent")

# Monitoring
kibana = Process("Kibana Visualising Dashboard")
elastic_search_monitoring = Process("Elasticsearch Monitoring")
logstash = Process("Logstash")
heartbeat = Process("Heartbeat")
apm_server = Process("Apm Server")

# Boundraries
hosted_services = Boundary("LetterApp DMZ")
mongo_atlas = Boundary("Mongo Atlas Cluster")
aws = Boundary("AWS VPC")
external_services = Boundary("External Services")
internet = Boundary("Internet")
frontend = Boundary("Frontend")
backend = Boundary("Backend")
monitoring_vpc = Boundary("Monitoring VPC")
monitoring_vpc.inBoundary = hosted_services

# Add elements to boundraries
monitong_elements = [
    kibana, elastic_search_monitoring, logstash, heartbeat, apm_server
]
for element in monitong_elements:
    element.inBoundary = monitoring_vpc
Пример #8
0
    def test_defaults(self):
        internet = Boundary("Internet")
        cloud = Boundary("Cloud")
        user = Actor("User", inBoundary=internet)
        server = Server("Server")
        db = Datastore("DB", inBoundary=cloud)
        func = Datastore("Lambda function", inBoundary=cloud)
        request = Dataflow(user, server, "request")
        response = Dataflow(server, user, "response")
        user_query = Dataflow(user, db, "user query")
        server_query = Dataflow(server, db, "server query")
        func_query = Dataflow(func, db, "func query")

        default = {
            "SID": "",
            "description": "",
            "condition": "",
            "target": ["Actor", "Boundary", "Dataflow", "Datastore", "Server"],
            "details": "",
            "severity": "",
            "mitigations": "",
            "example": "",
            "references": "",
        }
        testCases = [
            {
                "target": server,
                "condition": "target.oneOf(Server, Datastore)"
            },
            {
                "target": server,
                "condition": "not target.oneOf(Actor, Dataflow)"
            },
            {
                "target": request,
                "condition": "target.crosses(Boundary)"
            },
            {
                "target": user_query,
                "condition": "target.crosses(Boundary)"
            },
            {
                "target": server_query,
                "condition": "target.crosses(Boundary)"
            },
            {
                "target": func_query,
                "condition": "not target.crosses(Boundary)"
            },
            {
                "target": func_query,
                "condition": "not target.enters(Boundary)"
            },
            {
                "target": func_query,
                "condition": "not target.exits(Boundary)"
            },
            {
                "target": request,
                "condition": "not target.enters(Boundary)"
            },
            {
                "target": request,
                "condition": "target.exits(Boundary)"
            },
            {
                "target": response,
                "condition": "target.enters(Boundary)"
            },
            {
                "target": response,
                "condition": "not target.exits(Boundary)"
            },
            {
                "target": user,
                "condition": "target.inside(Boundary)"
            },
        ]
        for case in testCases:
            t = Threat({**default, **{"condition": case["condition"]}})
            self.assertTrue(
                t.apply(case["target"]),
                "Failed to match {} against {}".format(case["target"],
                                                       case["condition"]),
            )
from pytm.pytm import TM, Boundary, Server, Actor, Datastore, Dataflow, SetOfProcesses

tm = TM("App-y-ness")
tm.description = "This is a sample threat model for the Threat Modeling Workshop."

internet = Boundary("Internet")

user = Actor("App-y-tenant")

app = Server("Mobile App")

buyApi = Server("Buy<br/>API-y")
buyApi.inBoundary = internet

rentApi = Server("Rent<br/>API-y")
rentApi.inBoundary = internet

market = SetOfProcesses("Market-y")
market.inBoundary = internet

alertApi = Server("Alert<br/>API-y")
alertApi.inBoundary = internet

authApi = Server("Auth<br/>API-y")
authApi.inBoundary = internet

allAuth = Server("All Auth")
allAuth.inBoundary = internet

phoneCloud = Server("Phone<br/>Provider<br/>Cloud")
Пример #10
0
# !/usr/bin/env python3

from pytm.pytm import TM, Server, Datastore, Dataflow, Boundary, Actor, Lambda, Process

tm = TM("Kubernetes Threat Model")
tm.description = "a deep-dive threat model of Kubernetes"

# Boundaries

inet = Boundary("Internet")
mcdata = Boundary("Master Control Data")
apisrv = Boundary("API Server")
mcomps = Boundary("Master Control Components")
worker = Boundary("Worker")
contain = Boundary("Container")

# Actors

miu = Actor("Malicious Internal User")
ia = Actor("Internal Attacker")
ea = Actor("External Actor")
admin = Actor("Administrator")
dev = Actor("Developer")
eu = Actor("End User")

# Server & OS Components

etcd = Datastore("N-ary etcd servers")
apiserver = Server("kube-apiserver")
kubelet = Server("kubelet")
kubeproxy = Server("kube-proxy")
Пример #11
0
#!/usr/bin/env python3

from pytm.pytm import TM, Server, Datastore, Dataflow, Boundary, Actor

tm = TM("my test tm")
tm.description = "This is a sample threat model of a very simple system - a web-based comment system. The user enters comments and these are added to a database and displayed back to the user. The thought is that it is, though simple, a complete enough example to express meaningful threats."

User_Web = Boundary("User/Web")
Web_DB = Boundary("Web/DB")

user = Actor("User")
user.inBoundary = User_Web

web = Server("Web Server")
web.OS = "CloudOS"
web.isHardened = True

db = Datastore("SQL Database (*)")
db.OS = "CentOS"
db.isHardened = False
db.inBoundary = Web_DB
db.isSql = True
db.inScope = False

user_to_web = Dataflow(user, web, "User enters comments (*)")
user_to_web.protocol = "HTTP"
user_to_web.dstPort = 80
user_to_web.data = 'Comments in HTML or Markdown'
user_to_web.order = 1
user_to_web.note = "This is a note\nmulti-line"
Пример #12
0
# !/usr/bin/env python3

from pytm.pytm import TM, Server, Datastore, Dataflow, Boundary, Actor, ExternalEntity, Process

tm = TM("Basic threat model")
tm.description = "DFD for storytelling exercise"

# Define boundaries
User = Boundary("User")
API = Boundary("Internet facing")
DB = Boundary("Database")

test = ExternalEntity("test")
test.implementsNonce = False

# Define actors
user = Actor("User")
user.inBoundary = User

# Define components
api_search = Server("api_search")
api_search.inBoundary = API
api_search.inScope = True
api_search.providesConfidentiality = True

api_reservation = Server("api_reservation")
api_reservation.inBoundary = API
api_reservation.inScope = True

api_rating = Server("api_rating")
api_rating.inBoundary = API
Пример #13
0
    def test_defaults(self):
        internet = Boundary("Internet")
        cloud = Boundary("Cloud")
        user = Actor("User", inBoundary=internet)
        server = Server("Server")
        db = Datastore("DB", inBoundary=cloud)
        func = Datastore("Lambda function", inBoundary=cloud)
        request = Dataflow(user, server, "request")
        response = Dataflow(server, user, "response")
        user_query = Dataflow(user, db, "user query")
        server_query = Dataflow(server, db, "server query")
        func_query = Dataflow(func, db, "func query")

        default_target = [
            "Actor", "Boundary", "Dataflow", "Datastore", "Server"
        ]
        testCases = [
            {
                "target": server,
                "condition": "target.oneOf(Server, Datastore)"
            },
            {
                "target": server,
                "condition": "not target.oneOf(Actor, Dataflow)"
            },
            {
                "target": request,
                "condition": "target.crosses(Boundary)"
            },
            {
                "target": user_query,
                "condition": "target.crosses(Boundary)"
            },
            {
                "target": server_query,
                "condition": "target.crosses(Boundary)"
            },
            {
                "target": func_query,
                "condition": "not target.crosses(Boundary)"
            },
            {
                "target": func_query,
                "condition": "not target.enters(Boundary)"
            },
            {
                "target": func_query,
                "condition": "not target.exits(Boundary)"
            },
            {
                "target": request,
                "condition": "not target.enters(Boundary)"
            },
            {
                "target": request,
                "condition": "target.exits(Boundary)"
            },
            {
                "target": response,
                "condition": "target.enters(Boundary)"
            },
            {
                "target": response,
                "condition": "not target.exits(Boundary)"
            },
            {
                "target": user,
                "condition": "target.inside(Boundary)"
            },
        ]
        for case in testCases:
            t = Threat(SID="",
                       target=default_target,
                       condition=case["condition"])
            self.assertTrue(
                t.apply(case["target"]),
                "Failed to match {} against {}".format(case["target"],
                                                       case["condition"]),
            )