From a5c98def94da87347a2d85402d4825830b3ef2ce Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Mon, 10 Mar 2025 15:34:16 -0700 Subject: [PATCH 1/5] use types in create repo --- socketsecurity/core/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/socketsecurity/core/__init__.py b/socketsecurity/core/__init__.py index b38358b..6ecf29c 100644 --- a/socketsecurity/core/__init__.py +++ b/socketsecurity/core/__init__.py @@ -397,7 +397,7 @@ def get_repo_info(self, repo_slug: str, default_branch: str = "socket-default-br # raise Exception(f"Failed to get repository info: {response.status}, message: {response.message}") except APIFailure: log.warning(f"Failed to get repository {repo_slug}, attempting to create it") - create_response = self.sdk.repos.post(self.config.org_slug, name=repo_slug, default_branch=default_branch) + create_response = self.sdk.repos.post(self.config.org_slug, name=repo_slug, default_branch=default_branch, use_types=True) if not create_response.success: log.error(f"Failed to create repository: {create_response.status}") log.error(create_response.message) From b4e35b29e27d31517b7fd9d02105e3dd37e49b57 Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Mon, 10 Mar 2025 15:56:59 -0700 Subject: [PATCH 2/5] fixed logging and create repo handling --- socketsecurity/core/__init__.py | 26 +++++++++++++++++--------- socketsecurity/core/logging.py | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/socketsecurity/core/__init__.py b/socketsecurity/core/__init__.py index 6ecf29c..0a8b773 100644 --- a/socketsecurity/core/__init__.py +++ b/socketsecurity/core/__init__.py @@ -397,15 +397,23 @@ def get_repo_info(self, repo_slug: str, default_branch: str = "socket-default-br # raise Exception(f"Failed to get repository info: {response.status}, message: {response.message}") except APIFailure: log.warning(f"Failed to get repository {repo_slug}, attempting to create it") - create_response = self.sdk.repos.post(self.config.org_slug, name=repo_slug, default_branch=default_branch, use_types=True) - if not create_response.success: - log.error(f"Failed to create repository: {create_response.status}") - log.error(create_response.message) - raise Exception( - f"Failed to create repository: {create_response.status}, message: {create_response.message}" - ) - else: - return create_response.data + try: + # Remove use_types=True since post() doesn't support it + create_response = self.sdk.repos.post(self.config.org_slug, name=repo_slug, default_branch=default_branch) + + # Check if the response is empty (failure) or has content (success) + if not create_response: + log.error("Failed to create repository: empty response") + raise Exception("Failed to create repository: empty response") + else: + # If we got here, create_response is a dictionary with the repository data + return create_response # This is already the repository data + + except APIFailure as e: + # Handle API failures from the post request + log.error(f"API failure while creating repository: {e}") + sys.exit(2) # Exit here with code 2. Code 1 indicates a successfully-detected security issue. + return response.data def get_head_scan_for_repo(self, repo_slug: str) -> str: diff --git a/socketsecurity/core/logging.py b/socketsecurity/core/logging.py index c0ff12d..25601d9 100644 --- a/socketsecurity/core/logging.py +++ b/socketsecurity/core/logging.py @@ -1,5 +1,6 @@ import logging + def initialize_logging( level: int = logging.INFO, format: str = "%(asctime)s: %(message)s", @@ -23,10 +24,24 @@ def initialize_logging( cli_logger = logging.getLogger(cli_logger_name) cli_logger.setLevel(level) + # Explicitly set urllib3 logger to WARNING to prevent debug messages + # when not in debug mode + urllib3_logger = logging.getLogger("urllib3") + urllib3_logger.setLevel(logging.WARNING) + + # Also set git logger to WARNING + git_logger = logging.getLogger("git") + git_logger.setLevel(logging.WARNING) + return socket_logger, cli_logger -def set_debug_mode(enable: bool = True) -> None: +def set_debug_mode(enable: bool = False) -> None: """Toggle debug logging across all loggers""" level = logging.DEBUG if enable else logging.INFO logging.getLogger("socketdev").setLevel(level) - logging.getLogger("socketcli").setLevel(level) \ No newline at end of file + logging.getLogger("socketcli").setLevel(level) + + # Also update urllib3 and git loggers when debug mode changes + urllib3_level = logging.DEBUG if enable else logging.WARNING + logging.getLogger("urllib3").setLevel(urllib3_level) + logging.getLogger("git").setLevel(urllib3_level) \ No newline at end of file From 4305f9af7c9e256cc31a35f8529ebd26cd8e722c Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Mon, 10 Mar 2025 15:58:58 -0700 Subject: [PATCH 3/5] bumped version --- socketsecurity/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/socketsecurity/__init__.py b/socketsecurity/__init__.py index 96db43f..1c645f0 100644 --- a/socketsecurity/__init__.py +++ b/socketsecurity/__init__.py @@ -1,2 +1,2 @@ __author__ = 'socket.dev' -__version__ = '2.0.11' +__version__ = '2.0.12' From 5aa87310618374bcfd0df7d8baac9dba83747227 Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Mon, 10 Mar 2025 16:01:35 -0700 Subject: [PATCH 4/5] cleanup --- socketsecurity/core/__init__.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/socketsecurity/core/__init__.py b/socketsecurity/core/__init__.py index 0a8b773..3d3a555 100644 --- a/socketsecurity/core/__init__.py +++ b/socketsecurity/core/__init__.py @@ -394,11 +394,10 @@ def get_repo_info(self, repo_slug: str, default_branch: str = "socket-default-br if not response.success: log.error(f"Failed to get repository: {response.status}") log.error(response.message) - # raise Exception(f"Failed to get repository info: {response.status}, message: {response.message}") except APIFailure: log.warning(f"Failed to get repository {repo_slug}, attempting to create it") try: - # Remove use_types=True since post() doesn't support it + create_response = self.sdk.repos.post(self.config.org_slug, name=repo_slug, default_branch=default_branch) # Check if the response is empty (failure) or has content (success) @@ -406,11 +405,9 @@ def get_repo_info(self, repo_slug: str, default_branch: str = "socket-default-br log.error("Failed to create repository: empty response") raise Exception("Failed to create repository: empty response") else: - # If we got here, create_response is a dictionary with the repository data - return create_response # This is already the repository data + return create_response except APIFailure as e: - # Handle API failures from the post request log.error(f"API failure while creating repository: {e}") sys.exit(2) # Exit here with code 2. Code 1 indicates a successfully-detected security issue. From 5d949d8196dafe9761d988bc3094c9e79b84dd90 Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Mon, 10 Mar 2025 16:42:39 -0700 Subject: [PATCH 5/5] fixed logging issue and reverted random stuff --- socketsecurity/core/logging.py | 13 ---------- socketsecurity/core/messages.py | 44 ++++++++++++++++----------------- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/socketsecurity/core/logging.py b/socketsecurity/core/logging.py index 25601d9..9e61dae 100644 --- a/socketsecurity/core/logging.py +++ b/socketsecurity/core/logging.py @@ -24,14 +24,6 @@ def initialize_logging( cli_logger = logging.getLogger(cli_logger_name) cli_logger.setLevel(level) - # Explicitly set urllib3 logger to WARNING to prevent debug messages - # when not in debug mode - urllib3_logger = logging.getLogger("urllib3") - urllib3_logger.setLevel(logging.WARNING) - - # Also set git logger to WARNING - git_logger = logging.getLogger("git") - git_logger.setLevel(logging.WARNING) return socket_logger, cli_logger @@ -40,8 +32,3 @@ def set_debug_mode(enable: bool = False) -> None: level = logging.DEBUG if enable else logging.INFO logging.getLogger("socketdev").setLevel(level) logging.getLogger("socketcli").setLevel(level) - - # Also update urllib3 and git loggers when debug mode changes - urllib3_level = logging.DEBUG if enable else logging.WARNING - logging.getLogger("urllib3").setLevel(urllib3_level) - logging.getLogger("git").setLevel(urllib3_level) \ No newline at end of file diff --git a/socketsecurity/core/messages.py b/socketsecurity/core/messages.py index 2940e3d..25a29d8 100644 --- a/socketsecurity/core/messages.py +++ b/socketsecurity/core/messages.py @@ -1,16 +1,14 @@ import json -import os -import re -import json import logging -logging.basicConfig(level=logging.DEBUG) - +import re from pathlib import Path + from mdutils import MdUtils from prettytable import PrettyTable from socketsecurity.core.classes import Diff, Issue, Purl +log = logging.getLogger("socketcli") class Messages: @@ -46,13 +44,13 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str) - Uses regex patterns to detect a match line by line """ file_type = Path(manifest_file).name - logging.debug("Processing file for line lookup: %s", manifest_file) + log.debug("Processing file for line lookup: %s", manifest_file) if file_type in ["package-lock.json", "Pipfile.lock", "composer.lock"]: try: with open(manifest_file, "r", encoding="utf-8") as f: raw_text = f.read() - logging.debug("Read %d characters from %s", len(raw_text), manifest_file) + log.debug("Read %d characters from %s", len(raw_text), manifest_file) data = json.loads(raw_text) packages_dict = ( data.get("packages") @@ -60,7 +58,7 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str) or data.get("dependencies") or {} ) - logging.debug("Found package keys in %s: %s", manifest_file, list(packages_dict.keys())) + log.debug("Found package keys in %s: %s", manifest_file, list(packages_dict.keys())) found_key = None found_info = None for key, value in packages_dict.items(): @@ -72,16 +70,16 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str) if found_key and found_info: needle_key = f'"{found_key}":' lines = raw_text.splitlines() - logging.debug("Total lines in %s: %d", manifest_file, len(lines)) + log.debug("Total lines in %s: %d", manifest_file, len(lines)) for i, line in enumerate(lines, start=1): if needle_key in line: - logging.debug("Found match at line %d in %s: %s", i, manifest_file, line.strip()) + log.debug("Found match at line %d in %s: %s", i, manifest_file, line.strip()) return i, line.strip() return 1, f'"{found_key}": {found_info}' else: return 1, f"{packagename} {packageversion} (not found in {manifest_file})" except (FileNotFoundError, json.JSONDecodeError) as e: - logging.error("Error reading %s: %s", manifest_file, e) + log.error("Error reading %s: %s", manifest_file, e) return 1, f"Error reading {manifest_file}" # For pnpm-lock.yaml, use a special regex pattern. @@ -114,15 +112,15 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str) } searchstring = search_patterns.get(file_type, rf'{re.escape(packagename)}.*{re.escape(packageversion)}') - logging.debug("Using search pattern for %s: %s", file_type, searchstring) + log.debug("Using search pattern for %s: %s", file_type, searchstring) try: with open(manifest_file, 'r', encoding="utf-8") as file: lines = [line.rstrip("\n") for line in file] - logging.debug("Total lines in %s: %d", manifest_file, len(lines)) + log.debug("Total lines in %s: %d", manifest_file, len(lines)) for line_number, line_content in enumerate(lines, start=1): line_main = line_content.split(";", 1)[0].strip() if re.search(searchstring, line_main, re.IGNORECASE): - logging.debug("Match found at line %d in %s: %s", line_number, manifest_file, line_content.strip()) + log.debug("Match found at line %d in %s: %s", line_number, manifest_file, line_content.strip()) return line_number, line_content.strip() except FileNotFoundError: return 1, f"{manifest_file} not found" @@ -172,8 +170,8 @@ def create_security_comment_sarif(diff) -> dict: - For alerts with multiple manifest files, generates an individual SARIF result for each file. - Appends the manifest file name to the rule ID and name to make each result unique. - Does NOT fall back to 'requirements.txt' if no manifest file is provided. - - Adds detailed logging to validate our assumptions. - + - Adds detailed log to validate our assumptions. + """ if len(diff.new_alerts) == 0: for alert in diff.new_alerts: @@ -204,7 +202,7 @@ def create_security_comment_sarif(diff) -> dict: base_rule_id = f"{pkg_name}=={pkg_version}" severity = alert.severity - logging.debug("Alert %s - introduced_by: %s, manifests: %s", base_rule_id, alert.introduced_by, getattr(alert, 'manifests', None)) + log.debug("Alert %s - introduced_by: %s, manifests: %s", base_rule_id, alert.introduced_by, getattr(alert, 'manifests', None)) manifest_files = [] if alert.introduced_by and isinstance(alert.introduced_by, list): for entry in alert.introduced_by: @@ -216,21 +214,21 @@ def create_security_comment_sarif(diff) -> dict: elif hasattr(alert, 'manifests') and alert.manifests: manifest_files = [mf.strip() for mf in alert.manifests.split(";") if mf.strip()] - logging.debug("Alert %s - extracted manifest_files: %s", base_rule_id, manifest_files) + log.debug("Alert %s - extracted manifest_files: %s", base_rule_id, manifest_files) if not manifest_files: - logging.error("Alert %s: No manifest file found; cannot determine file location.", base_rule_id) + log.error("Alert %s: No manifest file found; cannot determine file location.", base_rule_id) continue - logging.debug("Alert %s - using manifest_files for processing: %s", base_rule_id, manifest_files) + log.debug("Alert %s - using manifest_files for processing: %s", base_rule_id, manifest_files) # Create an individual SARIF result for each manifest file. for mf in manifest_files: - logging.debug("Alert %s - Processing manifest file: %s", base_rule_id, mf) + log.debug("Alert %s - Processing manifest file: %s", base_rule_id, mf) socket_url = Messages.get_manifest_type_url(mf, pkg_name, pkg_version) line_number, line_content = Messages.find_line_in_file(pkg_name, pkg_version, mf) if line_number < 1: line_number = 1 - logging.debug("Alert %s: Manifest %s, line %d: %s", base_rule_id, mf, line_number, line_content) + log.debug("Alert %s: Manifest %s, line %d: %s", base_rule_id, mf, line_number, line_content) # Create a unique rule id and name by appending the manifest file. unique_rule_id = f"{base_rule_id} ({mf})" @@ -271,7 +269,7 @@ def create_security_comment_sarif(diff) -> dict: sarif_data["runs"][0]["results"] = results_list return sarif_data - + @staticmethod def create_security_comment_json(diff: Diff) -> dict: scan_failed = False