feat: Add channels and local path support for community plugins#195
feat: Add channels and local path support for community plugins#195
Conversation
Wiz Scan Summary
To detect these findings earlier in the dev lifecycle, try using Wiz Code VS Code Extension. |
| for name in stale_modules: | ||
| sys.modules.pop(name, None) | ||
|
|
||
| module = importlib.import_module(module_name) |
There was a problem hiding this comment.
Arbitrary Code Execution via Insecure Import (CWE-706)
More Details
The importlib.import_module() function in Python allows dynamically importing modules at runtime. If the module name is derived from untrusted user input, an attacker could potentially execute arbitrary code on the system by causing a malicious module to be loaded.
| Attribute | Value |
|---|---|
| Impact | |
| Likelihood |
Remediation
The importlib.import_module() function in Python allows for dynamic code loading, which can be a security risk if the module name is derived from untrusted user input. An attacker could potentially exploit this vulnerability to execute arbitrary code on the system, leading to various security issues such as code injection, data tampering, or unauthorized access.
To fix this issue, avoid using dynamic values in importlib.import_module() or implement a strict whitelist of allowed module names. If dynamic module loading is necessary, validate and sanitize the input to ensure that only trusted and approved modules are loaded.
Code examples:
// VULNERABLE CODE - Directly using user input for module loading
import importlib
user_input = input("Enter module name: ")
module = importlib.import_module(user_input)
// SECURE CODE - Using a whitelist of allowed modules
import importlib
ALLOWED_MODULES = ["module1", "module2", "module3"]
user_input = input("Enter module name: ")
if user_input in ALLOWED_MODULES:
module = importlib.import_module(user_input)
else:
print("Module not allowed")
Additional recommendations:
- Follow the principle of least privilege and only grant the minimum required permissions for module loading.
- Implement input validation and sanitization techniques to prevent code injection attacks.
- Consider using a secure coding framework or library that provides built-in protection against code injection vulnerabilities.
- Adhere to the OWASP Top 10 security guidelines, specifically "A1:2021 - Broken Access Control" and "A3:2021 - Injection."
- Regularly update and maintain the whitelist of allowed modules to ensure it remains secure and up-to-date.
Rule ID: WS-I013-PYTHON-00176
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
Pull Request
📝 Summary
This pull request significantly enhances the community plugin system by introducing installation "channels". It adds a
dev_localchannel to support loading plugins directly from a local file path, streamlining the development workflow. For the defaultstablechannel (installing from Git), it improves security and reproducibility by resolving version tags to specific commit SHAs, preventing unexpected changes from upstream force-pushes.🔧 Changes Made
stable(from a Git repository) anddev_local(from a local filesystem path).get_plugin_source_channelandget_plugin_source_pathtoTitanConfigto read the new plugin source configuration.resolve_ref_to_commit_shato convert a user-provided Git reference (tag, short SHA) into a full 40-character commit SHA forstablechannel installations, using the GitHub API.CommunityPluginRecorddata model to store the installation channel, local path, requested Git reference, and the resolved commit SHA.stablechannel.🧪 Testing
poetry run pytest)make test)titan-dev📊 Logs
✅ Checklist