feat: Add community plugin installer with git repository support#183
feat: Add community plugin installer with git repository support#183
Conversation
…for community plugins
7b92010 to
c7b7ea0
Compare
Wiz Scan Summary
To detect these findings earlier in the dev lifecycle, try using Wiz Code VS Code Extension. |
| req = Request(raw_url) | ||
| if token: | ||
| req.add_header("Authorization", f"token {token}") | ||
| with urlopen(req, timeout=_FETCH_TIMEOUT) as resp: |
There was a problem hiding this comment.
Insecure URL handling in Python urllib module (CWE-939)
More Details
The Python urllib module allows applications to open URLs and retrieve data from the web. However, if the URL is not a literal value and can be controlled by an attacker, it can lead to security vulnerabilities. The urllib module supports the "file://" scheme, which means an attacker could potentially read arbitrary files on the system if they can control the URL value.
This vulnerability poses a significant risk as it can lead to unauthorized access to sensitive information, data leaks, and potentially even remote code execution, depending on the application's context and privileges. It is crucial to avoid passing user-controlled input directly to the urllib module's functions without proper validation and sanitization.
| Attribute | Value |
|---|---|
| Impact | |
| Likelihood |
Remediation
To mitigate this vulnerability, it is recommended to either:
- Hardcode the URLs being used in the urllib module, ensuring that they are not derived from user input or other untrusted sources.
- Use a more secure and modern library like the
requestsmodule, which does not support the "file://" scheme by default.
Example using the requests module to issue an HTTPS request:
import requests
# Issue a GET request to https://example.com with a timeout of 10 seconds
response = requests.get('https://example.com', timeout=10)
# Work with the response object
# ...Rule ID: WS-I011-PYTHON-00053
To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason
If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).
To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate
| req.add_header("Accept", "application/vnd.github+json") | ||
| if token: | ||
| req.add_header("Authorization", f"Bearer {token}") | ||
| with urlopen(req, timeout=_FETCH_TIMEOUT) as resp: |
There was a problem hiding this comment.
Insecure URL handling in Python urllib module (CWE-939)
More Details
The Python urllib module allows applications to open URLs and retrieve data from the web. However, if the URL is not a literal value and can be controlled by an attacker, it can lead to security vulnerabilities. The urllib module supports the "file://" scheme, which means an attacker could potentially read arbitrary files on the system if they can control the URL value.
This vulnerability poses a significant risk as it can lead to unauthorized access to sensitive information, data leaks, and potentially even remote code execution, depending on the application's context and privileges. It is crucial to avoid passing user-controlled input directly to the urllib module's functions without proper validation and sanitization.
| Attribute | Value |
|---|---|
| Impact | |
| Likelihood |
Remediation
To mitigate this vulnerability, it is recommended to either:
- Hardcode the URLs being used in the urllib module, ensuring that they are not derived from user input or other untrusted sources.
- Use a more secure and modern library like the
requestsmodule, which does not support the "file://" scheme by default.
Example using the requests module to issue an HTTPS request:
import requests
# Issue a GET request to https://example.com with a timeout of 10 seconds
response = requests.get('https://example.com', timeout=10)
# Work with the response object
# ...Rule ID: WS-I011-PYTHON-00053
To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason
If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).
To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate
| req = Request(api_url) | ||
| if token: | ||
| req.add_header("PRIVATE-TOKEN", token) | ||
| with urlopen(req, timeout=_FETCH_TIMEOUT) as resp: |
There was a problem hiding this comment.
Insecure URL handling in Python urllib module (CWE-939)
More Details
The Python urllib module allows applications to open URLs and retrieve data from the web. However, if the URL is not a literal value and can be controlled by an attacker, it can lead to security vulnerabilities. The urllib module supports the "file://" scheme, which means an attacker could potentially read arbitrary files on the system if they can control the URL value.
This vulnerability poses a significant risk as it can lead to unauthorized access to sensitive information, data leaks, and potentially even remote code execution, depending on the application's context and privileges. It is crucial to avoid passing user-controlled input directly to the urllib module's functions without proper validation and sanitization.
| Attribute | Value |
|---|---|
| Impact | |
| Likelihood |
Remediation
To mitigate this vulnerability, it is recommended to either:
- Hardcode the URLs being used in the urllib module, ensuring that they are not derived from user input or other untrusted sources.
- Use a more secure and modern library like the
requestsmodule, which does not support the "file://" scheme by default.
Example using the requests module to issue an HTTPS request:
import requests
# Issue a GET request to https://example.com with a timeout of 10 seconds
response = requests.get('https://example.com', timeout=10)
# Work with the response object
# ...Rule ID: WS-I011-PYTHON-00053
To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason
If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).
To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate
Pull Request
📝 Summary
Adds a complete community plugin installation system that allows users to install Titan plugins from any git repository (GitHub, GitLab, Bitbucket) using
pipx injectfor isolation. Includes a 4-step installation wizard with preview functionality, version tracking, update notifications, and plugin-based workflow filtering capabilities.🔧 Changes Made
titan_cli/core/plugins/community.py): Core business logic for URL validation, git host detection, pyproject.toml preview fetching, pipx install/uninstall, and tracking file management in~/.titan/community_plugins.tomltitan_cli/ui/tui/screens/install_plugin_screen.py): Interactive wizard for URL input, metadata preview with security warnings, installation progress, and success/failure handlingtitan_cli/ui/tui/screens/plugin_management.py): Added install button (i), uninstall button (u) for community plugins, and[community]badge to distinguish plugin sourcestitan_cli/ui/tui/widgets/wizard.py): ReusableStepStatus,WizardStep, andStepIndicatorcomponents for multi-step workflowstitan_cli/core/plugins/updates.py,titan_cli/ui/tui/screens/plugin_management.py): Checks for newer versions of community plugins and displays update badges with available versionstitan_cli/core/plugins/registry.py,titan_cli/core/workflow/workflow_manager.py): Workflows can now be filtered by active plugins through configuration, with support for nested plugin workflow directoriestitan_cli/core/plugins/community.py): SupportsGITHUB_TOKENenvironment variable for fetching from private repositoriestitan_cli/core/plugins/community.py): Automatically detects Poetry virtual environments and uses appropriate pip for plugin installationtitan_cli/core/plugins/registry.py): Extracts and displays plugin versions from distribution metadata🧪 Testing
poetry run pytest)make test)titan-devUnit tests cover:
📊 Logs
community_plugin_install_started(INFO) — repo_url, version, package_namecommunity_plugin_install_success(INFO) — package_name, titan_plugin_name, durationcommunity_plugin_install_failed(ERROR) — repo_url, error_type, error_messagecommunity_plugin_uninstall_started(INFO) — package_name, titan_plugin_namecommunity_plugin_uninstall_success(INFO) — package_name, durationcommunity_plugin_uninstall_failed(ERROR) — package_name, error_messagecommunity_plugin_preview_fetch_ok(DEBUG) — repo_url, version, hostcommunity_plugin_preview_fetch_failed(DEBUG) — repo_url, version, error_typecommunity_plugin_update_check(DEBUG) — plugin_name, current_version, latest_version, update_availableplugin_workflow_filter_applied(DEBUG) — plugin_name, total_workflows, filtered_workflows✅ Checklist