diff --git a/vulnerabilities/importers/nginx.py b/vulnerabilities/importers/nginx.py index 7aa217747..acd766b8c 100644 --- a/vulnerabilities/importers/nginx.py +++ b/vulnerabilities/importers/nginx.py @@ -19,9 +19,11 @@ # for any legal advice. # VulnerableCode is a free software tool from nexB Inc. and others. # Visit https://github.com/nexB/vulnerablecode/ for support and download. + import asyncio import logging from typing import Iterable +from typing import NamedTuple import requests from bs4 import BeautifulSoup @@ -30,6 +32,7 @@ from univers.version_range import NginxVersionRange from univers.versions import SemverVersion +from vulnerabilities.helpers import evolve_purl from vulnerabilities.importer import AdvisoryData from vulnerabilities.importer import AffectedPackage from vulnerabilities.importer import Importer @@ -41,8 +44,7 @@ from vulnerabilities.models import Advisory from vulnerabilities.package_managers import GitHubTagsAPI from vulnerabilities.package_managers import Version -from vulnerabilities.severity_systems import SCORING_SYSTEMS -from vulnerabilities.severity_systems import ScoringSystem +from vulnerabilities.severity_systems import GENERIC logger = logging.getLogger(__name__) @@ -55,39 +57,54 @@ class NginxImporter(Importer): spdx_license_expression = "TODO" def advisory_data(self) -> Iterable[AdvisoryData]: - data = requests.get(self.url).content - soup = BeautifulSoup(data, features="lxml") - vuln_list = soup.select("li p") - for vuln_info in vuln_list: - yield to_advisory_data(**parse_advisory_data_from_paragraph(vuln_info)) + text = requests.get(self.url).content + yield from advisory_data_from_text(text) -def to_advisory_data( - aliases, summary, advisory_severity, not_vulnerable, vulnerable, references -) -> AdvisoryData: +def advisory_data_from_text(text): """ - Return AdvisoryData formed by given parameters - An advisory paragraph, without html markup, looks like: - - 1-byte memory overwrite in resolver - Severity: medium - Advisory - CVE-2021-23017 - Not vulnerable: 1.21.0+, 1.20.1+ - Vulnerable: 0.6.18-1.20.0 - The patch pgp + Yield AdvisoryData from the ``text`` of the nginx security advisories HTML + web page. """ + soup = BeautifulSoup(text, features="lxml") + vuln_list = soup.select("li p") + for vuln_info in vuln_list: + ngnix_adv = parse_advisory_data_from_paragraph(vuln_info) + yield to_advisory_data(ngnix_adv) + + +class NginxAdvisory(NamedTuple): + aliases: list + summary: str + advisory_severity: str + not_vulnerable: str + vulnerable: str + references: list + + def to_dict(self): + return self._asdict() + +def to_advisory_data(ngnx_adv: NginxAdvisory) -> AdvisoryData: + """ + Return AdvisoryData from an NginxAdvisory tuple. + """ + package_name = "nginx" + package_type = "nginx" qualifiers = {} - _, _, affected_version_range = vulnerable.partition(":") + _, _, affected_version_range = ngnx_adv.vulnerable.partition(":") if "nginx/Windows" in affected_version_range: qualifiers["os"] = "windows" affected_version_range = affected_version_range.replace("nginx/Windows", "") + + purl = PackageURL(type=package_type, name=package_name, qualifiers=qualifiers) + affected_version_range = NginxVersionRange.from_native(affected_version_range) affected_packages = [] - _, _, fixed_versions = not_vulnerable.partition(":") + _, _, fixed_versions = ngnx_adv.not_vulnerable.partition(":") + for fixed_version in fixed_versions.split(","): fixed_version = fixed_version.rstrip("+") @@ -95,14 +112,13 @@ def to_advisory_data( if "none" in fixed_version: affected_packages.append( AffectedPackage( - package=PackageURL(type="generic", name="nginx", qualifiers=qualifiers), + package=purl, affected_version_range=affected_version_range, ) ) break fixed_version = SemverVersion(fixed_version) - purl = PackageURL(type="generic", name="nginx", qualifiers=qualifiers) affected_packages.append( AffectedPackage( package=purl, @@ -112,110 +128,111 @@ def to_advisory_data( ) return AdvisoryData( - aliases=aliases, - summary=summary, + aliases=ngnx_adv.aliases, + summary=ngnx_adv.summary, affected_packages=affected_packages, - references=references, + references=ngnx_adv.references, ) def parse_advisory_data_from_paragraph(vuln_info): """ - Return a dict with keys (aliases, summary, advisory_severity, - not_vulnerable, vulnerable, references) from bs4 paragraph + Return an NginxAdvisory from a ``vuln_info`` bs4 paragraph. + + An advisory paragraph, without html markup, looks like this: + + 1-byte memory overwrite in resolver + Severity: medium + Advisory + CVE-2021-23017 + Not vulnerable: 1.21.0+, 1.20.1+ + Vulnerable: 0.6.18-1.20.0 + The patch pgp - For example: - >>> paragraph = ('

1-byte memory overwrite in resolver
Severity: medium
' - ... '' - ... 'Advisory
CVE-2021-23017
Not vulnerable: 1.21.0+, 1.20.1+
' - ... 'Vulnerable: 0.6.18-1.20.0
' - ... 'The patch  pgp

') - >>> vuln_info = BeautifulSoup(paragraph, features="lxml").p - >>> expected = { - ... 'aliases': ['CVE-2021-23017'], - ... 'summary': '1-byte memory overwrite in resolver', - ... 'advisory_severity': 'Severity: medium', - ... 'not_vulnerable': 'Not vulnerable: 1.21.0+, 1.20.1+', - ... 'vulnerable': 'Vulnerable: 0.6.18-1.20.0', - ... 'references': [ - ... Reference( - ... reference_id='', - ... url='http://mailman.nginx.org/pipermail/nginx-announce/2021/000300.html', - ... severities=[VulnerabilitySeverity( - ... system=ScoringSystem( - ... identifier='generic_textual', - ... name='Generic textual severity rating', - ... url='', - ... notes='Severity for unknown scoring systems. ' - ... 'Contains generic textual values like High, Low etc'), - ... value='Severity: medium' - ... )] - ... ), - ... Reference( - ... reference_id='', - ... url='https://nginx.org/download/patch.2021.resolver.txt', - ... severities=[] - ... ), - ... Reference( - ... reference_id='', - ... url='https://nginx.org/download/patch.2021.resolver.txt.asc', - ... severities=[] - ... ) - ... ] - ... } - >>> assert parse_advisory_data_from_paragraph(vuln_info) == expected """ aliases = [] - summary = advisory_severity = not_vulnerable = vulnerable = None + summary = None + advisory_severity = None + not_vulnerable = None + vulnerable = None references = [] is_first = True + + # we iterate on the children to accumulate values in variables + # FIXME: using an explicit xpath-like query could be simpler for child in vuln_info.children: if is_first: summary = child is_first = False + continue - elif child.text.startswith( + text = child.text.strip() + text_low = text.lower() + + if text.startswith( ( "CVE-", "CORE-", "VU#", ) ): - aliases.append(child.text) + aliases.append(text) + if text.startswith("CVE-"): + + # always keep the CVE as a reference too + link = f"https://nvd.nist.gov/vuln/detail/{text}" + reference = Reference(reference_id=text, url=link) + references.append(reference) + + elif "severity" in text_low: + advisory_severity = build_severity(severity=text) + + elif "not vulnerable" in text_low: + not_vulnerable = text + + elif "vulnerable" in text_low: + vulnerable = text + + elif hasattr(child, "attrs"): + link = child.attrs.get("href") + if link: + if "cve.mitre.org" in link: + references.append(Reference(reference_id=text, url=link)) + elif "mailman.nginx.org" in link: + if advisory_severity: + severities = [advisory_severity] + else: + severities = [] + references.append(Reference(url=link, severities=severities)) + else: + link = requests.compat.urljoin("https://nginx.org", link) + references.append(Reference(url=link)) + + return NginxAdvisory( + aliases=aliases, + summary=summary, + advisory_severity=advisory_severity, + not_vulnerable=not_vulnerable, + vulnerable=vulnerable, + references=references, + ) - elif "severity" in child.text.lower(): - advisory_severity = child.text - elif "not vulnerable" in child.text.lower(): - not_vulnerable = child.text +def build_severity(severity): + """ + Return a VulnerabilitySeverity built from a ``severity`` string, or None. - elif "vulnerable" in child.text.lower(): - vulnerable = child.text + For example:: + >>> severity = "Severity: medium" + >>> expected = VulnerabilitySeverity(system=GENERIC, value="medium") + >>> assert build_severity(severity) == expected + """ + if severity.startswith("Severity:"): + _, _, severity = severity.partition("Severity:") - elif hasattr(child, "attrs") and child.attrs.get("href"): - link = child.attrs["href"] - # Take care of relative urls - link = requests.compat.urljoin("https://nginx.org", link) - if "cve.mitre.org" in link: - cve = child.text.strip() - reference = Reference(reference_id=cve, url=link) - references.append(reference) - elif "http://mailman.nginx.org" in link: - ss = SCORING_SYSTEMS["generic_textual"] - severity = VulnerabilitySeverity(system=ss, value=advisory_severity) - references.append(Reference(url=link, severities=[severity])) - else: - references.append(Reference(url=link)) - - return { - "aliases": aliases, - "summary": summary, - "advisory_severity": advisory_severity, - "not_vulnerable": not_vulnerable, - "vulnerable": vulnerable, - "references": references, - } + severity = severity.strip() + if severity: + return VulnerabilitySeverity(system=GENERIC, value=severity) class NginxBasicImprover(Improver): @@ -228,7 +245,7 @@ def interesting_advisories(self) -> QuerySet: def get_inferences(self, advisory_data: AdvisoryData) -> Iterable[Inference]: """ - Generate and return Inferences for the given advisory data + Yield Inference from the ``advisory data`` AdvisoryData. """ try: purl, affected_version_ranges, fixed_versions = AffectedPackage.merge( @@ -248,12 +265,13 @@ def get_inferences(self, advisory_data: AdvisoryData) -> Iterable[Inference]: affected_version_range=affected_version_range, fixed_versions=fixed_versions, ): - affected_purls.append(purl._replace(version=version)) + new_purl = evolve_purl(purl=purl, version=version) + affected_purls.append(new_purl) for fixed_version in fixed_versions: # TODO: This also yields with a lower fixed version, maybe we should # only yield fixes that are upgrades ? - fixed_purl = purl._replace(version=fixed_version) + fixed_purl = evolve_purl(purl=purl, version=fixed_version) yield Inference.from_advisory_data( advisory_data, confidence=90, # TODO: Decide properly @@ -265,29 +283,54 @@ def set_api(self): self.version_api = GitHubTagsAPI() asyncio.run(self.version_api.load_api(["nginx/nginx"])) - # Nginx tags it's releases are in the form of `release-1.2.3` - # Chop off the `release-` part here. normalized_versions = set() while self.version_api.cache["nginx/nginx"]: version = self.version_api.cache["nginx/nginx"].pop() - cleaned = version.value.replace("release-", "") + cleaned = clean_nginx_git_tag(version.value) normalized_version = Version(value=cleaned, release_date=version.release_date) normalized_versions.add(normalized_version) self.version_api.cache["nginx/nginx"] = normalized_versions +def clean_nginx_git_tag(tag): + """ + Return a cleaned ``version`` string from an nginx git tag. + + Nginx tags git release as in `release-1.2.3` + This removes the the `release-` prefix. + + For example: + >>> clean_nginx_git_tag("release-1.2.3") == "1.2.3" + True + >>> clean_nginx_git_tag("1.2.3") == "1.2.3" + True + """ + if tag.startswith("release-"): + _, _, tag = tag.partition("release-") + return tag + + def is_vulnerable(version, affected_version_range, fixed_versions): """ - Check if the version is in "Vulnerable" range. If it's not, the - version is not vulnerable. + Return True if the ``version`` Version for nginx is vulnerable according to + the nginx approach. + + A ``version`` is vulnerable as explained by @mdounin + in https://marc.info/?l=nginx&m=164070162912710&w=2 : + + "Note that it is generally trivial to find out if a version is + vulnerable or not from the information about a vulnerability, + without any knowledge about nginx branches. That is: + + - Check if the version is in "Vulnerable" range. If it's not, the + version is not vulnerable. - If it is, check if the branch is explicitly listed in the "Not - vulnerable". If it's not, the version is vulnerable. If it - is, check the minor number: if it's greater or equal to the - version listed as not vulnerable, the version is not vulnerable, - else the version is vulnerable. + - If it is, check if the branch is explicitly listed in the "Not + vulnerable". If it's not, the version is vulnerable. If it + is, check the minor number: if it's greater or equal to the + version listed as not vulnerable, the version is not vulnerable, + else the version is vulnerable." - See: https://marc.info/?l=nginx&m=164070162912710&w=2 """ if version in NginxVersionRange.from_string(affected_version_range.to_string()): for fixed_version in fixed_versions: diff --git a/vulnerabilities/tests/conftest.py b/vulnerabilities/tests/conftest.py index 0bb246db3..e510a7ceb 100644 --- a/vulnerabilities/tests/conftest.py +++ b/vulnerabilities/tests/conftest.py @@ -21,8 +21,6 @@ # VulnerableCode is a free software code scanning tool from nexB Inc. and others. # Visit https://github.com/nexB/vulnerablecode/ for support and download. -import os - import pytest @@ -43,7 +41,6 @@ def no_rmtree(monkeypatch): collect_ignore = [ "test_models.py", "test_msr2019.py", - "test_nginx.py", "test_apache_httpd.py", "test_npm.py", "test_apache_kafka.py", diff --git a/vulnerabilities/tests/test_data/nginx/security_advisories.html b/vulnerabilities/tests/test_data/nginx/security_advisories.html index 58f76f064..db3556eba 100644 --- a/vulnerabilities/tests/test_data/nginx/security_advisories.html +++ b/vulnerabilities/tests/test_data/nginx/security_advisories.html @@ -1,28 +1,88 @@ - +nginx security advisories

nginx security advisories

+All nginx security issues should be reported to +security-alert@nginx.org.

Patches are signed using one of the PGP public keys.

diff --git a/vulnerabilities/tests/test_data/nginx/security_advisories.json b/vulnerabilities/tests/test_data/nginx/security_advisories.json new file mode 100644 index 000000000..3734a5529 --- /dev/null +++ b/vulnerabilities/tests/test_data/nginx/security_advisories.json @@ -0,0 +1,1655 @@ +[ + { + "aliases": [ + "CVE-2021-23017" + ], + "summary": "1-byte memory overwrite in resolver", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.6.18|<=1.20.0", + "fixed_version": "1.21.0" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.6.18|<=1.20.0", + "fixed_version": "1.20.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2021/000300.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2021-23017", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-23017", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2021.resolver.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2021.resolver.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2019-9511" + ], + "summary": "Excessive CPU usage in HTTP/2 with small window updates", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.9.5|<=1.17.2", + "fixed_version": "1.17.3" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.9.5|<=1.17.2", + "fixed_version": "1.16.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2019/000249.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2019-9511", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9511", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2019-9513" + ], + "summary": "Excessive CPU usage in HTTP/2 with priority changes", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.9.5|<=1.17.2", + "fixed_version": "1.17.3" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.9.5|<=1.17.2", + "fixed_version": "1.16.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2019/000249.html", + "severities": [ + { + "system": "generic_textual", + "value": "low" + } + ] + }, + { + "reference_id": "CVE-2019-9513", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9513", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2019-9516" + ], + "summary": "Excessive memory usage in HTTP/2 with zero length headers", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.9.5|<=1.17.2", + "fixed_version": "1.17.3" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.9.5|<=1.17.2", + "fixed_version": "1.16.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2019/000249.html", + "severities": [ + { + "system": "generic_textual", + "value": "low" + } + ] + }, + { + "reference_id": "CVE-2019-9516", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9516", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2018-16843" + ], + "summary": "Excessive memory usage in HTTP/2", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.9.5|<=1.15.5", + "fixed_version": "1.15.6" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.9.5|<=1.15.5", + "fixed_version": "1.14.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2018/000220.html", + "severities": [ + { + "system": "generic_textual", + "value": "low" + } + ] + }, + { + "reference_id": "CVE-2018-16843", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-16843", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2018-16844" + ], + "summary": "Excessive CPU usage in HTTP/2", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.9.5|<=1.15.5", + "fixed_version": "1.15.6" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.9.5|<=1.15.5", + "fixed_version": "1.14.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2018/000220.html", + "severities": [ + { + "system": "generic_textual", + "value": "low" + } + ] + }, + { + "reference_id": "CVE-2018-16844", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-16844", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2018-16845" + ], + "summary": "Memory disclosure in the ngx_http_mp4_module", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.0.7|<=1.0.15|>=1.1.3|<=1.15.5", + "fixed_version": "1.15.6" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.0.7|<=1.0.15|>=1.1.3|<=1.15.5", + "fixed_version": "1.14.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2018/000221.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2018-16845", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-16845", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2018.mp4.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2018.mp4.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2017-7529" + ], + "summary": "Integer overflow in the range filter", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.5.6|<=1.13.2", + "fixed_version": "1.13.3" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.5.6|<=1.13.2", + "fixed_version": "1.12.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2017/000200.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2017-7529", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-7529", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2017.ranges.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2017.ranges.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2016-4450" + ], + "summary": "NULL pointer dereference while writing client request body", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.3.9|<=1.11.0", + "fixed_version": "1.11.1" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.3.9|<=1.11.0", + "fixed_version": "1.10.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2016/000179.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2016-4450", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2016-4450", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2016.write.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2016.write.txt.asc", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2016.write2.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2016.write2.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2016-0742" + ], + "summary": "Invalid pointer dereference in resolver", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.6.18|<=1.9.9", + "fixed_version": "1.9.10" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.6.18|<=1.9.9", + "fixed_version": "1.8.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2016/000169.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2016-0742", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2016-0742", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2016-0746" + ], + "summary": "Use-after-free during CNAME response processing in resolver", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.6.18|<=1.9.9", + "fixed_version": "1.9.10" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.6.18|<=1.9.9", + "fixed_version": "1.8.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2016/000169.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2016-0746", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2016-0746", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2016-0747" + ], + "summary": "Insufficient limits of CNAME resolution in resolver", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.6.18|<=1.9.9", + "fixed_version": "1.9.10" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.6.18|<=1.9.9", + "fixed_version": "1.8.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2016/000169.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2016-0747", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2016-0747", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2014-3616" + ], + "summary": "SSL session reuse vulnerability", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.5.6|<=1.7.4", + "fixed_version": "1.7.5" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.5.6|<=1.7.4", + "fixed_version": "1.6.2" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2014/000147.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2014-3616", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2014-3616", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2014-3556" + ], + "summary": "STARTTLS command injection", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.5.6|<=1.7.3", + "fixed_version": "1.7.4" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.5.6|<=1.7.3", + "fixed_version": "1.6.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2014/000144.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2014-3556", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2014-3556", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2014.starttls.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2014.starttls.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2014-0133" + ], + "summary": "SPDY heap buffer overflow", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.3.15|<=1.5.11", + "fixed_version": "1.5.12" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.3.15|<=1.5.11", + "fixed_version": "1.4.7" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2014/000135.html", + "severities": [] + }, + { + "reference_id": "CVE-2014-0133", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2014-0133", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2014.spdy2.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2014.spdy2.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2014-0088" + ], + "summary": "SPDY memory corruption", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/1.5.10", + "fixed_version": "1.5.11" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2014/000132.html", + "severities": [] + }, + { + "reference_id": "CVE-2014-0088", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2014-0088", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2014.spdy.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2014.spdy.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2013-4547" + ], + "summary": "Request line parsing vulnerability", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.8.41|<=1.5.6", + "fixed_version": "1.5.7" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.8.41|<=1.5.6", + "fixed_version": "1.4.4" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2013/000125.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2013-4547", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2013-4547", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2013.space.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2013.space.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2013-2070" + ], + "summary": "Memory disclosure with specially crafted HTTP backend responses", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.1.4|<=1.2.8|>=1.3.9|<=1.4.0", + "fixed_version": "1.5.0" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.1.4|<=1.2.8|>=1.3.9|<=1.4.0", + "fixed_version": "1.4.1" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.1.4|<=1.2.8|>=1.3.9|<=1.4.0", + "fixed_version": "1.2.9" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2013/000114.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2013-2070", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2013-2070", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2013.chunked.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2013.chunked.txt.asc", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2013.proxy.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2013.proxy.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2013-2028" + ], + "summary": "Stack-based buffer overflow with specially crafted request", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.3.9|<=1.4.0", + "fixed_version": "1.5.0" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.3.9|<=1.4.0", + "fixed_version": "1.4.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2013/000112.html", + "severities": [] + }, + { + "reference_id": "CVE-2013-2028", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2013-2028", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2013.chunked.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2013.chunked.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2011-4963" + ], + "summary": "Vulnerabilities with Windows directory aliases", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": { + "os": "windows" + }, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.7.52|<=1.3.0", + "fixed_version": "1.3.1" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": { + "os": "windows" + }, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.7.52|<=1.3.0", + "fixed_version": "1.2.1" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2012/000086.html", + "severities": [ + { + "system": "generic_textual", + "value": "medium" + } + ] + }, + { + "reference_id": "CVE-2011-4963", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2011-4963", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2012-2089" + ], + "summary": "Buffer overflow in the ngx_http_mp4_module", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.0.7|<=1.0.14|>=1.1.3|<=1.1.18", + "fixed_version": "1.1.19" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=1.0.7|<=1.0.14|>=1.1.3|<=1.1.18", + "fixed_version": "1.0.15" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2012/000080.html", + "severities": [] + }, + { + "reference_id": "CVE-2012-2089", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2012-2089", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2012.mp4.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2012.mp4.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2012-1180" + ], + "summary": "Memory disclosure with specially crafted backend responses", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=1.1.16", + "fixed_version": "1.1.17" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=1.1.16", + "fixed_version": "1.0.14" + } + ], + "references": [ + { + "reference_id": "", + "url": "http://mailman.nginx.org/pipermail/nginx-announce/2012/000076.html", + "severities": [] + }, + { + "reference_id": "CVE-2012-1180", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2012-1180", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2012.memory.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.2012.memory.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2011-4315" + ], + "summary": "Buffer overflow in resolver", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.6.18|<=1.1.7", + "fixed_version": "1.1.8" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.6.18|<=1.1.7", + "fixed_version": "1.0.10" + } + ], + "references": [ + { + "reference_id": "CVE-2011-4315", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2011-4315", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2010-2266" + ], + "summary": "Vulnerabilities with invalid UTF-8 sequence on Windows", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": { + "os": "windows" + }, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.7.52|<=0.8.40", + "fixed_version": "0.8.41" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": { + "os": "windows" + }, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.7.52|<=0.8.40", + "fixed_version": "0.7.67" + } + ], + "references": [ + { + "reference_id": "CVE-2010-2266", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2010-2266", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2010-2263" + ], + "summary": "Vulnerabilities with Windows file default stream", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": { + "os": "windows" + }, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.7.52|<=0.8.39", + "fixed_version": "0.8.40" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": { + "os": "windows" + }, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.7.52|<=0.8.39", + "fixed_version": "0.7.66" + } + ], + "references": [ + { + "reference_id": "CVE-2010-2263", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2010-2263", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CORE-2010-0121" + ], + "summary": "Vulnerabilities with Windows 8.3 filename pseudonyms", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": { + "os": "windows" + }, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.7.52|<=0.8.32", + "fixed_version": "0.8.33" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": { + "os": "windows" + }, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.7.52|<=0.8.32", + "fixed_version": "0.7.65" + } + ], + "references": [], + "date_published": null + }, + { + "aliases": [ + "CVE-2009-4487" + ], + "summary": "An error log data are not sanitized", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/*", + "fixed_version": null + } + ], + "references": [ + { + "reference_id": "CVE-2009-4487", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2009-4487", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "VU#120541", + "CVE-2009-3555" + ], + "summary": "The renegotiation vulnerability in SSL protocol", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.22", + "fixed_version": "0.8.23" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.22", + "fixed_version": "0.7.64" + } + ], + "references": [ + { + "reference_id": "CVE-2009-3555", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2009-3555", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.cve-2009-3555.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.cve-2009-3555.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2009-3898" + ], + "summary": "Directory traversal vulnerability", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.16", + "fixed_version": "0.8.17" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.16", + "fixed_version": "0.7.63" + } + ], + "references": [ + { + "reference_id": "CVE-2009-3898", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2009-3898", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "VU#180065", + "CVE-2009-2629" + ], + "summary": "Buffer underflow vulnerability", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.14", + "fixed_version": "0.8.15" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.14", + "fixed_version": "0.7.62" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.14", + "fixed_version": "0.6.39" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.14", + "fixed_version": "0.5.38" + } + ], + "references": [ + { + "reference_id": "CVE-2009-2629", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2009-2629", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.180065.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.180065.txt.asc", + "severities": [] + } + ], + "date_published": null + }, + { + "aliases": [ + "CVE-2009-3896" + ], + "summary": "Null pointer dereference vulnerability", + "affected_packages": [ + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.13", + "fixed_version": "0.8.14" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.13", + "fixed_version": "0.7.62" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.13", + "fixed_version": "0.6.39" + }, + { + "package": { + "type": "nginx", + "namespace": null, + "name": "nginx", + "version": null, + "qualifiers": null, + "subpath": null + }, + "affected_version_range": "vers:nginx/>=0.1.0|<=0.8.13", + "fixed_version": "0.5.38" + } + ], + "references": [ + { + "reference_id": "CVE-2009-3896", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2009-3896", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.null.pointer.txt", + "severities": [] + }, + { + "reference_id": "", + "url": "https://nginx.org/download/patch.null.pointer.txt.asc", + "severities": [] + } + ], + "date_published": null + } +] \ No newline at end of file diff --git a/vulnerabilities/tests/test_nginx.py b/vulnerabilities/tests/test_nginx.py index 6c313f036..5ffa382a4 100644 --- a/vulnerabilities/tests/test_nginx.py +++ b/vulnerabilities/tests/test_nginx.py @@ -20,172 +20,121 @@ # VulnerableCode is a free software tool from nexB Inc. and others. # Visit https://github.com/nexB/vulnerablecode/ for support and download. -import os -from unittest import TestCase -from unittest.mock import patch - -from packageurl import PackageURL - -from vulnerabilities.helpers import AffectedPackage -from vulnerabilities.importer import Advisory -from vulnerabilities.importers.nginx import NginxImporter -from vulnerabilities.package_managers import GitHubTagsAPI -from vulnerabilities.package_managers import Version - -BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -TEST_DATA = os.path.join(BASE_DIR, "test_data/nginx", "security_advisories.html") - - -class TestNginxImporter(TestCase): - @classmethod - def setUpClass(cls): - with open(TEST_DATA) as f: - cls.data = f.read() - data_source_cfg = {"etags": {}} - cls.data_src = NginxImporter(1, config=data_source_cfg) - cls.data_src.version_api = GitHubTagsAPI( - cache={ - "nginx/nginx": { - Version("1.2.3"), - Version("1.7.0"), - Version("1.3.9"), - Version("0.7.52"), - } - } - ) +from pathlib import Path - def test_to_advisories(self): - expected_advisories = [ - Advisory( - summary="An error log data are not sanitized", - vulnerability_id="CVE-2009-4487", - affected_packages=[], - references=[], - ), - Advisory( - summary="Directory traversal vulnerability", - vulnerability_id="CVE-2009-3898", - affected_packages=[ - AffectedPackage( - vulnerable_package=PackageURL( - type="generic", - namespace=None, - name="nginx", - version="0.7.52", - qualifiers={}, - subpath=None, - ), - patched_package=None, - ) - ], - references=[], - ), - Advisory( - summary="Stack-based buffer overflow with specially crafted request", - vulnerability_id="CVE-2013-2028", - affected_packages=[ - AffectedPackage( - vulnerable_package=PackageURL( - type="generic", - namespace=None, - name="nginx", - version="1.3.9", - qualifiers={}, - subpath=None, - ), - patched_package=PackageURL( - type="generic", - namespace=None, - name="nginx", - version="1.7.0", - qualifiers={}, - subpath=None, - ), - ) - ], - references=[], - ), - Advisory( - summary="The renegotiation vulnerability in SSL protocol", - vulnerability_id="CVE-2009-3555", - affected_packages=[ - AffectedPackage( - vulnerable_package=PackageURL( - type="generic", - namespace=None, - name="nginx", - version="0.7.52", - qualifiers={}, - subpath=None, - ), - patched_package=None, - ) - ], - references=[], - ), - Advisory( - summary="Vulnerabilities with Windows directory aliases", - vulnerability_id="CVE-2011-4963", - affected_packages=[ - AffectedPackage( - vulnerable_package=PackageURL( - type="generic", - namespace=None, - name="nginx", - version="0.7.52", - qualifiers={"os": "windows"}, - subpath=None, - ), - patched_package=PackageURL( - type="generic", - namespace=None, - name="nginx", - version="1.2.3", - qualifiers={}, - subpath=None, - ), - ), - AffectedPackage( - vulnerable_package=PackageURL( - type="generic", - namespace=None, - name="nginx", - version="1.2.3", - qualifiers={"os": "windows"}, - subpath=None, - ), - patched_package=PackageURL( - type="generic", - namespace=None, - name="nginx", - version="1.3.9", - qualifiers={}, - subpath=None, - ), - ), - ], - references=[], - ), - Advisory( - summary="Vulnerabilities with invalid UTF-8 sequence on Windows", - vulnerability_id="CVE-2010-2266", - affected_packages=[ - AffectedPackage( - vulnerable_package=PackageURL( - type="generic", - namespace=None, - name="nginx", - version="0.7.52", - qualifiers={"os": "windows"}, - subpath=None, - ), - patched_package=None, - ) - ], - references=[], +from bs4 import BeautifulSoup +from commoncode import testcase + +from vulnerabilities import severity_systems +from vulnerabilities.importer import Reference +from vulnerabilities.importer import VulnerabilitySeverity +from vulnerabilities.importers import nginx +from vulnerabilities.tests import util_tests + + +class TestNginxImporter(testcase.FileBasedTesting): + test_data_dir = str(Path(__file__).resolve().parent / "test_data" / "nginx") + + def test_is_vulnerable(self): + # Not vulnerable: 1.17.3+, 1.16.1+ + # Vulnerable: 1.9.5-1.17.2 + + vcls = nginx.NginxVersionRange.version_class + affected_version_range = nginx.NginxVersionRange.from_native("1.9.5-1.17.2") + fixed_versions = [vcls("1.17.3"), vcls("1.16.1")] + + version = vcls("1.9.4") + assert not nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.9.5") + assert nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.9.6") + assert nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.16.0") + assert nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.16.1") + assert not nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.16.2") + assert not nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.16.99") + assert not nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.17.0") + assert nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.17.1") + assert nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.17.2") + assert nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.17.3") + assert not nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.17.4") + assert not nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + version = vcls("1.18.0") + assert not nginx.is_vulnerable(version, affected_version_range, fixed_versions) + + def test_parse_advisory_data_from_paragraph(self): + paragraph = ( + "

1-byte memory overwrite in resolver" + "
Severity: medium
" + 'Advisory' + "
" + 'CVE-2021-23017' + "
Not vulnerable: 1.21.0+, 1.20.1+
" + "Vulnerable: 0.6.18-1.20.0
" + '' + 'The patch  pgp' + "

" + ) + vuln_info = BeautifulSoup(paragraph, features="lxml").p + expected = { + "aliases": ["CVE-2021-23017"], + "summary": "1-byte memory overwrite in resolver", + "advisory_severity": VulnerabilitySeverity( + system=severity_systems.GENERIC, value="medium" ), - ] - found_data = self.data_src.to_advisories(self.data) - expected_advisories = list(map(Advisory.normalized, expected_advisories)) - found_data = list(map(Advisory.normalized, found_data)) - assert sorted(found_data) == sorted(expected_advisories) + "not_vulnerable": "Not vulnerable: 1.21.0+, 1.20.1+", + "vulnerable": "Vulnerable: 0.6.18-1.20.0", + "references": [ + Reference( + reference_id="", + url="http://mailman.nginx.org/pipermail/nginx-announce/2021/000300.html", + severities=[ + VulnerabilitySeverity(system=severity_systems.GENERIC, value="medium") + ], + ), + Reference( + reference_id="CVE-2021-23017", + url="https://nvd.nist.gov/vuln/detail/CVE-2021-23017", + ), + Reference( + reference_id="", + url="https://nginx.org/download/patch.2021.resolver.txt", + ), + Reference( + reference_id="", url="https://nginx.org/download/patch.2021.resolver.txt.asc" + ), + ], + } + + result = nginx.parse_advisory_data_from_paragraph(vuln_info) + assert result.to_dict() == expected + + def test_advisory_data_from_text(self): + test_file = self.get_test_loc("security_advisories.html") + with open(test_file) as tf: + test_text = tf.read() + + expected_file = self.get_test_loc("security_advisories.json", must_exist=False) + + results = [na.to_dict() for na in nginx.advisory_data_from_text(test_text)] + util_tests.check_results_against_json(results, expected_file) diff --git a/vulnerabilities/tests/util_tests.py b/vulnerabilities/tests/util_tests.py new file mode 100644 index 000000000..1ff0887d2 --- /dev/null +++ b/vulnerabilities/tests/util_tests.py @@ -0,0 +1,64 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# http://nexb.com and https://github.com/nexB/vulnerablecode/ +# The VulnerableCode software is licensed under the Apache License version 2.0. +# Data generated with VulnerableCode require an acknowledgment. +# +# You may not use this software except in compliance with the License. +# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# +# When you publish or redistribute any data created with VulnerableCode or any VulnerableCode +# derivative work, you must accompany this data with the following acknowledgment: +# +# Generated with VulnerableCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES +# OR CONDITIONS OF ANY KIND, either express or implied. No content created from +# VulnerableCode should be considered or used as legal advice. Consult an Attorney +# for any legal advice. +# VulnerableCode is a free software code scanning tool from nexB Inc. and others. +# Visit https://github.com/nexB/vulnerablecode/ for support and download. + +import json +import os + +import saneyaml + +""" +Shared testing utilities +""" + +# Used for tests to regenerate fixtures with regen=True: run a test with this +# env. var set to any value to regenarte expected result files. For example with: +# "VULNERABLECODE_REGEN_TEST_FIXTURES=yes pytest -vvs vulnerabilities/tests" +VULNERABLECODE_REGEN_TEST_FIXTURES = os.getenv("VULNERABLECODE_REGEN_TEST_FIXTURES", False) + + +def check_results_against_json( + results, + expected_file, + regen=VULNERABLECODE_REGEN_TEST_FIXTURES, +): + """ + Check the JSON-serializable mapping or sequence ``results`` against the + expected data in the JSON ``expected_file`` + + If ``regen`` is True, the ``expected_file`` is overwritten with the + ``results`` data. This is convenient for updating tests expectations. + """ + if regen: + with open(expected_file, "w") as reg: + json.dump(results, reg, indent=2, separators=(",", ": ")) + expected = results + else: + with open(expected_file) as exp: + expected = exp.read() + + # NOTE we redump the JSON as a YAML string for easier display of + # the failures comparison/diff + if results != expected: + expected = saneyaml.dump(expected) + results = saneyaml.dump(results) + assert results == expected