示例#1
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"],
                ),
            )
示例#2
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)
示例#3
0
def makeDataflow(dataflow_json, componentObj, boundaryObj):
    name = dataflow_json.pop('name')
    if dataflow_json['source'] is not '' and dataflow_json['sink'] is not '':
        src = componentObj[dataflow_json.pop('source')]
        sink = componentObj[dataflow_json.pop('sink')]
    else:
        return None
    dataflow = Dataflow(src, sink, name)
    for k,v in dataflow_json.items():
        if k == 'Options':
            for option, v_ in v.items():
                replaceAttribute(dataflow, option, v_)
        else:
            if k == 'inBoundary':
                continue
            elif k == 'inBoundary' and v is not '':
                dataflow.inBoundary = boundaryObj[v]
                continue
            replaceAttribute(dataflow, k, v)

    return dataflow
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, " ")

db_r = Datastore("Oracle Table R")
db_r.inBoundary = Web
rent_api_to_db = Dataflow(rent_api, db_r, " ")

db_t = Datastore("Oracle Table Tenants")
db_t.inBoundary = Web
rent_api_to_db_t = Dataflow(rent_api, db_t, " ")
buy_api_to_db_t = Dataflow(buy_api, db_t, " ")
alert_api_to_db_t = Dataflow(alert_api, db_t, " ")
示例#5
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"]))
示例#6
0
web.sanitizesInput = False
web.encodesOutput = True
web.authorizesSource = False

db = Datastore("SQL Database")
db.OS = "CentOS"
db.isHardened = False
db.inBoundary = server_db
db.isSQL = True
db.inScope = True

my_lambda = Lambda("AWS Lambda")
my_lambda.hasAccessControl = True
my_lambda.inBoundary = vpc

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.note = "This is a simple web app\nthat stores and retrieves user comments."

web_to_db = Dataflow(web, db, "Insert query with comments")
web_to_db.protocol = "MySQL"
web_to_db.dstPort = 3306
web_to_db.data = 'MySQL insert statement, all literals'
web_to_db.note = "Web server inserts user comments\ninto it's SQL query and stores them in the DB."

db_to_web = Dataflow(db, web, "Retrieve comments")
db_to_web.protocol = "MySQL"
db_to_web.dstPort = 80
db_to_web.data = 'Web server retrieves comments from DB'
示例#7
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)
示例#8
0
文件: tm.py 项目: luisfalconeri/pytm
    service.inBoundary = hosted_services

aws_services = [s3_bucket]
for service in aws_services:
    service.inBoundary = aws

mongo_services = [identity_db, token_blacklist_db, resources_db]
for service in mongo_services:
    service.inBoundary = mongo_atlas
sendgrid.inBoundary = external_services
#TODO
# aws.inBoundary = external_services
# mongo_atlas.inBoundary = external_services

# Dataflows
user_browser = Dataflow(web_user, browser, "User Accesing Webapp")
browser_user = Dataflow(browser, web_user, "Responses to user")
browser_user.responseTo = user_browser

browser_webserver = Dataflow(browser, react_webapp, "User Accesing Webapp")
webserver_browser = Dataflow(react_webapp, browser, "Responses to user")
webserver_browser.responseTo = browser_webserver

for entity in [browser, mobile_client, direct_api]:
    to_webserver = Dataflow(entity, nginx_backend_server,
                            "{} acessing api".format(entity.name))
    from_webserver = Dataflow(nginx_backend_server, entity,
                              "Responses to {}".format(entity.name))
    from_webserver.responseTo = to_webserver

# web_user
示例#9
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"]),
            )
示例#10
0
kubeproxy.inBoundary = worker
pods.inBoundary = contain
scheduler.inBoundary = mcomps
controllers.inBoundary = mcomps
pods.inBoundary = contain
iptables.inBoundary = worker
miu.inBoundary = apisrv
ia.inBoundary = contain
ea.inBoundary = inet
admin.inBoundary = apisrv
dev.inBoundary = inet
eu.inBoundary = inet

# Dataflows

apiserver2etcd = Dataflow(apiserver, etcd, "All kube-apiserver data")
apiserver2etcd.isEncrypted = True
apiserver2etcd.protocol = "HTTPS"

apiserver2kubelet = Dataflow(apiserver, kubelet,
                             "kubelet Health, Status, &amp;c.")
apiserver2kubelet.isEncrypted = False
apiserver2kubelet.protocol = "HTTP"

apiserver2kubeproxy = Dataflow(apiserver, kubeproxy,
                               "kube-proxy Health, Status, &amp;c.")
apiserver2kubeproxy.isEncrypted = False
apiserver2kubeproxy.protocol = "HTTP"

apiserver2scheduler = Dataflow(apiserver, scheduler,
                               "kube-scheduler Health, Status, &amp;c.")
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, " ")
buyapi_to_dbt = Dataflow(buyApi, dbT, " ")
buyapi_to_market = Dataflow(buyApi, market, " ")
rentapi_to_dbr = Dataflow(rentApi, dbR, " ")
rentapi_to_dbb = Dataflow(buyApi, dbB, " ")
rentapi_to_market = Dataflow(rentApi, market, " ")
alert_to_phonecloud = Dataflow(alertApi, phoneCloud, "push")
alert_to_firensurf = Dataflow(alertApi, firensurfCloud, "Kafka<br/>HTTPS")
firensurf_to_alert = Dataflow(firensurfCloud, alertApi, "push")
buyapi_to_phonecloud = Dataflow(buyApi, phoneCloud, " ")
示例#12
0
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"
web_to_user.data = 'Ack of saving or error message, in JSON'
web_to_user.order = 2

web_to_db = Dataflow(web, db, "Insert query with comments")
web_to_db.protocol = "MySQL"
web_to_db.dstPort = 3306
web_to_db.data = 'MySQL insert statement, all literals'
示例#13
0
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
search_user_to_api.order =1
search_api_to_db = Dataflow(api_search, db_search, "Search critirea")
search_api_to_db.order = 2
search_db_to_api = Dataflow(db_search, api_search, "Results")
search_db_to_api.order = 3
search_api_to_user = Dataflow(api_search, user, "Results")
search_api_to_user.order = 4

reservation_user_to_api = Dataflow(user, api_reservation, "User enters reservation")
reservation_user_to_api.isEncrypted = True
reservation_user_to_api.order =5
reservation_api_to_db = Dataflow(api_reservation, db_reservations, "Check availability")
reservation_api_to_db.order = 6
reservation_db_to_api = Dataflow(db_reservations, api_reservation, "Returns availability")
示例#14
0
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
web.

my_lambda = Lambda("cleanDBevery6hours")
my_lambda.hasAccessControl = True
my_lambda.inBoundary = Web_DB

my_lambda_to_db = Dataflow(my_lambda, db, "(&lambda;)Periodically cleans DB")
my_lambda_to_db.protocol = "SQL"
my_lambda_to_db.dstPort = 3306

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

web_to_user = Dataflow(web, user, "Comments saved (*)")
web_to_user.protocol = "HTTP"
web_to_user.data = 'Ack of saving or error message, in JSON'
web_to_user.order = 2

web_to_db = Dataflow(web, db, "Insert query with comments")
示例#15
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"]),
            )
示例#16
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()