Exemplo n.º 1
0
 def test_AC04(self):
     user = Actor("User")
     web = Server("Web Server")  
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.data = 'XML' 
     user_to_web.authorizesSource = False
     ThreatObj = Threat(next(item for item in threats_json if item["SID"] == "AC04"))
     self.assertTrue(ThreatObj.apply(user_to_web))
Exemplo n.º 2
0
 def test_DE01(self):
     user = Actor("User")
     web = Server("Web Server")  
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.protocol = 'HTTP'
     user_to_web.isEncrypted = False
     ThreatObj = Threat(next(item for item in threats_json if item["SID"] == "DE01")) 
     self.assertTrue(ThreatObj.apply(user_to_web))
Exemplo n.º 3
0
    def test_overrides(self):
        random.seed(0)

        TM.reset()
        tm = TM("my test tm", description="aaa")
        internet = Boundary("Internet")
        server_db = Boundary("Server/DB")
        user = Actor("User", inBoundary=internet, inScope=False)
        web = Server(
            "Web Server",
            overrides=[
                Finding(id="Server", response="mitigated by adding TLS"),
            ],
        )
        db = Datastore(
            "SQL Database",
            inBoundary=server_db,
            overrides=[
                Finding(id="Datastore",
                        response="accepted since inside the trust boundary"),
            ],
        )

        req = Dataflow(user, web, "User enters comments (*)")
        query = Dataflow(web, db, "Insert query with comments")
        results = Dataflow(db, web, "Retrieve comments")
        resp = Dataflow(web, user, "Show comments (*)")

        TM._threats = [
            Threat(SID="Server", target="Server", condition="False"),
            Threat(SID="Datastore", target="Datastore"),
        ]
        tm.resolve()

        self.maxDiff = None
        self.assertEqual(
            [f.id for f in tm.findings],
            ["Server", "Datastore"],
        )
        self.assertEqual([f.response for f in web.findings],
                         ["mitigated by adding TLS"])
        self.assertEqual(
            [f.response for f in db.findings],
            ["accepted since inside the trust boundary"],
        )
Exemplo n.º 4
0
 def test_CR08(self):
     user = Actor("User")
     web = Server("Web Server")
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.protocol = 'HTTP'
     user_to_web.usesLatestTLSversion = False
     ThreatObj = Threat(
         next(item for item in threats_json if item["SID"] == "CR08"))
     self.assertTrue(ThreatObj.apply(user_to_web))
Exemplo n.º 5
0
 def test_DO03(self):
     user = Actor("User")
     web = Server("Web Server")
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.protocol = "HTTP"
     xml = Data(name="user to web data", description="textual", format="XML")
     user_to_web.data = xml
     threat = threats["DO03"]
     self.assertTrue(threat.apply(user_to_web))
Exemplo n.º 6
0
 def test_AC04(self):
     user = Actor("User")
     web = Server("Web Server")
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     xml = Data(name="user to web data", description="textual", format="XML")
     user_to_web.data = xml
     user_to_web.authorizesSource = False
     threat = threats["AC04"]
     self.assertTrue(threat.apply(user_to_web))
Exemplo n.º 7
0
 def test_AC05(self):
     process1 = Process("Process1")
     web = Server("Web Server")
     process1.authenticatesDestination = False
     proc_to_web = Dataflow(process1, web, "Process calls a web API")
     proc_to_web.protocol = "HTTPS"
     proc_to_web.isEncrypted = True
     threat = threats["AC05"]
     self.assertTrue(threat.apply(proc_to_web))
Exemplo n.º 8
0
 def test_DE03(self):
     user = Actor("User")
     web = Server("Web Server")
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.protocol = "HTTP"
     user_to_web.isEncrypted = False
     user_to_web.usesVPN = False
     threat = threats["DE03"]
     self.assertTrue(threat.apply(user_to_web))
Exemplo n.º 9
0
 def test_CR06(self):
     user = Actor("User")
     web = Server("Web Server")
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.protocol = "HTTP"
     user_to_web.usesVPN = False
     user_to_web.implementsAuthenticationScheme = False
     user_to_web.authorizesSource = False
     threat = threats["CR06"]
     self.assertTrue(threat.apply(user_to_web))
Exemplo n.º 10
0
 def test_CR08(self):
     user = Actor("User")
     web = Server("Web Server")
     web.minTLSVersion = TLSVersion.TLSv11
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.protocol = "HTTPS"
     user_to_web.isEncrypted = True
     user_to_web.tlsVersion = TLSVersion.SSLv3
     threat = threats["CR08"]
     self.assertTrue(threat.apply(user_to_web))
Exemplo n.º 11
0
    def test_multilevel_dfd(self):
        random.seed(0)
        dir_path = os.path.dirname(os.path.realpath(__file__))
        install_path = os.path.dirname(os.path.realpath(pytm.__file__))

        with open(os.path.join(dir_path, "dfd_level0.txt")) as x:
            level_0 = (
                x.read().strip().replace("INSTALL_PATH", os.path.dirname(install_path))
            )
        with open(os.path.join(dir_path, "dfd_level1.txt")) as x:
            level_1 = (
                x.read().strip().replace("INSTALL_PATH", os.path.dirname(install_path))
            )

        TM.reset()
        tm = TM("my test tm", description="aaa")
        tm.isOrdered = False
        internet = Boundary("Internet")
        server_db = Boundary("Server/DB")
        user = Actor("User", inBoundary=internet, levels=0)
        web = Server("Web Server")
        db = Datastore("SQL Database", inBoundary=server_db)
        Dataflow(user, web, "User enters comments (*)", note="bbb")
        Dataflow(web, db, "Insert query with comments", note="ccc")
        Dataflow(db, web, "Retrieve comments")
        Dataflow(web, user, "Show comments (*)")

        self.assertTrue(tm.check())
        output = tm.dfd(levels={0})
        with open(os.path.join(dir_path, "0.txt"), "w") as x:
            x.write(output)
        self.assertEqual(output, level_0)

        TM.reset()
        tm = TM("my test tm", description="aaa")
        tm.isOrdered = False
        internet = Boundary("Internet")
        server_db = Boundary("Server/DB")
        user = Actor("User", inBoundary=internet, levels=1)
        web = Server("Web Server")
        db = Datastore("SQL Database", inBoundary=server_db)
        Dataflow(user, web, "User enters comments (*)", note="bbb")
        Dataflow(web, db, "Insert query with comments", note="ccc")
        Dataflow(db, web, "Retrieve comments")
        Dataflow(web, user, "Show comments (*)")

        self.assertTrue(tm.check())
        output = tm.dfd(levels={1})
        with open(os.path.join(dir_path, "1.txt"), "w") as x:
            x.write(output)
        self.maxDiff = None
        self.assertEqual(output, level_1)
Exemplo n.º 12
0
 def test_AC22(self):
     user = Actor("User")
     web = Server("Web Server")
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.data = Data("password",
                             isCredentials=True,
                             credentialsLife=Lifetime.HARDCODED)
     user_to_web.protocol = "HTTPS"
     user_to_web.isEncrypted = True
     threat = threats["AC22"]
     self.assertTrue(threat.apply(user_to_web))
Exemplo n.º 13
0
 def test_CR06(self):
     user = Actor("User")
     web = Server("Web Server")
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.protocol = 'HTTP'
     user_to_web.usesVPN = False
     user_to_web.implementsAuthenticationScheme = False
     user_to_web.authorizesSource = False
     ThreatObj = Threat(
         next(item for item in threats_json if item["SID"] == "CR06"))
     self.assertTrue(ThreatObj.apply(user_to_web))
Exemplo n.º 14
0
    def test_dfd(self):
        dir_path = os.path.dirname(os.path.realpath(__file__))
        with open(os.path.join(dir_path, "dfd.dot")) as x:
            expected = x.read().strip()

        random.seed(0)

        TM.reset()
        tm = TM("my test tm", description="aaa")
        internet = Boundary("Internet")
        net = Boundary("Company net")
        dmz = Boundary("dmz", inBoundary=net)
        backend = Boundary("backend", inBoundary=net)
        user = Actor("User", inBoundary=internet)
        gw = Server("Gateway", inBoundary=dmz)
        web = Server("Web Server", inBoundary=backend)
        db = Datastore("SQL Database", inBoundary=backend)

        Dataflow(user, gw, "User enters comments (*)")
        Dataflow(gw, web, "Request")
        Dataflow(web, db, "Insert query with comments")
        Dataflow(db, web, "Retrieve comments")
        Dataflow(web, gw, "Response")
        Dataflow(gw, user, "Show comments (*)")

        self.assertTrue(tm.check())
        output = tm.dfd()

        self.maxDiff = None
        self.assertEqual(output, expected)
Exemplo n.º 15
0
    def test_dfd_duplicates_ignore(self):
        dir_path = os.path.dirname(os.path.realpath(__file__))
        with open(os.path.join(dir_path, 'dfd.dot')) as x:
            expected = x.read().strip()

        random.seed(0)

        TM.reset()
        tm = TM("my test tm", description="aaa", onDuplicates=Action.IGNORE)
        internet = Boundary("Internet")
        server_db = Boundary("Server/DB")
        user = Actor("User", inBoundary=internet)
        web = Server("Web Server")
        db = Datastore("SQL Database", inBoundary=server_db)

        Dataflow(user, web, "User enters comments (*)")
        Dataflow(user, web, "User views comments")
        Dataflow(web, db, "Insert query with comments")
        Dataflow(web, db, "Select query")
        Dataflow(db, web, "Retrieve comments")
        Dataflow(web, user, "Show comments (*)")

        tm.check()
        output = tm.dfd()

        self.maxDiff = None
        self.assertEqual(output, expected)
Exemplo n.º 16
0
    def test_dfd_duplicates_raise(self):
        random.seed(0)

        TM.reset()
        tm = TM("my test tm", description="aaa", onDuplicates=Action.RESTRICT)
        internet = Boundary("Internet")
        server_db = Boundary("Server/DB")
        user = Actor("User", inBoundary=internet)
        web = Server("Web Server")
        db = Datastore("SQL Database", inBoundary=server_db)

        Dataflow(user, web, "User enters comments (*)")
        Dataflow(user, web, "User views comments")
        Dataflow(web, db, "Insert query with comments")
        Dataflow(web, db, "Select query")
        Dataflow(db, web, "Retrieve comments")
        Dataflow(web, user, "Show comments (*)")

        e = re.escape(
            "Duplicate Dataflow found between Actor(User) "
            "and Server(Web Server): Dataflow(User enters comments (*)) "
            "is same as Dataflow(User views comments)"
        )
        with self.assertRaisesRegex(ValueError, e):
            tm.check()
Exemplo n.º 17
0
    def test_report(self):
        random.seed(0)
        dir_path = os.path.dirname(os.path.realpath(__file__))
        with open(os.path.join(dir_path, "output.md")) as x:
            expected = x.read().strip()

        TM.reset()
        tm = TM("my test tm",
                description="aaa",
                threatsFile="pytm/threatlib/threats.json")
        tm.isOrdered = True
        internet = Boundary("Internet")
        server_db = Boundary("Server/DB")
        user = Actor("User", inBoundary=internet)
        web = Server("Web Server")
        func = Lambda("Lambda func")
        worker = Process("Task queue worker")
        db = Datastore("SQL Database", inBoundary=server_db)

        Dataflow(user,
                 web,
                 "User enters comments (*)",
                 note="bbb",
                 data="auth cookie")
        Dataflow(web, db, "Insert query with comments", note="ccc")
        Dataflow(web, func, "Call func")
        Dataflow(db, web, "Retrieve comments")
        Dataflow(web, user, "Show comments (*)")
        Dataflow(worker, db, "Query for tasks")

        self.assertTrue(tm.check())
        output = tm.report("docs/template.md")

        self.maxDiff = None
        self.assertEqual(output.strip(), expected.strip())
Exemplo n.º 18
0
 def test_AC10(self):
     user = Actor("User")
     web = Server("Web Server")
     web.minTLSVersion = TLSVersion.TLSv11
     web.implementsAuthenticationScheme = False
     web.authorizesSource = False
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.protocol = "HTTPS"
     user_to_web.isEncrypted = True
     user_to_web.tlsVersion = TLSVersion.SSLv3
     web.inputs = [user_to_web]
     threat = threats["AC10"]
     self.assertTrue(threat.apply(web))
Exemplo n.º 19
0
 def create_dataflow(
     source=Classification.RESTRICTED,
     sink=Classification.RESTRICTED,
     dataflow=Classification.RESTRICTED,
     data=Classification.RESTRICTED,
     define_data=True,
 ):
     source_ = Server("Source", maxClassification=source)
     sink_ = Datastore("Sink", maxClassification=sink)
     flow_ = Dataflow(source_, sink_, "Flow", maxClassification=dataflow)
     if define_data:
         flow_.data = Data("Data", classification=data)
     return flow_
Exemplo n.º 20
0
 def test_CR01(self):
     user = Actor("User")
     web = Server("Web Server")
     web.protocol = "HTTP"
     web.usesVPN = False
     web.usesSessionTokens = True
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.protocol = "HTTP"
     user_to_web.usesVPN = False
     user_to_web.usesSessionTokens = True
     threat = threats["CR01"]
     self.assertTrue(threat.apply(web))
     self.assertTrue(threat.apply(user_to_web))
Exemplo n.º 21
0
 def test_CR01(self):
     user = Actor("User")
     web = Server("Web Server")
     web.protocol = 'HTTP'
     web.usesVPN = False
     web.usesSessionTokens = True
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.protocol = 'HTTP'
     user_to_web.usesVPN = False
     user_to_web.usesSessionTokens = True
     ThreatObj = Threat(next(item for item in threats_json if item["SID"] == "CR01"))
     self.assertTrue(ThreatObj.apply(web))
     self.assertTrue(ThreatObj.apply(user_to_web))
Exemplo n.º 22
0
    def test_resolve(self):
        random.seed(0)

        TM.reset()
        tm = TM("my test tm", description="aaa")
        internet = Boundary("Internet")
        server_db = Boundary("Server/DB")
        user = Actor("User", inBoundary=internet, inScope=False)
        web = Server("Web Server")
        db = Datastore("SQL Database", inBoundary=server_db)

        req = Dataflow(user, web, "User enters comments (*)")
        query = Dataflow(web, db, "Insert query with comments")
        results = Dataflow(db, web, "Retrieve comments")
        resp = Dataflow(web, user, "Show comments (*)")

        TM._threats = [
            Threat(SID=klass, target=klass)
            for klass in ["Actor", "Server", "Datastore", "Dataflow"]
        ]
        tm.resolve()

        self.maxDiff = None
        self.assertEqual(
            [f.id for f in tm.findings],
            [
                "Server", "Datastore", "Dataflow", "Dataflow", "Dataflow",
                "Dataflow"
            ],
        )
        self.assertEqual([f.id for f in user.findings], [])
        self.assertEqual([f.id for f in web.findings], ["Server"])
        self.assertEqual([f.id for f in db.findings], ["Datastore"])
        self.assertEqual([f.id for f in req.findings], ["Dataflow"])
        self.assertEqual([f.id for f in query.findings], ["Dataflow"])
        self.assertEqual([f.id for f in results.findings], ["Dataflow"])
        self.assertEqual([f.id for f in resp.findings], ["Dataflow"])
Exemplo n.º 23
0
 def test_CR02(self):
     user = Actor("User")
     web = Server("Web Server")
     web.protocol = 'HTTP'
     web.sanitizesInput = False
     web.validatesInput = False
     web.usesSessionTokens = True
     user_to_web = Dataflow(user, web, "User enters comments (*)")
     user_to_web.protocol = 'HTTP'
     user_to_web.sanitizesInput = False
     user_to_web.validatesInput = False
     user_to_web.usesSessionTokens = True
     threat = threats["CR02"]
     self.assertTrue(threat.apply(web))
     self.assertTrue(threat.apply(user_to_web))
Exemplo n.º 24
0
    def test_json_dumps(self):
        random.seed(0)
        dir_path = os.path.dirname(os.path.realpath(__file__))
        with open(os.path.join(dir_path, "output.json")) as x:
            expected = x.read().strip()
        TM.reset()
        tm = TM("my test tm",
                description="aaa",
                threatsFile="pytm/threatlib/threats.json")
        tm.isOrdered = True
        internet = Boundary("Internet")
        server_db = Boundary("Server/DB")
        user = Actor("User", inBoundary=internet)
        web = Server("Web Server")
        func = Lambda("Lambda func")
        worker = Process("Task queue worker")
        db = Datastore("SQL Database", inBoundary=server_db)

        cookie = Data(
            name="auth cookie",
            description="auth cookie description",
            classification=Classification.PUBLIC,
        )
        Dataflow(user,
                 web,
                 "User enters comments (*)",
                 note="bbb",
                 data=cookie)
        Dataflow(web, db, "Insert query with comments", note="ccc")
        Dataflow(web, func, "Call func")
        Dataflow(db, web, "Retrieve comments")
        Dataflow(web, user, "Show comments (*)")
        Dataflow(worker, db, "Query for tasks")

        self.assertTrue(tm.check())
        output = json.dumps(tm,
                            default=to_serializable,
                            sort_keys=True,
                            indent=4)

        with open(os.path.join(dir_path, "output_current.json"), "w") as x:
            x.write(output)

        self.maxDiff = None
        self.assertEqual(output, expected)
Exemplo n.º 25
0
secretDb.sourceFiles = ["pytm/pytm.py"]
secretDb.isHardened = True
secretDb.inBoundary = server_db
secretDb.isSQL = True
secretDb.inScope = True
secretDb.storesPII = True
secretDb.maxClassification = Classification.TOP_SECRET

my_lambda = Lambda("AWS Lambda")
my_lambda.hasAccessControl = True
my_lambda.inBoundary = vpc
my_lambda.levels = [1, 2]

token_user_identity = Data("Token verifying user identity",
                           classification=Classification.SECRET)
db_to_secretDb = Dataflow(db, secretDb, "Database verify real user identity")
db_to_secretDb.protocol = "RDA-TCP"
db_to_secretDb.dstPort = 40234
db_to_secretDb.data = token_user_identity
db_to_secretDb.note = "Verifying that the user is who they say they are."
db_to_secretDb.maxClassification = Classification.SECRET

comments_in_text = Data("Comments in HTML or Markdown",
                        classification=Classification.PUBLIC)
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_text
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")
Exemplo n.º 26
0
merchant_web = Server("Merchant Web Server")
merchant_web.inBoundary = Merchant_Web
merchant_web.OS = "Ubuntu"
merchant_web.isHardened = True
merchant_web.onAWS = True
# web.levels = [2]

stripe_api = ExternalEntity("Stripe API service")
stripe_api.inBoundary = Stripe_API
stripe_api.onAWS = False

stripe_process = Process("Stripe Payment Service")
stripe_process.inBoundary = Stripe_API

customer_to_customer_client = Dataflow(
    customer, customer_client, "Customer logs into the merchant site (*)")
customer_to_customer_client.protocol = "HTTPS"
customer_to_customer_client.dstPort = 443
customer_to_customer_client.data = 'OAuth'

customer_to_customer_client = Dataflow(
    customer, customer_client,
    "Customer proceeds to payment page to make a purchase (*)")
customer_to_customer_client.protocol = "HTTPS"
customer_to_customer_client.dstPort = 443

customer_client_to_merchant_web = Dataflow(
    customer_client, merchant_web,
    "Customer Client sends order intent, including order amount (*)")
customer_client_to_merchant_web.protocol = "HTTPS"
customer_client_to_merchant_web.dstPort = 443
Exemplo n.º 27
0
web.OS = "CloudOS"
web.isHardened = True

my_lambda = Lambda("cleanDBevery6hours")
my_lambda.hasAccessControl = True
my_lambda.inBoundary = Web_DB
#my_lambda.inBoundary = VPC  #  TODO: need multiple boundaries capability for these situations

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

my_lambda_to_db = Dataflow(my_lambda, db, "(λ)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
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
Exemplo n.º 28
0
Arquivo: tm.py Projeto: 321jr/pytm
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'
Exemplo n.º 29
0
redis.isHardened = True
redis.inBoundary = apps_vpc
redis.inBoundary = cache_boundary
redis.isSQL = False
redis.inScope = True
db.onAWS = True
db.isShared = False
db.storesSensitiveData = False

third_party = Element("3rd party services")
third_party.inBoundary = internet

third_party_bim = Element("3rd party BIM360 services")
third_party_bim.inBoundary = internet

user_to_apigee = Dataflow(user, apigee,
                          "User sends API request to Apps service")
user_to_apigee.protocol = "HTTPS"
user_to_apigee.isEncrypted = True
user_to_apigee.authenticatedWith = True
user_to_apigee.dstPort = 443
user_to_apigee.data = 'JSON'
user_to_apigee.order = 1

apigee_to_server = Dataflow(apigee, server,
                            "Apigee forwards API request to Apps server")
apigee_to_server.protocol = "HTTPS"
apigee_to_server.isEncrypted = True
apigee_to_server.authenticatedWith = True
apigee_to_server.dstPort = 443
apigee_to_server.data = 'JSON'
apigee_to_server.order = 2