Skip to content

Commit

Permalink
Fix pysec importer
Browse files Browse the repository at this point in the history
Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
  • Loading branch information
TG1999 committed May 20, 2022
1 parent f71776b commit ee1f0cf
Show file tree
Hide file tree
Showing 7 changed files with 464 additions and 554 deletions.
58 changes: 29 additions & 29 deletions vulnerabilities/importers/pysec.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@
import logging
from io import BytesIO
from typing import Iterable
from typing import List
from typing import Optional
from zipfile import ZipFile

import dateparser
import requests
from packageurl import PackageURL
from univers.version_range import InvalidVersionRange
from univers.version_range import PypiVersionRange
from univers.versions import InvalidVersion
from univers.versions import PypiVersion
from univers.versions import SemverVersion
from univers.versions import Version

from vulnerabilities.helpers import dedupe
from vulnerabilities.importer import AdvisoryData
Expand Down Expand Up @@ -70,17 +71,32 @@ def advisory_data(self) -> Iterable[AdvisoryData]:


def parse_advisory_data(raw_data: dict) -> Optional[AdvisoryData]:
raw_id = raw_data["id"]
raw_id = raw_data.get("id") or ""
summary = raw_data.get("summary") or ""
aliases = get_aliases(raw_data)
details = raw_data.get("details") or ""
summary_and_details = []
if summary:
summary_and_details.append(summary)
if details:
summary_and_details.append(details)
summary = ".".join(summary_and_details)
aliases = raw_data.get("aliases") or []
if raw_id:
aliases.append(raw_id)
date_published = get_published_date(raw_data)
severity = list(get_severities(raw_data))
references = get_references(raw_data, severity)

affected_packages = []
if "affected" not in raw_data:
logger.error(f"affected_packages not found - {raw_id !r}")
return
return AdvisoryData(
aliases=aliases,
summary=summary,
references=references,
affected_packages=[],
date_published=date_published,
)

for affected_pkg in raw_data.get("affected") or []:
purl = get_affected_purl(affected_pkg, raw_id)
Expand Down Expand Up @@ -110,7 +126,7 @@ def parse_advisory_data(raw_data: dict) -> Optional[AdvisoryData]:
)


def fixed_filter(fixed_range) -> []:
def fixed_filter(fixed_range) -> Iterable[str]:
"""
Return a list of fixed version strings given a ``fixed_range`` mapping of OSV data.
>>> list(fixed_filter({"type": "SEMVER", "events": [{"introduced": "0"}, {"fixed": "1.6.0"}]}))
Expand All @@ -124,30 +140,12 @@ def fixed_filter(fixed_range) -> []:
yield fixed


def get_aliases(raw_data) -> []:
"""
aliases field is optional , id is required and these are all aliases from our perspective
converting list of two fields to a dict then , convert it to a list to make sure a list is unique
>>> get_aliases({"id": "GHSA-j3f7-7rmc-6wqj"})
['GHSA-j3f7-7rmc-6wqj']
>>> get_aliases({"aliases": ["CVE-2021-40831"]})
['CVE-2021-40831']
>>> get_aliases({"aliases": ["CVE-2022-22817", "GHSA-8vj2-vxx3-667w"], "id": "GHSA-j3f7-7rmc-6wqj"})
['CVE-2022-22817', 'GHSA-8vj2-vxx3-667w', 'GHSA-j3f7-7rmc-6wqj']
"""
vulnerability_id = raw_data.get("id")
vulnerability_aliases = raw_data.get("aliases") or []
if vulnerability_id:
vulnerability_aliases.append(vulnerability_id)
return vulnerability_aliases


def get_published_date(raw_data):
published = raw_data.get("published")
return published and dateparser.parse(published)


def get_severities(raw_data) -> []:
def get_severities(raw_data) -> Iterable[VulnerabilitySeverity]:
for sever_list in raw_data.get("severity") or []:
if sever_list.get("type") == "CVSS_V3":
yield VulnerabilitySeverity(
Expand All @@ -173,7 +171,7 @@ def get_severities(raw_data) -> []:
)


def get_references(raw_data, severities) -> []:
def get_references(raw_data, severities) -> List[Reference]:
references = raw_data.get("references") or []
return [Reference(url=ref["url"], severities=severities) for ref in references if ref]

Expand All @@ -199,14 +197,16 @@ def get_affected_version_range(affected_pkg, raw_id):
affected_versions = affected_pkg.get("versions")
if affected_versions:
try:
return PypiVersionRange(affected_versions)
except InvalidVersionRange:
logger.error(f"InvalidVersionRange affected_pkg_version_range Error - {raw_id !r} ")
return PypiVersionRange.from_versions(affected_versions)
except Exception as e:
logger.error(
f"InvalidVersionRange affected_pkg_version_range Error - {raw_id !r} {e!r}"
)
else:
logger.error(f"affected_pkg_version_range not found - {raw_id !r} ")


def get_fixed_version(fixed_range, raw_id) -> []:
def get_fixed_version(fixed_range, raw_id) -> List[Version]:
"""
Return a list of fixed versions, using fixed_filter we get the list of fixed version strings,
then we pass every element to their univers.versions , then we dedupe the result
Expand Down
55 changes: 55 additions & 0 deletions vulnerabilities/tests/test_data/pysec/pysec-expected-1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"aliases": [
"CVE-2022-22817",
"GHSA-8vj2-vxx3-667w",
"PYSEC-2022-10"
],
"summary": "PIL.ImageMath.eval in Pillow before 9.0.0 allows evaluation of arbitrary expressions, such as ones that use the Python exec method.",
"affected_packages": [
{
"package": {
"type": "pypi",
"namespace": null,
"name": "pillow",
"version": null,
"qualifiers": null,
"subpath": null
},
"affected_version_range": "vers:pypi/1.0|1.1|1.2|1.3|1.4|1.5|1.6|1.7.0|1.7.1|1.7.2|1.7.3|1.7.4|1.7.5|1.7.6|1.7.7|1.7.8|2.0.0|2.1.0|2.2.0|2.2.1|2.2.2|2.3.0|2.3.1|2.3.2|2.4.0|2.5.0|2.5.1|2.5.2|2.5.3|2.6.0|2.6.1|2.6.2|2.7.0|2.8.0|2.8.1|2.8.2|2.9.0|3.0.0|3.1.0rc1|3.1.0rc1|3.1.0|3.1.1|3.1.2|3.2.0|3.3.0|3.3.1|3.3.2|3.3.3|3.4.0|3.4.1|3.4.2|4.0.0|4.1.0|4.1.1|4.2.0|4.2.1|4.3.0|5.0.0|5.1.0|5.2.0|5.3.0|5.4.0.dev0|5.4.0|5.4.1|6.0.0|6.1.0|6.2.0|6.2.1|6.2.2|7.0.0|7.1.0|7.1.1|7.1.2|7.2.0|8.0.0|8.0.1|8.1.0|8.1.1|8.1.2|8.2.0|8.3.0|8.3.1|8.3.2|8.4.0",
"fixed_version": "9.0.0"
}
],
"references": [
{
"reference_id": "",
"url": "https://pillow.readthedocs.io/en/stable/releasenotes/9.0.0.html#restrict-builtins-available-to-imagemath-eval",
"severities": [
{
"system": "generic_textual",
"value": "HIGH"
}
]
},
{
"reference_id": "",
"url": "https://lists.debian.org/debian-lts-announce/2022/01/msg00018.html",
"severities": [
{
"system": "generic_textual",
"value": "HIGH"
}
]
},
{
"reference_id": "",
"url": "https://github.com/advisories/GHSA-8vj2-vxx3-667w",
"severities": [
{
"system": "generic_textual",
"value": "HIGH"
}
]
}
],
"date_published": "2022-01-10T14:12:00.853348+00:00"
}
44 changes: 44 additions & 0 deletions vulnerabilities/tests/test_data/pysec/pysec-expected-2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"aliases": [
"CVE-2021-40831",
"GHSA-j3f7-7rmc-6wqj"
],
"summary": "Improper certificate management in AWS IoT Device SDK v2.The AWS IoT Device SDK v2 for Java, Python, C++ and Node.js appends a user supplied Certificate Authority (CA) to the root CAs instead of overriding it on macOS systems. Additionally, SNI validation is also not enabled when the CA has been \u201coverridden\u201d. TLS handshakes will thus succeed if the peer can be verified either from the user-supplied CA or the system\u2019s default trust-store. Attackers with access to a host\u2019s trust stores or are able to compromise a certificate authority already in the host's trust store (note: the attacker must also be able to spoof DNS in this case) may be able to use this issue to bypass CA pinning. An attacker could then spoof the MQTT broker, and either drop traffic and/or respond with the attacker's data, but they would not be able to forward this data on to the MQTT broker because the attacker would still need the user's private keys to authenticate against the MQTT broker. The 'aws_tls_ctx_options_override_default_trust_store_*' function within the aws-c-io submodule has been updated to address this behavior. This issue affects: Amazon Web Services AWS IoT Device SDK v2 for Java versions prior to 1.5.0 on macOS. Amazon Web Services AWS IoT Device SDK v2 for Python versions prior to 1.7.0 on macOS. Amazon Web Services AWS IoT Device SDK v2 for C++ versions prior to 1.14.0 on macOS. Amazon Web Services AWS IoT Device SDK v2 for Node.js versions prior to 1.6.0 on macOS. Amazon Web Services AWS-C-IO 0.10.7 on macOS.",
"affected_packages": [
{
"package": {
"type": "pypi",
"namespace": null,
"name": "awsiotsdk",
"version": null,
"qualifiers": null,
"subpath": null
},
"affected_version_range": "vers:pypi/0.2.4|0.2.9|0.3.0|1.0.2|1.0.3|1.0.5|1.0.6|1.1.0|1.2.0|1.2.1|1.3.0|1.3.1|1.3.2|1.4.0|1.5.0|1.5.1|1.5.2|1.5.3|1.5.4|1.5.5|1.5.6|1.5.7|1.5.8|1.5.10|1.5.11|1.5.12|1.5.13|1.5.14|1.5.15|1.5.16|1.5.17|1.5.18|1.6.0|1.6.1|1.6.2",
"fixed_version": "1.7.0"
}
],
"references": [
{
"reference_id": "",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-40831",
"severities": [
{
"system": "cvssv3.1_vector",
"value": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N"
}
]
},
{
"reference_id": "",
"url": "https://github.com/aws/aws-iot-device-sdk-cpp-v2",
"severities": [
{
"system": "cvssv3.1_vector",
"value": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N"
}
]
}
],
"date_published": "2021-11-24T20:35:03+00:00"
}
Loading

0 comments on commit ee1f0cf

Please sign in to comment.