Skip to content

Commit

Permalink
➕ Add Apache HTTPD advisory importer
Browse files Browse the repository at this point in the history
Signed-off-by: Shivam Sandbhor <[email protected]>
  • Loading branch information
sbs2001 committed Sep 28, 2020
1 parent 8efdbd1 commit 4b89ef1
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 0 deletions.
9 changes: 9 additions & 0 deletions vulnerabilities/importer_yielder.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@
'data_source': 'ProjectKBMSRDataSource',
'data_source_cfg': {
'etag': {}
}
},
{
'name': 'apache_httpd',
'license': '',
'last_run': None,
'data_source': 'ApacheHTTPDDataSource',
'data_source_cfg': {
'etags': {}
},
},

Expand Down
1 change: 1 addition & 0 deletions vulnerabilities/importers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@
from vulnerabilities.importers.github import GitHubAPIDataSource
from vulnerabilities.importers.nvd import NVDDataSource
from vulnerabilities.importers.project_kb_msr2019 import ProjectKBMSRDataSource
from vulnerabilities.importers.apache_httpd import ApacheHTTPDDataSource
106 changes: 106 additions & 0 deletions vulnerabilities/importers/apache_httpd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# 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 tool from nexB Inc. and others.
# Visit https://github.com/nexB/vulnerablecode/ for support and download.

from dataclasses import dataclass
import xml.etree.ElementTree as ET

import requests
from packageurl import PackageURL

from vulnerabilities.data_source import Advisory
from vulnerabilities.data_source import DataSource
from vulnerabilities.data_source import DataSourceConfiguration


@dataclass
class ApacheHTTPDDataSourceConfiguration(DataSourceConfiguration):
etags: dict


class ApacheHTTPDDataSource(DataSource):

CONFIG_CLASS = ApacheHTTPDDataSourceConfiguration
url = "https://httpd.apache.org/security/vulnerabilities-httpd.xml"

def updated_advisories(self):
# Etags are like hashes of web responses. We maintain
# (url, etag) mappings in the DB. `create_etag` creates
# (url, etag) pair. If a (url, etag) already exists then the code
# skips processing the response further to avoid duplicate work

if self.create_etag(self.url):
data = fetch_xml(self.url)
advisories = to_advisories(data)
return self.batch_advisories(advisories)

return []

def create_etag(self, url):
etag = requests.head(url).headers.get("ETag")
if not etag:
return True

elif url in self.config.etags:
if self.config.etags[url] == etag:
return False

self.config.etags[url] = etag
return True


def to_advisories(data):
advisories = []
for issue in data:
resolved_packages = []
impacted_packages = []
for info in issue:
if info.tag == "cve":
cve = info.attrib["name"]

if info.tag == "title":
summary = info.text

if info.tag == "fixed":
resolved_packages.append(
PackageURL(name="httpd", version=info.attrib["version"], type="generic")
)

if info.tag == "affects" or info.tag == "maybeaffects":
impacted_packages.append(
PackageURL(name="httpd", version=info.attrib["version"], type="generic")
)

advisories.append(
Advisory(
cve_id=cve,
summary=summary,
impacted_package_urls=impacted_packages,
resolved_package_urls=resolved_packages,
)
)

return advisories


def fetch_xml(url):
resp = requests.get(url).content
return ET.fromstring(resp)

0 comments on commit 4b89ef1

Please sign in to comment.