Example #1
0
    def test_responses(self):
        tm = TM("my test tm", description="aa", isOrdered=True)

        user = Actor("User")
        web = Server("Web Server")
        db = Datastore("SQL Database")

        http_req = Dataflow(user, web, "http req")
        insert = Dataflow(web, db, "insert data")
        query = Dataflow(web, db, "query")
        query_resp = Dataflow(db, web, "query results", responseTo=query)
        http_resp = Dataflow(web, user, "http resp")
        http_resp.responseTo = http_req

        self.assertTrue(tm.check())

        self.assertEqual(http_req.response, http_resp)
        self.assertIs(http_resp.isResponse, True)

        self.assertIs(query_resp.isResponse, True)
        self.assertEqual(query_resp.responseTo, query)
        self.assertEqual(query.response, query_resp)

        self.assertIsNone(insert.response)
        self.assertIs(insert.isResponse, False)
Example #2
0
    def test_load_threats(self):
        tm = TM("TM")
        self.assertNotEqual(len(TM._threats), 0)
        with self.assertRaises(FileNotFoundError):
            tm.threatsFile = "threats.json"

        with self.assertRaises(FileNotFoundError):
            TM("TM", threatsFile="threats.json")
Example #3
0
class ThreatModel:
    def __init__(self, name, description="My TM", isOrdered=True, mergeResponses=True):
        self.tm = TM(name)
        self.tm.description=description
        self.tm.isOrdered = isOrdered
        self.tm.mergeResponses = mergeResponses

    def start(self):
        self.tm.process()
Example #4
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"],
                ),
            )
#!/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, " ")
Example #6
0
    def test_defaults(self):
        tm = TM("TM")
        user = Actor("User", data="HTTP", authenticatesDestination=True)
        server = Server("Server",
                        port=443,
                        protocol="HTTPS",
                        isEncrypted=True,
                        data="JSON")
        db = Datastore(
            "PostgreSQL",
            isSQL=True,
            port=5432,
            protocol="PostgreSQL",
            isEncrypted=False,
            data="SQL resp",
        )
        worker = Process("Task queue worker")

        req_get = Dataflow(user, server, "HTTP GET")
        server_query = Dataflow(server, db, "Query", data="SQL")
        result = Dataflow(db, server, "Results", isResponse=True)
        resp_get = Dataflow(server, user, "HTTP Response", isResponse=True)

        req_post = Dataflow(user, server, "HTTP POST", data="JSON")
        resp_post = Dataflow(server, user, "HTTP Response", isResponse=True)

        worker_query = Dataflow(worker, db, "Query", data="SQL")
        Dataflow(db, worker, "Results", isResponse=True)

        cookie = Data("Auth Cookie", carriedBy=[req_get, req_post])

        self.assertTrue(tm.check())

        self.assertEqual(req_get.srcPort, -1)
        self.assertEqual(req_get.dstPort, server.port)
        self.assertEqual(req_get.isEncrypted, server.isEncrypted)
        self.assertEqual(req_get.authenticatesDestination,
                         user.authenticatesDestination)
        self.assertEqual(req_get.protocol, server.protocol)
        self.assertTrue(user.data.issubset(req_get.data))

        self.assertEqual(server_query.srcPort, -1)
        self.assertEqual(server_query.dstPort, db.port)
        self.assertEqual(server_query.isEncrypted, db.isEncrypted)
        self.assertEqual(server_query.authenticatesDestination,
                         server.authenticatesDestination)
        self.assertEqual(server_query.protocol, db.protocol)
        self.assertTrue(server.data.issubset(server_query.data))

        self.assertEqual(result.srcPort, db.port)
        self.assertEqual(result.dstPort, -1)
        self.assertEqual(result.isEncrypted, db.isEncrypted)
        self.assertEqual(result.authenticatesDestination, False)
        self.assertEqual(result.protocol, db.protocol)
        self.assertTrue(db.data.issubset(result.data))

        self.assertEqual(resp_get.srcPort, server.port)
        self.assertEqual(resp_get.dstPort, -1)
        self.assertEqual(resp_get.isEncrypted, server.isEncrypted)
        self.assertEqual(resp_get.authenticatesDestination, False)
        self.assertEqual(resp_get.protocol, server.protocol)
        self.assertTrue(server.data.issubset(resp_get.data))

        self.assertEqual(req_post.srcPort, -1)
        self.assertEqual(req_post.dstPort, server.port)
        self.assertEqual(req_post.isEncrypted, server.isEncrypted)
        self.assertEqual(req_post.authenticatesDestination,
                         user.authenticatesDestination)
        self.assertEqual(req_post.protocol, server.protocol)
        self.assertTrue(user.data.issubset(req_post.data))

        self.assertEqual(resp_post.srcPort, server.port)
        self.assertEqual(resp_post.dstPort, -1)
        self.assertEqual(resp_post.isEncrypted, server.isEncrypted)
        self.assertEqual(resp_post.authenticatesDestination, False)
        self.assertEqual(resp_post.protocol, server.protocol)
        self.assertTrue(server.data.issubset(resp_post.data))

        self.assertListEqual(server.inputs, [req_get, req_post])
        self.assertListEqual(server.outputs, [server_query])
        self.assertListEqual(worker.inputs, [])
        self.assertListEqual(worker.outputs, [worker_query])

        self.assertListEqual(cookie.carriedBy, [req_get, req_post])
        self.assertSetEqual(set(cookie.processedBy), set([user, server]))
        self.assertIn(cookie, req_get.data)
        self.assertSetEqual(set([d.name for d in req_post.data]),
                            set([cookie.name, "HTTP", "JSON"]))
Example #7
0
 def __init__(self, name, description="My TM", isOrdered=True, mergeResponses=True):
     self.tm = TM(name)
     self.tm.description=description
     self.tm.isOrdered = isOrdered
     self.tm.mergeResponses = mergeResponses
Example #8
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"
Example #9
0
    def test_defaults(self):
        tm = TM("TM")
        user = Actor("User", data="HTTP")
        server = Server("Server",
                        port=443,
                        protocol="HTTPS",
                        isEncrypted=True,
                        data="JSON")
        db = Datastore(
            "PostgreSQL",
            isSQL=True,
            port=5432,
            protocol="PostgreSQL",
            isEncrypted=False,
            data="SQL resp",
        )

        req_get = Dataflow(user, server, "HTTP GET")
        query = Dataflow(server, db, "Query", data="SQL")
        result = Dataflow(db, server, "Results", isResponse=True)
        resp_get = Dataflow(server, user, "HTTP Response", isResponse=True)

        req_post = Dataflow(user, server, "HTTP POST", data="JSON")
        resp_post = Dataflow(server, user, "HTTP Response", isResponse=True)

        tm.check()

        self.assertEqual(req_get.srcPort, -1)
        self.assertEqual(req_get.dstPort, server.port)
        self.assertEqual(req_get.isEncrypted, server.isEncrypted)
        self.assertEqual(req_get.protocol, server.protocol)
        self.assertEqual(req_get.data, user.data)

        self.assertEqual(query.srcPort, -1)
        self.assertEqual(query.dstPort, db.port)
        self.assertEqual(query.isEncrypted, db.isEncrypted)
        self.assertEqual(query.protocol, db.protocol)
        self.assertNotEqual(query.data, server.data)

        self.assertEqual(result.srcPort, db.port)
        self.assertEqual(result.dstPort, -1)
        self.assertEqual(result.isEncrypted, db.isEncrypted)
        self.assertEqual(result.protocol, db.protocol)
        self.assertEqual(result.data, db.data)

        self.assertEqual(resp_get.srcPort, server.port)
        self.assertEqual(resp_get.dstPort, -1)
        self.assertEqual(resp_get.isEncrypted, server.isEncrypted)
        self.assertEqual(resp_get.protocol, server.protocol)
        self.assertEqual(resp_get.data, server.data)

        self.assertEqual(req_post.srcPort, -1)
        self.assertEqual(req_post.dstPort, server.port)
        self.assertEqual(req_post.isEncrypted, server.isEncrypted)
        self.assertEqual(req_post.protocol, server.protocol)
        self.assertNotEqual(req_post.data, user.data)

        self.assertEqual(resp_post.srcPort, server.port)
        self.assertEqual(resp_post.dstPort, -1)
        self.assertEqual(resp_post.isEncrypted, server.isEncrypted)
        self.assertEqual(resp_post.protocol, server.protocol)
        self.assertEqual(resp_post.data, server.data)
Example #10
0
#!/usr/bin/env python3

# TM, Element, Server, ExternalEntity, Datastore, Actor, Process, SetOfProcesses, Dataflow, Boundary and Lambda.

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

tm = TM("LetterApp flow diagram")
tm.description = """LetterApp is a cloud-based and machine learning-powered document-management 
                    and workflow system which allow users to upload documents and access 
                    them from a Web client and a mobile client, as well as programtically 
                    through a group of Restful API's. Besides making the documents avaiable 
                    across devices, it also allows for flow management - users can group, tag, 
                    and track activities related to each document. Computer vision helps users
                    with automatic tagging and entity extraction. Users can also send letters, 
                    faxes na messages straight from the app. Since the nature of the data stored 
                    is sensitve, security is of heightened importance for the app's development."""

tm.isOrdered = True
tm.mergeResponses = True
tm

#Actors
#TODO add mobile client?  programtic user? anonymous user?
#External Entities - out of control
#Sendgrid

#External Entities / Processes / Actors
web_user = ExternalEntity('Web User')
administrator = ExternalEntity('Administrator')
mobile_client = ExternalEntity("Mobile Client")
direct_api = ExternalEntity("API programatic access")
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")
Example #12
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")
Example #13
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
Example #14
0
from pytm.pytm import TM, Boundary, Server, Actor, Datastore, Dataflow, SetOfProcesses

tm = TM("Generic CMS example")
tm.description = "This is a sample threat model for the Threat Model Cookbook."

internet = Boundary("Internet")

user = Actor("Generic/Privilege User")

webserver = Server("Web Server")
webserver.inBoundary = internet

user_to_webserver = Dataflow(user, webserver, "HTTPS")

db = Datastore("db")
db.inBoundary = internet
db_to_webserver = Dataflow(webserver, db, " ")

adminuser = Actor(" admin ")
admin_to_webserver = Dataflow(adminuser, db,
                              "unsecure<br/>mysql<br/>connection")

cdn = SetOfProcesses("CDN network")
user_to_cdn = Dataflow(user, cdn, "HTTP")
webserver_to_cdn = Dataflow(webserver, cdn, "Push to Bucket")

tm.process()