pyupio/safety

Feature request: run from Python

joosbuijsNL opened this issue · 5 comments

  • safety version: 1.10.3
  • Python version: 3.6/3.7/3.8/3.9
  • Operating System: Windows

Description

We would like to implement a check at the beginning of our code whether all used packages are safe, according to 'safety'. Is it / would it be possible to run safety from Python, inspecting the current work environment, and allowing the Python code then to determine whether it can continue safely or whether there is an issue? This would put many (manager)minds at ease :)

I'm aware of the possibility of Python to run commands, but I would prefer a more pythonic approach.

What I Did

Read the documentation and search the internet.

We are interested in this too.

Hi! I'm sorry for the late on this thread.

Right now, there is a Safety version 2.0b5 on PyPi.

This version includes support for running Python directly in your code; here there is a small example:

from safety import safety
from safety.formatter import SafetyFormatter

requirements_to_analyze = ['requirements.txt']

files = [open(f, 'r') for f in requirements_to_analyze]

packages = safety.get_packages(files=files, stdin=False)

key = 'YOUR_API_KEY_HERE'
ignore_severity_rules = None
ignore = {}
db = ''
cache = 0
proxy_config = None

vulns, db_full = safety.check(packages=packages, key=key, db_mirror=db, cached=cache, ignore_vulns=ignore, ignore_severity_rules=ignore_severity_rules, proxy=proxy_config,
include_ignored=True)

remediations = safety.calculate_remediations(vulns, db_full)

for vuln in vulns:
    print(vuln.vulnerability_id)
    print(vuln.advisory)

output_report = SafetyFormatter(output='json').render_vulnerabilities([], vulns, remediations, True, packages)

I will close this feature request; if you find issues, file a new issue in this repository. Thanks!

Thanks, I will give this a go. Quick question, what site do the rules get downloaded from? I will need to open up our internel internet proxy for that...

Also is there any way to get the requirements.txt' from the current virtual environment safety is running on without passing the requirements.txt to it?

We have developed the following function which does not check requirements.txt but all available/installed packages in the current environment, and even quits the application when issues are found.

Use at your own risk.

Any code improvements/suggestions are welcome.

def safety_check(abort=True):
    """
    Performs a safety check on all packages in this Python environment.
    Input parameter:
    - abort (default:True) When True, the application will abort (sys.exit(1) 
    when unsafe packages are found.

    Returns (if abort=False) a list of vulnerabilities or None if all is OK. 
    This allows for a test like `if safety_check(abort=False): DO SOMETHING TO SHUT DOWN`
    """
    # Joos Buijs 2021-09-14
    # Based on https://github.com/pyupio/safety/blob/master/safety/cli.py

    from safety import safety
    from safety.formatter import report
    from safety.util import get_proxy_dict

    import sys

    import pkg_resources
    packages = [
        d for d in pkg_resources.working_set
        if d.key not in {"python", "wsgiref", "argparse"}
    ]    

    abort_text = "We will abort if we find any unsafe packages." if abort else ""
    logger.info(f"Checking {len(packages)} packages for potential security issues before we start. {abort_text}")

    # Command line arguments / defaults
    key = ""
    db = ""
    json = False
    full_report = False
    bare = False
    stdin = False
    files = None
    cache = False
    ignore = []
    output = ""
    proxyprotocol = 'https' # default http
    proxyhost = None
    proxyport = 80

    proxy_dictionary = get_proxy_dict(proxyprotocol, proxyhost, proxyport)
    vulns = safety.check(packages=packages, key=key, db_mirror=db, cached=cache, ignore_ids=ignore, proxy=proxy_dictionary)

    if vulns:
        output_report = report(vulns=vulns, 
                            full=full_report, 
                            json_report=json, 
                            bare_report=bare,
                            checked_packages=len(packages),
                            db=db, 
                            key=key
                            )
        print(output_report) # print/show report for user to act on
        print("The environment is not safe! See the report above for more details.")
        # ABORT your application now!
        if abort:
            sys.exit(1)
        else:
            return output_report
    # Else: all OK, carry on
    return None