diff --git a/.safety-project.ini b/.safety-project.ini new file mode 100644 index 00000000..adfeac03 --- /dev/null +++ b/.safety-project.ini @@ -0,0 +1,5 @@ +[project] +id = safety +url = /projects/44af96bd-956f-478f-9285-1389f622b182/findings +name = safety + diff --git a/safety/scan/command.py b/safety/scan/command.py index 377757bc..181015c1 100644 --- a/safety/scan/command.py +++ b/safety/scan/command.py @@ -995,12 +995,7 @@ def scan(ctx: typer.Context, with console.status(wait_msg, spinner=DEFAULT_SPINNER): if use_server_matching: - # Handle the server-matching case response_json = process_files(paths=file_paths, config=config, use_server_matching=True, obj=ctx.obj, target=target) - # from safety.scan.test_json import test_json - # with open("safety/scan/test.json", 'r') as file: - # test_json = json.load(file) - # response_json = test_json projects = safe_get(response_json, ["scan_results", "projects"], []) for project in projects: project_files = project.get("files", []) @@ -1018,6 +1013,13 @@ def scan(ctx: typer.Context, to_fix_spec = [] file_matched_for_fix = file_data.get("type") in fix_file_types + for spec in affected_specifications: + if spec["vulnerabilities"]: + if len(spec["vulnerabilities"]["known_vulnerabilities"]) < MIN_DETAILED_OUTPUT_THRESHOLD: + detailed_output = True + break + + # Handle files with affected specifications if any(affected_specifications): dependency_vuln_detected = detect_dependency_vulnerabilities(console, dependency_vuln_detected) @@ -1030,6 +1032,8 @@ def scan(ctx: typer.Context, # Print vulnerabilities for each specification console.print() for dependency in dependencies: + + for specification in dependency.get("specifications", []): vulns_to_report = sort_and_filter_vulnerabilities_json( safe_get(specification, ["vulnerabilities", "known_vulnerabilities"], []), @@ -1038,35 +1042,38 @@ def scan(ctx: typer.Context, critical_vulns_count = count_critical_vulnerabilities_json(vulns_to_report) vulns_found = len(vulns_to_report) vuln_word = pluralize("vulnerability", vulns_found) - spec_name = dependency.get("name") - spec_raw = specification.get("raw", "") - msg = generate_vulnerability_message(spec_name, spec_raw, vulns_found, critical_vulns_count, vuln_word) - console.print(Padding(f"{msg}]", PADDING_VALUES), emoji=True, overflow="crop") - - if detailed_output or vulns_found < MIN_DETAILED_OUTPUT_THRESHOLD: - render_vulnerabilities_json(vulns_to_report, console, detailed_output) - - lines, resolved_vulns, fixes = generate_remediation_details_json(spec, spec_name, vuln_word, critical_vulns_count) - total_resolved_vulns += resolved_vulns - fixes_count += fixes - - for line in lines: - console.print(Padding(line, PADDING_VALUES), emoji=True) - - # construct the url HERE - # https://data.safetycli.com/p/pypi/django/eda/?from=2.2&to=4.2.17 - # Construct this with 3 inputs- django, raw, - remediation = safe_get(spec, ["vulnerabilities", "remediation"], {}) - recommended = remediation.get("recommended") - URL_PREFIX = "https://data.safetycli.com/p/pypi/" - URL_MIDDLE = "/eda/?from=" - URL_END = "&to=" - more_info_url = URL_PREFIX+spec_name+URL_MIDDLE+spec_raw.split("==")[1]+URL_END+recommended - - if more_info_url: - console.print( - Padding(MSG_LEARN_MORE.format(more_info_url), PADDING_VALUES), emoji=True - ) + spec_name = dependency.get("name").lower() + spec_raw = specification.get("raw").lower() + + + if (spec_name in spec_raw): + if vulns_found != 0: + msg = generate_vulnerability_message(spec_name, spec_raw, vulns_found, critical_vulns_count, vuln_word) + console.print(Padding(f"{msg}]", PADDING_VALUES), emoji=True, overflow="crop") + + if detailed_output: + render_vulnerabilities_json(vulns_to_report, console, detailed_output) + lines, resolved_vulns, fixes = generate_remediation_details_json(spec, spec_name, vuln_word, critical_vulns_count) + total_resolved_vulns += resolved_vulns + fixes_count += fixes + + for line in lines: + console.print(Padding(line, PADDING_VALUES), emoji=True) + + # construct the url HERE + # https://data.safetycli.com/p/pypi/django/eda/?from=2.2&to=4.2.17 + # Construct this with 3 inputs- django, raw, + remediation = safe_get(spec, ["vulnerabilities", "remediation"], {}) + recommended = remediation.get("recommended") + URL_PREFIX = "https://data.safetycli.com/p/pypi/" + URL_MIDDLE = "/eda/?from=" + URL_END = "&to=" + more_info_url = URL_PREFIX+spec_name+URL_MIDDLE+spec_raw.split("==")[1]+URL_END+recommended + + if more_info_url: + console.print( + Padding(MSG_LEARN_MORE.format(more_info_url), PADDING_VALUES), emoji=True + ) else: # Handle files with no issues console.print() diff --git a/test_requirements.txt b/test_requirements.txt index bace7c37..3c1be50d 100644 --- a/test_requirements.txt +++ b/test_requirements.txt @@ -11,7 +11,7 @@ ruamel.yaml>=0.17.21 dataclasses==0.8; python_version=="3.6" jinja2; python_version=="3.6" jinja2>=3.1.0; python_version>="3.7" -marshmallow; python_version=="3.6" +marshmallow; python_version=="3.6" marshmallow>=3.15.0; python_version>="3.7" Authlib>=1.2.0 rich