Ejemplo n.º 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
Ejemplo n.º 2
0
def check_for_update(cve_json, task):
    cve_id = cve_json["cve"]["CVE_data_meta"]["ID"]
    cve_obj = Cve.query.filter_by(cve_id=cve_id).first()
    events = []

    # A new CVE has been added
    if not cve_obj:
        cve_obj = CveUtil.create_cve(cve_json)
        logger.info("{} created (ID: {})".format(cve_id, cve_obj.id))
        events = [CveUtil.create_event(cve_obj, cve_json, "new_cve", {})]

    # Existing CVE has changed
    elif CveUtil.cve_has_changed(cve_obj, cve_json):
        logger.info("{} has changed, parsing it...".format(cve_obj.cve_id))

        events = []
        checks = BaseCheck.__subclasses__()

        # Loop on each kind of check
        for check in checks:
            c = check(cve_obj, cve_json)
            event = c.execute()

            if event:
                events.append(event)

        # Change the last updated date
        cve_obj.updated_at = arrow.get(cve_json["lastModifiedDate"]).datetime
        cve_obj.json = cve_json
        db.session.commit()

    # Create the change
    if events:
        CveUtil.create_change(cve_obj, cve_json, task, events)
Ejemplo n.º 3
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]
Ejemplo n.º 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
Ejemplo n.º 5
0
def test_create_event(app, open_file):
    cve_json = open_file("cves/CVE-2020-26116.json")
    cve = CveUtil.create_cve(cve_json)

    event = CveUtil.create_event(cve, cve_json, "new_cve", {"foo": "bar"})
    assert Event.query.first().id == event.id

    assert event.type == "new_cve"
    assert event.details == {"foo": "bar"}
    assert event.review == False
    assert event.cve_id == cve.id
    assert event.cve.id == cve.id
    assert event.change == None
    assert event.change_id == None
    assert event.alerts == []
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 10
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, {})