diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 1959a5253..7811a7cb8 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -4,3 +4,7 @@ **Vulnerability:** Found an unused `_attempt_import` function in `src/codeweaver/server/mcp/server.py` that dynamically imports a module directly from unvalidated configuration (`import_module(mw.rsplit(".", 1)[0])`), leading to potential arbitrary code execution. **Learning:** Functions that perform dynamic imports should not be left around in the codebase if they are unused, especially if they are designed to take unvalidated strings as input. **Prevention:** Avoid dynamic imports based on configuration or inputs without strict whitelisting. Use tools like `semgrep` with python security rules to actively catch these patterns. +## 2026-04-21 - Unvalidated dynamic import vulnerability removed +**Vulnerability:** Found dynamic import logic (`importlib.import_module(f"pydantic_ai.profiles.{provider}")`) in `src/codeweaver/providers/agent/capabilities.py` that accepted potentially unvalidated `provider` strings from parsed inputs. +**Learning:** Passing unvalidated inputs directly to `importlib.import_module` can lead to unintended execution paths or potential arbitrary code execution. +**Prevention:** Always validate external or dynamically parsed inputs against a strict whitelist of expected/safe values before using them to import modules. diff --git a/src/codeweaver/providers/agent/capabilities.py b/src/codeweaver/providers/agent/capabilities.py index affc0e5a0..c966f1098 100644 --- a/src/codeweaver/providers/agent/capabilities.py +++ b/src/codeweaver/providers/agent/capabilities.py @@ -44,6 +44,9 @@ def _parse_model_name(name: str) -> tuple[str, str]: def _attempt_to_get_profile(provider: str, full_name: str) -> AgentModelCapabilities | None: + # Security: Validate the provider against a known whitelist before using it in a dynamic import + if provider not in PYDANTIC_AI_MODEL_CAPABILITIES_PROVIDERS: + return None with contextlib.suppress(ImportError): module = importlib.import_module(f"pydantic_ai.profiles.{provider}") if profile_getter := getattr(module, f"{provider}_model_profile", None): @@ -58,6 +61,9 @@ def get_agent_model_capabilities() -> dict[KnownAgentModelName, AgentModelCapabi profiles: dict[KnownAgentModelName, AgentModelCapabilities] = {} for name in model_names: provider, _model = _parse_model_name(name) + # Security: Validate the provider against a known whitelist before using it in a dynamic import + if provider not in PYDANTIC_AI_MODEL_CAPABILITIES_PROVIDERS: + continue try: profile = None module = importlib.import_module(f"pydantic_ai.profiles.{provider}")