Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,18 @@ ARG PIP_EXTRA_INDEX_URL=https://pypi.org/simple
ARG USE_LOCAL_INSTALL=false

RUN apk update \
&& apk add --no-cache git nodejs npm yarn curl \
&& npm install @coana-tech/cli -g
&& apk add --no-cache git nodejs npm yarn curl wget \
go ruby ruby-dev build-base \
openjdk17-jdk \
dotnet8-sdk \
&& npm install @coana-tech/cli -g \
&& gem install bundler \
&& curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
&& . ~/.cargo/env \
&& rustup component add rustfmt clippy

# Add Rust to PATH
ENV PATH="/root/.cargo/bin:${PATH}"

# Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ If you don't want to provide the Socket API Token every time then you can use th
| --reach-version | False | latest | Version of @coana-tech/cli to use for analysis |
| --reach-analysis-timeout | False | 1200 | Timeout in seconds for the reachability analysis (default: 1200 seconds / 20 minutes) |
| --reach-analysis-memory-limit | False | 4096 | Memory limit in MB for the reachability analysis (default: 4096 MB / 4 GB) |
| --reach-concurrency | False | | Control parallel analysis execution (must be >= 1) |
| --reach-additional-params | False | | Pass custom parameters to the coana CLI tool |
| --reach-ecosystems | False | | Comma-separated list of ecosystems to analyze (e.g., "npm,pypi"). If not specified, all supported ecosystems are analyzed |
| --reach-exclude-paths | False | | Comma-separated list of file paths or patterns to exclude from reachability analysis |
| --reach-min-severity | False | | Minimum severity level for reporting reachability results (low, medium, high, critical) |
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "hatchling.build"

[project]
name = "socketsecurity"
version = "2.2.27"
version = "2.2.30"
requires-python = ">= 3.10"
license = {"file" = "LICENSE"}
dependencies = [
Expand All @@ -16,7 +16,7 @@ dependencies = [
'GitPython',
'packaging',
'python-dotenv',
'socketdev>=3.0.17,<4.0.0',
'socketdev>=3.0.19,<4.0.0',
"bs4>=0.0.2",
]
readme = "README.md"
Expand Down
2 changes: 1 addition & 1 deletion socketsecurity/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__author__ = 'socket.dev'
__version__ = '2.2.27'
__version__ = '2.2.30'
USER_AGENT = f'SocketPythonCLI/{__version__}'
39 changes: 30 additions & 9 deletions socketsecurity/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class CliConfig:
reach_skip_cache: bool = False
reach_min_severity: Optional[str] = None
reach_output_file: Optional[str] = None
reach_concurrency: Optional[int] = None
reach_additional_params: Optional[List[str]] = None
only_facts_file: bool = False

@classmethod
Expand Down Expand Up @@ -132,6 +134,8 @@ def from_args(cls, args_list: Optional[List[str]] = None) -> 'CliConfig':
'reach_skip_cache': args.reach_skip_cache,
'reach_min_severity': args.reach_min_severity,
'reach_output_file': args.reach_output_file,
'reach_concurrency': args.reach_concurrency,
'reach_additional_params': args.reach_additional_params,
'only_facts_file': args.only_facts_file,
'version': __version__
}
Expand Down Expand Up @@ -169,6 +173,11 @@ def from_args(cls, args_list: Optional[List[str]] = None) -> 'CliConfig':
logging.error("--only-facts-file requires --reach to be specified")
exit(1)

# Validate reach_concurrency is >= 1 if provided
if args.reach_concurrency is not None and args.reach_concurrency < 1:
logging.error("--reach-concurrency must be >= 1")
exit(1)

return cls(**config_args)

def to_dict(self) -> dict:
Expand Down Expand Up @@ -429,20 +438,13 @@ def create_argument_parser() -> argparse.ArgumentParser:
help="Exclude license details from the diff report (boosts performance for large repos)"
)

# Security Configuration
security_group = parser.add_argument_group('Security Configuration')
security_group.add_argument(
"--allow-unverified",
action="store_true",
help="Allow unverified packages"
)
security_group.add_argument(
output_group.add_argument(
"--disable-security-issue",
dest="disable_security_issue",
action="store_true",
help="Disable security issue checks"
)
security_group.add_argument(
output_group.add_argument(
"--disable_security_issue",
dest="disable_security_issue",
action="store_true",
Expand Down Expand Up @@ -494,6 +496,11 @@ def create_argument_parser() -> argparse.ArgumentParser:
help="Timeout in seconds for API requests",
required=False
)
advanced_group.add_argument(
"--allow-unverified",
action="store_true",
help="Disable SSL certificate verification for API requests"
)
config_group.add_argument(
"--include-module-folders",
dest="include_module_folders",
Expand Down Expand Up @@ -567,6 +574,20 @@ def create_argument_parser() -> argparse.ArgumentParser:
default=".socket.facts.json",
help="Output file path for reachability analysis results (default: .socket.facts.json)"
)
reachability_group.add_argument(
"--reach-concurrency",
dest="reach_concurrency",
type=int,
metavar="<number>",
help="Concurrency level for reachability analysis (must be >= 1)"
)
reachability_group.add_argument(
"--reach-additional-params",
dest="reach_additional_params",
nargs='+',
metavar="<param>",
help="Additional parameters to pass to the coana CLI (e.g., --reach-additional-params --other-param value --another-param value2)"
)
reachability_group.add_argument(
"--only-facts-file",
dest="only_facts_file",
Expand Down
20 changes: 19 additions & 1 deletion socketsecurity/core/tools/reachability.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def _ensure_coana_cli_installed(self, version: Optional[str] = None) -> str:
Check if @coana-tech/cli is installed, and install/update it if needed.

Args:
version: Specific version to install (e.g., '1.2.3'). If None, updates to latest.
version: Specific version to install (e.g., '1.2.3'). If None, always updates to latest.

Returns:
str: The package specifier to use with npx
Expand Down Expand Up @@ -48,6 +48,7 @@ def _ensure_coana_cli_installed(self, version: Optional[str] = None) -> str:
log.debug(f"Could not check for existing @coana-tech/cli installation: {e}")

# Install or update the package
# When no version is specified, always try to update to latest
if version:
log.info(f"Installing reachability analysis plugin (@coana-tech/cli@{version})...")
else:
Expand Down Expand Up @@ -95,6 +96,9 @@ def run_reachability_analysis(
repo_name: Optional[str] = None,
branch_name: Optional[str] = None,
version: Optional[str] = None,
concurrency: Optional[int] = None,
additional_params: Optional[List[str]] = None,
allow_unverified: bool = False,
) -> Dict[str, Any]:
"""
Run reachability analysis.
Expand All @@ -114,6 +118,9 @@ def run_reachability_analysis(
repo_name: Repository name
branch_name: Branch name
version: Specific version of @coana-tech/cli to use
concurrency: Concurrency level for analysis (must be >= 1)
additional_params: Additional parameters to pass to coana CLI
allow_unverified: Disable SSL certificate verification (sets NODE_TLS_REJECT_UNAUTHORIZED=0)

Returns:
Dict containing scan_id and report_path
Expand Down Expand Up @@ -158,6 +165,13 @@ def run_reachability_analysis(
if skip_cache:
cmd.append("--skip-cache-usage")

if concurrency:
cmd.extend(["--concurrency", str(concurrency)])

# Add any additional parameters provided by the user
if additional_params:
cmd.extend(additional_params)

# Set up environment variables
env = os.environ.copy()

Expand All @@ -172,6 +186,10 @@ def run_reachability_analysis(
if branch_name:
env["SOCKET_BRANCH_NAME"] = branch_name

# Set NODE_TLS_REJECT_UNAUTHORIZED=0 if allow_unverified is True
if allow_unverified:
env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"

# Execute CLI
log.info("Running reachability analysis...")
log.debug(f"Reachability command: {' '.join(cmd)}")
Expand Down
14 changes: 12 additions & 2 deletions socketsecurity/socketcli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import sys
import traceback
import shutil
import warnings

from dotenv import load_dotenv
from git import InvalidGitRepositoryError, NoSuchPathError
Expand Down Expand Up @@ -55,7 +56,13 @@ def main_code():
"2. Environment variable: SOCKET_SECURITY_API_KEY")
sys.exit(3)

sdk = socketdev(token=config.api_token)
sdk = socketdev(token=config.api_token, allow_unverified=config.allow_unverified)

# Suppress urllib3 InsecureRequestWarning when using --allow-unverified
if config.allow_unverified:
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

output_handler = OutputHandler(config, sdk)
log.debug("sdk loaded")

Expand Down Expand Up @@ -277,7 +284,10 @@ def main_code():
disable_analytics=config.reach_disable_analytics or False,
repo_name=config.repo,
branch_name=config.branch,
version=config.reach_version
version=config.reach_version,
concurrency=config.reach_concurrency,
additional_params=config.reach_additional_params,
allow_unverified=config.allow_unverified
)

log.info(f"Reachability analysis completed successfully")
Expand Down
Loading