SHARE
TWEET

Python-safety-safety.py

a guest Oct 31st, 2017 20 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # -*- coding: utf-8 -*-
  2. import click
  3. import pip
  4. import requests
  5. from packaging.specifiers import SpecifierSet
  6. from .errors import DatabaseFetchError
  7. from .constants import DATABASE_MIRRORS, REQUEST_TIMEOUT
  8. from collections import namedtuple
  9.  
  10.  
  11. class Vulnerability(namedtuple("Vulnerability", ["name", "spec", "version", "data"])):
  12.  
  13.     @property
  14.     def source(self):
  15.         return self.cve_id if self.is_cve else "changelog"
  16.  
  17.     @property
  18.     def is_cve(self):
  19.         return "cve" in self.data
  20.  
  21.     @property
  22.     def is_changelog(self):
  23.         return "changelog" in self.data
  24.  
  25.     @property
  26.     def cve_id(self):
  27.         return self.data["cve"]
  28.  
  29.     @property
  30.     def description(self):
  31.         return self.data["description"] if self.is_cve else self.data["changelog"]
  32.  
  33.  
  34. def fetch_database(full=False):
  35.     for mirror in DATABASE_MIRRORS:
  36.         db_name = "insecure_full.json" if full else "insecure.json"
  37.         url = mirror + db_name
  38.         r = requests.get(url=url, timeout=REQUEST_TIMEOUT)
  39.         return r.json()
  40.     raise DatabaseFetchError()
  41.  
  42.  
  43. def get_vulnerabilities(pkg, spec, db):
  44.     for entry in db[pkg]:
  45.         if spec == entry["v"]:
  46.             yield entry
  47.  
  48.  
  49. def check(packages):
  50.     db = fetch_database()
  51.     db_full = None
  52.     vulnerable_packages = frozenset(db.keys())
  53.     vulnerable = []
  54.     for pkg in packages:
  55.         # normalize the package name, the safety-db is converting underscores to dashes and uses
  56.         # lowercase
  57.         name = pkg.key.replace("_", "-").lower()
  58.  
  59.         if name in vulnerable_packages:
  60.             # we have a candidate here, build the spec set
  61.             for specifier in db[name]:
  62.                 spec_set = SpecifierSet(specifiers=specifier)
  63.                 if spec_set.contains(pkg.version):
  64.                     if not db_full:
  65.                         db_full = fetch_database(full=True)
  66.                     for data in get_vulnerabilities(pkg=name, spec=specifier, db=db_full):
  67.                         vulnerable.append(
  68.                             Vulnerability(name=name, spec=specifier, version=pkg.version, data=data)
  69.                         )
  70.     return vulnerable
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top