Пример #1
0
    def execute(self):
        # Some CVE does not have CVSS, or they just have one version
        # Check the old values
        old = {}
        if self.cve_obj.cvss2:
            old["v2"] = self.cve_obj.cvss2
        if self.cve_obj.cvss3:
            old["v3"] = self.cve_obj.cvss3

        # Check the new values
        new = {}
        if "baseMetricV2" in self.cve_json["impact"]:
            new["v2"] = self.cve_json["impact"]["baseMetricV2"]["cvssV2"][
                "baseScore"]
        if "baseMetricV3" in self.cve_json["impact"]:
            new["v3"] = self.cve_json["impact"]["baseMetricV3"]["cvssV3"][
                "baseScore"]

        # If at least one version has changed, update the CVE
        if old != new:
            self.cve_obj.cvss2 = new.get("v2")
            self.cve_obj.cvss3 = new.get("v3")
            db.session.commit()

            # Create the event with the CVSS changes
            event = CveUtil.create_event(self.cve_obj, self.cve_json, "cvss", {
                "old": old,
                "new": new
            })
            return event

        return None
Пример #2
0
def test_filter_events_first_time(create_user, create_cve, create_vendor,
                                  open_file):
    cve = create_cve("CVE-2018-18074")
    event = CveUtil.create_event(
        cve,
        open_file(f"modified_cves/CVE-2018-18074_first_time_1.json")[0],
        "first_time",
        ["opencveio", "opencveio$PRODUCT$opencveio"],
    )

    # User1 doesn't have the first_time type
    user1 = create_user("user1")
    user1.filters_notifications = {"cvss": 0, "event_types": ["summary"]}
    db.session.commit()
    assert filter_events(user1, [event]) == []

    # User2 hasn't subscribed to opencve vendor
    user2 = create_user("user2")
    vendor = create_vendor("not_existing")
    user2.vendors.append(vendor)
    db.session.commit()
    assert filter_events(user2, [event]) == []

    # User3 has subscribed to opencve vendor
    user3 = create_user("user3")
    vendor = create_vendor("opencveio")
    user3.vendors.append(vendor)
    db.session.commit()
    assert filter_events(user3, [event]) == [event]
Пример #3
0
def test_create_change(open_file):
    task = Task()
    db.session.add(task)
    db.session.commit()

    cve_json = open_file("cves/CVE-2020-26116.json")
    cve = CveUtil.create_cve(cve_json)

    change = CveUtil.create_change(cve, cve_json, task, [])
    assert Change.query.first().id == change.id

    assert change.json == cve_json
    assert change.cve_id == cve.id
    assert change.cve.id == cve.id
    assert change.task_id == task.id
    assert change.task.id == task.id
    assert change.events == []
Пример #4
0
    def execute(self):
        old = flatten_vendors(convert_cpes(
            self.cve_obj.json["configurations"]))
        new = flatten_vendors(convert_cpes(self.cve_json["configurations"]))
        payload = list(set(new) - set(old))

        if payload:
            event = CveUtil.create_event(self.cve_obj, self.cve_json,
                                         "first_time", payload)
            return event

        return None
Пример #5
0
def test_create_cve(app, open_file):
    cve = CveUtil.create_cve(open_file("cves/CVE-2020-26116.json"))

    cves = Cve.query.all()
    assert len(cves) == 1

    # The CVE has been created
    assert cve.id == cves[0].id
    assert cve.cve_id == "CVE-2020-26116"
    assert cve.cwes == ["CWE-116"]
    assert sorted(cve.vendors) == sorted(
        [
            "fedoraproject",
            f"fedoraproject{PRODUCT_SEPARATOR}fedora",
            "python",
            f"python{PRODUCT_SEPARATOR}python",
        ]
    )
    assert (
        cve.summary
        == "http.client in Python 3.x before 3.5.10, 3.6.x before 3.6.12, 3.7.x before 3.7.9, and 3.8.x before 3.8.5 allows CRLF injection if the attacker controls the HTTP request method, as demonstrated by inserting CR and LF control characters in the first argument of HTTPConnection.request."
    )
    assert cve.cvss2 == 6.4
    assert cve.cvss3 == 7.2
    assert cve.events == []
    assert cve.changes == []
    assert cve.alerts == []
    assert round(cve.cvss_weight, 1) == 13.6

    # The CWE has been created
    cwes = Cwe.query.all()
    assert len(cwes) == 1
    cwe = cwes[0]
    assert cwe.cwe_id == "CWE-116"

    # The vendors and products has been created
    vendors = Vendor.query.all()
    assert len(vendors) == 2

    vendor_1 = Vendor.query.filter_by(name="fedoraproject").first()
    assert len(vendor_1.products) == 1
    assert vendor_1.products[0].name == "fedora"

    vendor_2 = Vendor.query.filter_by(name="python").first()
    assert len(vendor_2.products) == 1
    assert vendor_2.products[0].name == "python"
Пример #6
0
    def execute(self):
        payload = {"changed": [], "added": [], "removed": []}

        # List the old and new references then make the diff between them
        old_refs = {
            ref["url"]: ref
            for ref in self.cve_obj.json["cve"]["references"]["reference_data"]
        }
        new_refs = {
            ref["url"]: ref
            for ref in self.cve_json["cve"]["references"]["reference_data"]
        }
        diff = DeepDiff(old_refs, new_refs)

        # New references
        payload["added"] = [
            new_refs[r[6:-2]] for r in diff.get("dictionary_item_added", [])
        ]

        # Removed references
        payload["removed"] = [
            old_refs[r[6:-2]] for r in diff.get("dictionary_item_removed", [])
        ]

        # Changed references (the following code parses the DeepDiff result
        # and extracts the urls of modified references)
        modified_urls = list(
            set([
                r.split("'")[1]
                for r in list(diff.get("values_changed", {}).keys()) +
                list(diff.get("iterable_item_added", {}).keys())
            ]))
        payload["changed"] = [{
            "old": old_refs[url],
            "new": new_refs[url]
        } for url in modified_urls]

        # Create the event with the references changes
        if payload["changed"] or payload["added"] or payload["removed"]:
            event = CveUtil.create_event(self.cve_obj, self.cve_json,
                                         "references", payload)
            return event

        return None
Пример #7
0
    def execute(self):
        old = nested_lookup("cpe23Uri", self.cve_obj.json["configurations"])
        new = nested_lookup("cpe23Uri", self.cve_json["configurations"])

        payload = {
            "added": list(set(new) - set(old)),
            "removed": list(set(old) - set(new)),
        }

        # The CPEs list has been modified
        if payload["added"] or payload["removed"]:

            # Change the CVE's vendors attribute
            self.cve_obj.vendors = flatten_vendors(
                convert_cpes(self.cve_json["configurations"])
            )
            db.session.commit()

            # Create the vendors and products objects if they don't exist
            vendors_products = convert_cpes(payload["added"])

            for vendor, products in vendors_products.items():
                v_obj = Vendor.query.filter_by(name=vendor).first()

                # Create the vendor and associate it to the CVE
                if not v_obj:
                    v_obj = Vendor(name=vendor)
                    db.session.add(v_obj)
                    db.session.commit()

                # Do the same for its products
                for product in products:
                    p_obj = Product.query.filter_by(name=product, vendor=v_obj).first()
                    if not p_obj:
                        p_obj = Product(name=product, vendor=v_obj)
                        db.session.add(p_obj)
                        db.session.commit()

            # Create the event
            event = CveUtil.create_event(self.cve_obj, self.cve_json, "cpes", payload)
            return event

        return None
Пример #8
0
    def execute(self):
        old = self.cve_obj.cwes
        new = [
            c["value"] for c in self.cve_json["cve"]["problemtype"]
            ["problemtype_data"][0]["description"]
        ]

        payload = {
            "added": list(set(new) - set(old)),
            "removed": list(set(old) - set(new)),
        }

        # It's possible that a CVE links a CWE not yet defined in database.
        # In this case we'll save it in the `cwes` table and a periodic task
        # will populate later its name and description using the MITRE file.
        for cwe_id in payload["added"]:
            cwe = Cwe.query.filter_by(cwe_id=cwe_id).first()

            if not cwe:
                info(
                    f"{cwe_id} detected in {self.cve_obj.cve_id} but not existing in database, adding it..."
                )
                cwe = Cwe(cwe_id=cwe_id)
                db.session.add(cwe)
                db.session.commit()

        # If the list of CWE changed
        if payload["added"] or payload["removed"]:

            # Save the new list
            self.cve_obj.cwes = new
            db.session.commit()

            # Create the event
            event = CveUtil.create_event(self.cve_obj, self.cve_json, "cwes",
                                         payload)
            return event

        return None
Пример #9
0
    def execute(self):
        summary = self.cve_json["cve"]["description"]["description_data"][0][
            "value"]

        # Check if the summary has changed
        if self.cve_obj.summary != summary:
            # Replace it in the CVE
            old = self.cve_obj.summary
            self.cve_obj.summary = summary
            db.session.commit()

            # Create a 'summary' event
            event = CveUtil.create_event(
                self.cve_obj,
                self.cve_json,
                "summary",
                {
                    "old": old,
                    "new": self.cve_obj.summary
                },
            )
            return event

        return None
Пример #10
0
 def _create_cve(cve_id):
     CveUtil.create_cve(open_file(f"cves/{cve_id}.json"))
     return Cve.query.filter_by(cve_id=cve_id).first()
Пример #11
0
 def create_events(cve):
     for t in ["summary", "cpes", "cwes", "cvss", "references"]:
         CveUtil.create_event(
             cve,
             open_file(f"modified_cves/CVE-2018-18074_{t}.json")[0], t, {})