Пример #1
0
def check(key, db, full_report, stdin, files, cache):

    if files and stdin:
        click.secho(
            "Can't read from --stdin and --file at the same time, exiting",
            fg="red")
        sys.exit(-1)

    if files:
        packages = itertools.chain.from_iterable(
            read_requirements(f, resolve=True) for f in files)
    elif stdin:
        packages = read_requirements(sys.stdin)
    else:
        packages = pip.get_installed_distributions()

    try:
        vulns = safety.check(packages=packages,
                             key=key,
                             db_mirror=db,
                             cached=cache)
        click.secho(report(vulns=vulns, full=full_report))
        sys.exit(-1 if vulns else 0)
    except InvalidKeyError:
        click.secho("Your API Key is invalid", fg="red")
        sys.exit(-1)
    except DatabaseFileNotFoundError:
        click.secho(
            "Unable to load vulnerability database from {db}".format(db=db),
            fg="red")
        sys.exit(-1)
    except DatabaseFetchError:
        click.secho("Unable to load vulnerability database", fg="red")
        sys.exit(-1)
Пример #2
0
    def test_check_live_cached(self):
        from safety.constants import CACHE_FILE

        # lets clear the cache first
        try:
            with open(CACHE_FILE, 'w') as f:
                f.write(json.dumps({}))
        except Exception:
            pass

        reqs = StringIO("insecure-package==0.1")
        packages = util.read_requirements(reqs)

        vulns, _ = safety.check(packages=packages,
                                key=None,
                                db_mirror=False,
                                cached=60 * 60,
                                ignore_vulns={},
                                ignore_severity_rules=None,
                                proxy={},
                                telemetry=False)
        self.assertEqual(len(vulns), 1)

        reqs = StringIO("insecure-package==0.1")
        packages = util.read_requirements(reqs)
        # make a second call to use the cache
        vulns, _ = safety.check(packages=packages,
                                key=None,
                                db_mirror=False,
                                cached=60 * 60,
                                ignore_vulns={},
                                ignore_severity_rules=None,
                                proxy={},
                                telemetry=False)
        self.assertEqual(len(vulns), 1)
Пример #3
0
    def test_check_live_cached(self):
        reqs = StringIO("insecure-package==0.1")
        packages = util.read_requirements(reqs)

        vulns = safety.check(
            packages=packages,
            db_mirror=False,
            cached=True,
            key=False,
            ignore_ids=[],
            proxy={},
        )
        self.assertEqual(len(vulns), 1)

        reqs = StringIO("insecure-package==0.1")
        packages = util.read_requirements(reqs)
        # make a second call to use the cache
        vulns = safety.check(
            packages=packages,
            db_mirror=False,
            cached=True,
            key=False,
            ignore_ids=[],
            proxy={},
        )
        self.assertEqual(len(vulns), 1)
Пример #4
0
    def test_check_live_down_cached(self):
        reqs = StringIO("insecure-package==0.1")
        packages = util.read_requirements(reqs)

        vulns = safety.check(
            packages=packages,
            db_mirror=False,
            cached=True,
            key=False,
            ignore_ids=[],
            proxy={}
        )
        self.assertEqual(len(vulns), 1)
        
        reqs = StringIO("insecure-package==0.1")
        packages = util.read_requirements(reqs)
        # make a second call, where server responds with 400 error, so use
        # the cache
        vulns = safety.check(
            packages=packages,
            db_mirror="http://pyup.io/",
            cached=False,
            key=False,
            ignore_ids=[],
            proxy={}
        )
        self.assertEqual(len(vulns), 1)
Пример #5
0
def check(key, db, json, full_report, bare, stdin, files, pipfile, cache, ignore, output, proxyprotocol, proxyhost, proxyport):
    if (files or pipfile) and stdin:
        click.secho("Can't read from --stdin and --file at the same time, exiting", fg="red", file=sys.stderr)
        sys.exit(-1)

    if files:
        packages = list(itertools.chain.from_iterable(read_requirements(f, resolve=True) for f in files))
    elif pipfile:
        packages = list(read_pipfile(pipfile))
    elif stdin:
        packages = list(read_requirements(sys.stdin))
    else:
        import pkg_resources
        packages = [
            d for d in pkg_resources.working_set
            if d.key not in {"python", "wsgiref", "argparse"}
        ]    
    proxy_dictionary = {}
    if proxyhost is not None:
        if proxyprotocol in ["http", "https"]:
            proxy_dictionary = {proxyprotocol: "{0}://{1}:{2}".format(proxyprotocol, proxyhost, str(proxyport))}
        else:
            click.secho("Proxy Protocol should be http or https only.", fg="red")
            sys.exit(-1)
    try:
        vulns = safety.check(packages=packages, key=key, db_mirror=db, cached=cache, ignore_ids=ignore, proxy=proxy_dictionary)
        output_report = report(vulns=vulns, 
                               full=full_report, 
                               json_report=json, 
                               bare_report=bare,
                               checked_packages=len(packages), 
                               db=db, 
                               key=key)

        if output:
            with open(output, 'w+') as output_file:
                output_file.write(output_report)
        else:
            click.secho(output_report, nl=False if bare and not vulns else True)
        sys.exit(-1 if vulns else 0)
    except InvalidKeyError:
        click.secho("Your API Key '{key}' is invalid. See {link}".format(
            key=key, link='https://goo.gl/O7Y1rS'),
            fg="red",
            file=sys.stderr)
        sys.exit(-1)
    except DatabaseFileNotFoundError:
        click.secho("Unable to load vulnerability database from {db}".format(db=db), fg="red", file=sys.stderr)
        sys.exit(-1)
    except DatabaseFetchError:
        click.secho("Unable to load vulnerability database", fg="red", file=sys.stderr)
        sys.exit(-1)
Пример #6
0
def license(key, db, cache, files, proxyprotocol, proxyhost, proxyport):

    if files:
        packages = list(itertools.chain.from_iterable(read_requirements(f, resolve=True) for f in files))
    else:
        import pkg_resources
        packages = [
            d for d in pkg_resources.working_set
            if d.key not in {"python", "wsgiref", "argparse"}
        ]  
   
    proxy_dictionary = get_proxy_dict(proxyprotocol, proxyhost, proxyport)
    try:
        licenses_db = safety.get_licenses(key, db, cache, proxy_dictionary)
    except InvalidKeyError:
        click.secho("Your API Key '{key}' is invalid. See {link}".format(
            key=key, link='https://goo.gl/O7Y1rS'),
            fg="red",
            file=sys.stderr)
        sys.exit(-1)
    except DatabaseFileNotFoundError:
        click.secho("Unable to load licenses database from {db}".format(db=db), fg="red", file=sys.stderr)
        sys.exit(-1)
    except TooManyRequestsError:
        click.secho("Unable to load licenses database (Too many requests, please wait before another request)",
            fg="red",
            file=sys.stderr
        )
        sys.exit(-1)
    except DatabaseFetchError:
        click.secho("Unable to load licenses database", fg="red", file=sys.stderr)
        sys.exit(-1)
    filtered_packages_licenses = get_packages_licenses(packages, licenses_db)
    output_report = license_report(packages=packages, licenses=filtered_packages_licenses)
    click.secho(output_report, nl=True)
Пример #7
0
    def test_get_packages_licenses(self):
        reqs = StringIO("Django==1.8.1\n\rinvalid==1.0.0")
        packages = util.read_requirements(reqs)
        licenses_db = safety.get_licenses(
            db_mirror=os.path.join(
                os.path.dirname(os.path.realpath(__file__)),
                "test_db"
            ),
            cached=False,
            key="foobarqux",
            proxy={},
        )
        self.assertIn("licenses", licenses_db)
        self.assertIn("packages", licenses_db)
        self.assertIn("BSD-3-Clause", licenses_db['licenses'])
        self.assertIn("django", licenses_db['packages'])

        pkg_licenses = util.get_packages_licenses(packages, licenses_db)

        self.assertIsInstance(pkg_licenses, list)
        for pkg_license in pkg_licenses:
            license = pkg_license['license']
            version = pkg_license['version']
            if pkg_license['package'] == 'django':
                self.assertEqual(license, 'BSD-3-Clause')
                self.assertEqual(version, '1.8.1')
            elif pkg_license['package'] == 'invalid':
                self.assertEqual(license, 'N/A')
                self.assertEqual(version, '1.0.0')
            else:
                raise AssertionError(
                    "unexpected package '" + pkg_license['package'] + "' was found"
                )
Пример #8
0
    def test_report_licenses_bare(self):
        from safety.formatter import license_report

        reqs = StringIO("Django==1.8.1\n\rinexistent==1.0.0")
        packages = util.read_requirements(reqs)

        # Using DB: test.test_db.licenses.json
        licenses_db = safety.get_licenses(
            db_mirror=os.path.join(
                os.path.dirname(os.path.realpath(__file__)),
                "test_db"
            ),
            cached=False,
            key=None,
            proxy={},
        )

        pkgs_licenses = util.get_packages_licenses(packages, licenses_db)
        output_report = license_report(
            packages=packages,
            licenses=pkgs_licenses,
            json_report=False,
            bare_report=True
        )
        self.assertEqual(output_report, "BSD-3-Clause")
Пример #9
0
 def test_unpinned_vcs_requirement(self):
     """
     https://github.com/pyupio/safety/issues/72
     """
     # this shouldn't raise an error
     content = StringIO("-e git+https://github.com/jdunck/python-unicodecsv#egg=unicodecsv")
     result = list(read_requirements(content))
     self.assertEqual(len(result), 0)
Пример #10
0
def check(key, db, json, full_report, bare, stdin, files, cache, ignore):

    if files and stdin:
        click.secho(
            "Can't read from --stdin and --file at the same time, exiting",
            fg="red")
        sys.exit(-1)

    if files:
        packages = list(
            itertools.chain.from_iterable(
                read_requirements(f, resolve=True) for f in files))
    elif stdin:
        packages = list(read_requirements(sys.stdin))
    else:
        packages = get_installed_distributions()

    try:
        vulns = safety.check(packages=packages,
                             key=key,
                             db_mirror=db,
                             cached=cache,
                             ignore_ids=ignore)
        click.secho(
            report(vulns=vulns,
                   full=full_report,
                   json_report=json,
                   bare_report=bare,
                   checked_packages=len(packages),
                   db=db,
                   key=key))
        sys.exit(-1 if vulns else 0)
    except InvalidKeyError:
        click.secho("Your API Key '{key}' is invalid. See {link}".format(
            key=key, link='https://goo.gl/O7Y1rS'),
                    fg="red")
        sys.exit(-1)
    except DatabaseFileNotFoundError:
        click.secho(
            "Unable to load vulnerability database from {db}".format(db=db),
            fg="red")
        sys.exit(-1)
    except DatabaseFetchError:
        click.secho("Unable to load vulnerability database", fg="red")
        sys.exit(-1)
Пример #11
0
    def test_check_live(self):
        reqs = StringIO("insecure-package==0.1")
        packages = util.read_requirements(reqs)

        vulns = safety.check(packages=packages,
                             db_mirror=False,
                             cached=False,
                             key=False)
        self.assertEqual(len(vulns), 1)
Пример #12
0
 def test_recursive_requirement(self):
     """
     https://github.com/pyupio/safety/issues/132
     """
     # this should find 2 bad packages
     dirname = os.path.dirname(__file__)
     test_filename = os.path.join(dirname, "reqs_1.txt")
     with open(test_filename) as fh:
         result = list(read_requirements(fh, resolve=True))
     self.assertEqual(len(result), 2)
Пример #13
0
    def test_check_from_file(self):
        reqs = StringIO("Django==1.8.1")
        packages = util.read_requirements(reqs)

        vulns = safety.check(packages=packages,
                             db_mirror=os.path.join(
                                 os.path.dirname(os.path.realpath(__file__)),
                                 "test_db"),
                             cached=False,
                             key=False)
        self.assertEqual(len(vulns), 2)
Пример #14
0
    def test_multiple_versions(self):
        reqs = StringIO("Django==1.8.1\n\rDjango==1.7.0")
        packages = util.read_requirements(reqs)

        vulns = safety.check(packages=packages,
                             db_mirror=os.path.join(
                                 os.path.dirname(os.path.realpath(__file__)),
                                 "test_db"),
                             cached=False,
                             key=False,
                             ignore_ids=[])
        self.assertEqual(len(vulns), 4)
Пример #15
0
 def safety():  # noqa: WPS430
     packages = list(read_requirements(StringIO(requirements)))
     vulns = safety_check(packages=packages,
                          ignore_ids="",
                          key="",
                          db_mirror="",
                          cached=False,
                          proxy={})
     output_report = report(vulns=vulns,
                            full=True,
                            checked_packages=len(packages))
     if vulns:
         print(output_report)
Пример #16
0
    def test_check_live(self):
        reqs = StringIO("insecure-package==0.1")
        packages = util.read_requirements(reqs)

        vulns, _ = safety.check(packages=packages,
                                key=None,
                                db_mirror=False,
                                cached=0,
                                ignore_vulns={},
                                ignore_severity_rules=None,
                                proxy={},
                                telemetry=False)

        self.assertEqual(len(vulns), 1)
Пример #17
0
 def check_vulns():
     packages = list(read_requirements(StringIO(requirements)))
     vulns = safety.check(packages=packages,
                          ignore_ids="41002",
                          key="",
                          db_mirror="",
                          cached=False,
                          proxy={})
     output_report = report(vulns=vulns,
                            full=True,
                            checked_packages=len(packages))
     print(vulns)
     if vulns:
         print(output_report)
Пример #18
0
def check(key, db, json, full_report, bare, stdin, files, cache, ignore):

    if files and stdin:
        click.secho("Can't read from --stdin and --file at the same time, exiting", fg="red")
        sys.exit(-1)

    if files:
        packages = list(itertools.chain.from_iterable(read_requirements(f, resolve=True) for f in files))
    elif stdin:
        packages = list(read_requirements(sys.stdin))
    else:
        packages = get_installed_distributions()

    try:
        vulns = safety.check(packages=packages, key=key, db_mirror=db, cached=cache, ignore_ids=ignore)
        click.secho(report(
            vulns=vulns,
            full=full_report,
            json_report=json,
            bare_report=bare,
            checked_packages=len(packages),
            db=db,
            key=key
            )
        )
        sys.exit(-1 if vulns else 0)
    except InvalidKeyError:
        click.secho("Your API Key '{key}' is invalid. See {link}".format(
            key=key, link='https://goo.gl/O7Y1rS'),
            fg="red")
        sys.exit(-1)
    except DatabaseFileNotFoundError:
        click.secho("Unable to load vulnerability database from {db}".format(db=db), fg="red")
        sys.exit(-1)
    except DatabaseFetchError:
        click.secho("Unable to load vulnerability database", fg="red")
        sys.exit(-1)
Пример #19
0
    def test_report_licenses_json(self, get_report_brief_info):
        get_report_brief_info.return_value = {
            'scan_target': 'environment',
            'scanned': ['/usr/local/lib/python3.9/site-packages'],
            'api_key': True,
            'packages_found': 2,
            'timestamp': '2022-03-03 16:31:30',
            'safety_version': '2.0.0.dev6'
        }

        reqs = StringIO("Django==1.8.1\n\rinexistent==1.0.0")
        packages = util.read_requirements(reqs)

        # Using DB: test.test_db.licenses.json
        licenses_db = safety.get_licenses(db_mirror=os.path.join(
            os.path.dirname(os.path.realpath(__file__)), "test_db"),
                                          cached=0,
                                          key=None,
                                          proxy={},
                                          telemetry=False)

        pkgs_licenses = util.get_packages_licenses(packages, licenses_db)
        output_report = SafetyFormatter(output='json').render_licenses(
            [], pkgs_licenses)

        expected_result = json.dumps(
            {
                "report_meta": {
                    "scan_target": "environment",
                    "scanned": ["/usr/local/lib/python3.9/site-packages"],
                    "api_key": True,
                    "packages_found": 2,
                    "timestamp": "2022-03-03 16:31:30",
                    "safety_version": "2.0.0.dev6"
                },
                "announcements": [],
                "licenses": [{
                    "package": "django",
                    "version": "1.8.1",
                    "license": "BSD-3-Clause"
                }, {
                    "package": "inexistent",
                    "version": "1.0.0",
                    "license": "unknown",
                }]
            },
            indent=4)
        # Packages without license are reported as "N/A"
        self.assertEqual(output_report.rstrip(), expected_result)
Пример #20
0
    def test_check_from_file(self):
        reqs = StringIO("Django==1.8.1")
        packages = util.read_requirements(reqs)

        vulns, _ = safety.check(
            packages=packages,
            key=None,
            db_mirror=os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                   "test_db"),
            cached=0,
            ignore_vulns={},
            ignore_severity_rules=None,
            proxy={},
            telemetry=False)
        self.assertEqual(len(vulns), 2)
Пример #21
0
 def parse(file_name):
     reqs = []
     try:
         with open(file_name) as fh:
             for item in read_requirements(fh):
                 if isinstance(item, SafetyPackage):
                     reqs.append(item)
                 elif isinstance(item, SafetyRequirementFile):
                     for other_file in parse(item.path):
                         yield other_file
             if reqs:
                 yield RequirementFile(project=self,
                                       requirements=reqs,
                                       path=file_name)
     except:
         pass
Пример #22
0
    def test_multiple_versions(self):
        # Probably used for external tools using safety.check directly
        reqs = StringIO("Django==1.8.1\n\rDjango==1.7.0")
        packages = util.read_requirements(reqs)

        vulns, _ = safety.check(
            packages=packages,
            key=None,
            db_mirror=os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                   "test_db"),
            cached=0,
            ignore_vulns={},
            ignore_severity_rules=None,
            proxy={},
            telemetry=False)
        self.assertEqual(len(vulns), 4)
Пример #23
0
    def test_check_from_file_with_hash_pins(self):
        reqs = StringIO((
            "Django==1.8.1 "
            "--hash=sha256:c6c7e7a961e2847d050d214ca96dc3167bb5f2b25cd5c6cb2eea96e1717f4ade"
        ))
        packages = util.read_requirements(reqs)

        vulns = safety.check(packages=packages,
                             db_mirror=os.path.join(
                                 os.path.dirname(os.path.realpath(__file__)),
                                 "test_db"),
                             cached=False,
                             key=False,
                             ignore_ids=[],
                             proxy={})
        self.assertEqual(len(vulns), 2)
Пример #24
0
    def test_report_licenses_bare(self):
        reqs = StringIO("Django==1.8.1\n\rinexistent==1.0.0")
        packages = util.read_requirements(reqs)

        # Using DB: test.test_db.licenses.json
        licenses_db = safety.get_licenses(db_mirror=os.path.join(
            os.path.dirname(os.path.realpath(__file__)), "test_db"),
                                          cached=0,
                                          key=None,
                                          proxy={},
                                          telemetry=False)

        pkgs_licenses = util.get_packages_licenses(packages, licenses_db)
        output_report = SafetyFormatter(output='bare').render_licenses(
            [], pkgs_licenses)

        self.assertEqual(output_report, "BSD-3-Clause unknown")
Пример #25
0
    def test_report_licenses_json(self):
        from safety.formatter import license_report

        reqs = StringIO("Django==1.8.1\n\rinexistent==1.0.0")
        packages = util.read_requirements(reqs)

        # Using DB: test.test_db.licenses.json
        licenses_db = safety.get_licenses(
            db_mirror=os.path.join(
                os.path.dirname(os.path.realpath(__file__)),
                "test_db"
            ),
            cached=False,
            key=None,
            proxy={},
        )

        pkgs_licenses = util.get_packages_licenses(packages, licenses_db)
        output_report = license_report(
            packages=packages,
            licenses=pkgs_licenses,
            json_report=True,
            bare_report=False
        )

        expected_result = json.dumps(
            [{
                "license": "BSD-3-Clause",
                "package": "django",
                "version": "1.8.1"
            },
            {
                "license": "N/A",
                "package": "inexistent",
                "version": "1.0.0"
            }],
            indent=4, sort_keys=True
        )
        # Packages without license are reported as "N/A"
        self.assertEqual(output_report.rstrip(), expected_result)