예제 #1
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)
예제 #2
0
    def test_defaults(self):
        tm = TM("TM")
        user_data = Data("HTTP")
        user = Actor("User", data=user_data)
        user.controls.authenticatesDestination=True

        json_data = Data("JSON")
        server = Server(
            "Server", port=443, protocol="HTTPS", isEncrypted=True, data=json_data
        )
        sql_resp = Data("SQL resp")
        db = Datastore(
            "PostgreSQL",
            port=5432,
            protocol="PostgreSQL",
            data=sql_resp,
        )
        db.controls.isEncrypted=False
        db.type = DatastoreType.SQL
        worker = Process("Task queue worker")

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

        req_post_data = Data("JSON")
        req_post = Dataflow(user, server, "HTTP POST", data=req_post_data)
        resp_post = Dataflow(server, user, "HTTP Response", isResponse=True)
        
        sql_data = Data("SQL")
        worker_query = Dataflow(worker, db, "Query", data=sql_data)
        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.controls.isEncrypted, server.controls.isEncrypted)
        self.assertEqual(
            req_get.controls.authenticatesDestination, user.controls.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.controls.isEncrypted, db.controls.isEncrypted)
        self.assertEqual(
            server_query.controls.authenticatesDestination, server.controls.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.controls.isEncrypted, db.controls.isEncrypted)
        self.assertEqual(result.controls.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.controls.isEncrypted, server.controls.isEncrypted)
        self.assertEqual(resp_get.controls.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.controls.isEncrypted, server.controls.isEncrypted)
        self.assertEqual(
            req_post.controls.authenticatesDestination, user.controls.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.controls.isEncrypted, server.controls.isEncrypted)
        self.assertEqual(resp_post.controls.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"])
        )
예제 #3
0
파일: tm.py 프로젝트: luisfalconeri/pytm
# Servers
eureka_service_discovery = Server("Eureka Service Discovery")
nginx_backend_server = Server("Nginx Backend Reverse Proxy and Load Balancer")

# Processes
react_webapp = Process("Webserver - React Frontend")

identity_service = Process("Flask Identity Service")
image_service = Process("Flask Image Service")
resources_service = Process("Flask Resouces Service")
search_service = Process("Flask Search Service")

elastic_search_resources = Process("Flask Elastic Search Resources")

# 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")
예제 #4
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)

        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.assertEqual(req_get.data, user.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.assertNotEqual(server_query.data, server.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.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.authenticatesDestination, False)
        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.authenticatesDestination,
                         user.authenticatesDestination)
        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.authenticatesDestination, False)
        self.assertEqual(resp_post.protocol, server.protocol)
        self.assertEqual(resp_post.data, server.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])
예제 #5
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"]),
            )
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")

firensurfCloud = Server("Fire n' Surf .gov")

dbB = Datastore("Oracle Table B")
dbB.inBoundary = internet

dbR = Datastore("Oracle Table R")
dbR.inBoundary = internet

dbT = Datastore("Oracle Table T")
dbT.inBoundary = internet

user_to_app = Dataflow(user, app, "use")
app_to_buyapi = Dataflow(app, buyApi, "HTTPS<br/>JSON")
app_to_phonecloud = Dataflow(app, phoneCloud, " ")
app_to_rentapi = Dataflow(app, rentApi, "HTTPS<br/>JSON")
app_to_authapi = Dataflow(app, authApi, "HTTPS<br/>JSON")
app_to_dbt = Dataflow(authApi, dbT, "Token-y")
allauth_to_dbt = Dataflow(allAuth, dbT, " ")
예제 #7
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, isSQL=True)
        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.isSQL "
                "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"],
                ),
            )
예제 #8
0
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")
scheduler = Server("kube-scheduler")
controllers = Server("CCM/KCM")
pods = Server("Pods")
iptables = Process("iptables")

# Component <> Boundary Relations
etcd.inBoundary = mcdata
mcdata.inBoundary = apisrv
apiserver.inBoundary = apisrv
kubelet.inBoundary = worker
kubeproxy.inBoundary = worker
pods.inBoundary = contain
예제 #9
0
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"

web_to_user = Dataflow(web, user, "Comments saved (*)")
web_to_user.protocol = "HTTP"
예제 #10
0
# 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
api_rating.inScope = True

db_search = Datastore("Restaurants")
db_search.inBoundary = DB
db_search.inScope = True
db_search.authenticatesSource = True

db_rating = Datastore("Ratings")
db_rating.inBoundary = DB
db_rating.inScope = False

db_reservations = Datastore("Reservations")
db_reservations.inBoundary = DB
db_reservations.inScope = False

# Define flows
search_user_to_api = Dataflow(user, api_search, "User enters search")
search_user_to_api.isEncrypted = True #JIRA TEST-0001
예제 #11
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"]),
            )
예제 #12
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()