Source code for swh.web.vulns.api_views

# Copyright (C) 2026  The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU Affero General Public License version 3, or any later version
# See top-level LICENSE file for more information

import grpc

from rest_framework.request import Request

from swh.vulns.grpc.swhvulns_pb2 import AffectingVulnerabilitiesRequest
from swh.vulns.grpc.swhvulns_pb2_grpc import VulnerabilityServiceStub
from swh.web.api.apidoc import api_doc
from swh.web.api.apiurls import APIUrls, api_route
from swh.web.config import get_config
from swh.web.utils.url_path_converters import register_url_path_converters

_GRPC_CHANNEL = None

vulns_api_urls = APIUrls()

register_url_path_converters()


def _grpc_channel():
    global _GRPC_CHANNEL
    if _GRPC_CHANNEL is None:
        config = get_config()["vulns"]
        if config["secure"]:
            _GRPC_CHANNEL = grpc.secure_channel(config["address"])
        else:
            _GRPC_CHANNEL = grpc.insecure_channel(config["address"])
    return _GRPC_CHANNEL


[docs] @api_route( r"/revision/(?P<sha1_git>[0-9a-f]+)/vulnerabilities/", "api-1-revision-vulnerabilities", checksum_args=["sha1_git"], api_urls=vulns_api_urls, ) @api_doc("/revision/vulnerabilities/", category="Metadata") def api_revision_vulnerabilities(request: Request, sha1_git: str): """ .. http:get:: /api/1/revision/(sha1_git)/directory/[(path)/] Get known vulnerabilities affecting the revision identified by ``sha1_git``. :statuscode 200: no error :statuscode 400: an invalid **sha1_git** value has been provided :>jsonarr array vulnerability.ids: array of strings, each of which is an identifier of the vulnerability :>jsonarr tool.name string: name of the tool used to identify the revision is vulnerable to this vulnerability :>jsonarr tool.variant string: optional human-readable description of the tool's configuration :>jsonarr source.name string: name of the database the vulnerability report comes from :>jsonarr source.version string: optional date of the database capture """ # we never return 404 because: # 1. we may, theoretically, have vulnerability reports that reference revisions # that we don't know about # 2. even if a revision is masked or taken down, there is no reason to hide # vulnerability reports that mention it (like we don't hide git submodules # that reference it either) grpc_request = AffectingVulnerabilitiesRequest( swhid=[f"swh:1:rev:{sha1_git}"], ) stub = VulnerabilityServiceStub(_grpc_channel()) response = stub.AffectingVulnerabilities(grpc_request) results = [ { "vulnerability": { "ids": list(item.vulnerability.id), }, "tool": item.tool and { "name": item.tool.name, "variant": item.tool.variant, }, "source": item.source and { "name": item.source.name, "version": item.source.version, }, } for item in response ] return {"results": results}