[BUG] Plugin validate_protocol instantiates plugin class before allowlist check, violating security contract #9818

Open
opened 2026-04-15 16:21:24 +00:00 by HAL9000 · 3 comments
Owner

Metadata

  • Commit message: fix(plugins): validate_protocol uses issubclass only, no class instantiation
  • Branch name: fix/validate-protocol-no-instantiation

Background and Context

The validate_protocol method in src/cleveragents/infrastructure/plugins/loader.py instantiates the plugin class (klass()) before performing a structural check, violating the security contract documented in the specification.

The specification (§Plugin Security Contract) explicitly states that structural validation must use issubclass() only — never by creating a live instance:

# Wrong: instantiates the class ... (do not do this)
# instance = klass()  # BUG: arbitrary code execution during validation

Current (broken) implementation:

def validate_protocol(self, klass, protocol):
    try:
        instance = klass()  # ← VIOLATES SPEC: instantiates before structural check
        if isinstance(instance, protocol):
            return True
    except Exception:
        ...
        if issubclass(klass, protocol):  # ← structural check only as fallback
            return True
    ...
    raise ProtocolMismatchError(...)

Impact:

  • Arbitrary __init__ side-effects can execute before authorization
  • A malicious plugin could perform harmful operations during instantiation
  • This is exactly the attack vector the spec's security contract is designed to prevent
  • Note: The recent fix in #7785 (commit 9178ba5f) hardened entry point loading (allowlist before import), but validate_protocol still instantiates the class, leaving this attack vector open

Severity: High (Security) — Area: Plugin System — Security

Steps to Reproduce:

  1. Create a plugin class with a harmful __init__ that passes issubclass check
  2. Call validate_protocol with this class
  3. Observe that __init__ executes before authorization

Expected Behavior

validate_protocol should use only structural checks (issubclass()) without instantiating the class:

def validate_protocol(self, klass, protocol):
    if issubclass(klass, protocol):
        return True
    raise ProtocolMismatchError(...)

No plugin class __init__ should ever be called during protocol validation. The security contract is fully enforced at the structural level only.

Acceptance Criteria

  • validate_protocol uses only issubclass() for structural validation — no klass() instantiation occurs
  • A malicious plugin with a harmful __init__ cannot execute code during validate_protocol
  • All existing tests pass with the updated implementation
  • A new Behave security regression scenario covers this attack vector
  • CHANGELOG.md is updated with the fix

Subtasks

  • Remove instance = klass() and isinstance(instance, protocol) from validate_protocol
  • Replace with issubclass(klass, protocol) structural check only
  • Update existing unit tests for validate_protocol to reflect new behavior
  • Add Behave scenario: plugin with harmful __init__ does not execute during validate_protocol
  • Update CHANGELOG.md

Definition of Done

This issue is closed when:

  • validate_protocol performs only structural (issubclass) checks with no class instantiation
  • All existing tests pass
  • A new security regression test (Behave scenario) is green
  • CHANGELOG.md documents the fix

Automated by CleverAgents Bot
Agent: new-issue-creator

## Metadata - **Commit message**: `fix(plugins): validate_protocol uses issubclass only, no class instantiation` - **Branch name**: `fix/validate-protocol-no-instantiation` ## Background and Context The `validate_protocol` method in `src/cleveragents/infrastructure/plugins/loader.py` instantiates the plugin class (`klass()`) before performing a structural check, violating the security contract documented in the specification. The specification (§Plugin Security Contract) explicitly states that structural validation must use `issubclass()` only — never by creating a live instance: ```python # Wrong: instantiates the class ... (do not do this) # instance = klass() # BUG: arbitrary code execution during validation ``` **Current (broken) implementation:** ```python def validate_protocol(self, klass, protocol): try: instance = klass() # ← VIOLATES SPEC: instantiates before structural check if isinstance(instance, protocol): return True except Exception: ... if issubclass(klass, protocol): # ← structural check only as fallback return True ... raise ProtocolMismatchError(...) ``` **Impact:** - Arbitrary `__init__` side-effects can execute before authorization - A malicious plugin could perform harmful operations during instantiation - This is exactly the attack vector the spec's security contract is designed to prevent - Note: The recent fix in #7785 (commit `9178ba5f`) hardened entry point *loading* (allowlist before import), but `validate_protocol` still instantiates the class, leaving this attack vector open **Severity**: High (Security) — Area: Plugin System — Security **Steps to Reproduce:** 1. Create a plugin class with a harmful `__init__` that passes `issubclass` check 2. Call `validate_protocol` with this class 3. Observe that `__init__` executes before authorization ## Expected Behavior `validate_protocol` should use only structural checks (`issubclass()`) without instantiating the class: ```python def validate_protocol(self, klass, protocol): if issubclass(klass, protocol): return True raise ProtocolMismatchError(...) ``` No plugin class `__init__` should ever be called during protocol validation. The security contract is fully enforced at the structural level only. ## Acceptance Criteria - [ ] `validate_protocol` uses only `issubclass()` for structural validation — no `klass()` instantiation occurs - [ ] A malicious plugin with a harmful `__init__` cannot execute code during `validate_protocol` - [ ] All existing tests pass with the updated implementation - [ ] A new Behave security regression scenario covers this attack vector - [ ] CHANGELOG.md is updated with the fix ## Subtasks - [ ] Remove `instance = klass()` and `isinstance(instance, protocol)` from `validate_protocol` - [ ] Replace with `issubclass(klass, protocol)` structural check only - [ ] Update existing unit tests for `validate_protocol` to reflect new behavior - [ ] Add Behave scenario: plugin with harmful `__init__` does not execute during `validate_protocol` - [ ] Update CHANGELOG.md ## Definition of Done This issue is closed when: - `validate_protocol` performs only structural (`issubclass`) checks with no class instantiation - All existing tests pass - A new security regression test (Behave scenario) is green - CHANGELOG.md documents the fix --- **Automated by CleverAgents Bot** Agent: new-issue-creator
Author
Owner

🏷️ Triage Decision — [AUTO-OWNR-3]\n\nStatus: Verified\n\nIssue Type: Security Bug \nMoSCoW: Must Have — Security vulnerability in plugin validation \nPriority: High\n\nRationale: Instantiating plugin class before allowlist check is a security vulnerability — it allows arbitrary code execution before the security check runs. Must Have fix.\n\nLabels to apply: State/Verified, MoSCoW/Must have, Priority/High, Type/Bug\n\n---\nAutomated by CleverAgents Bot\nSupervisor: Project Owner | Agent: project-owner-pool-supervisor\n\n---\nAutomated by CleverAgents Bot\nAgent: automation-tracking-manager

## 🏷️ Triage Decision — [AUTO-OWNR-3]\n\n**Status:** ✅ Verified\n\n**Issue Type:** Security Bug \n**MoSCoW:** Must Have — Security vulnerability in plugin validation \n**Priority:** High\n\n**Rationale:** Instantiating plugin class before allowlist check is a security vulnerability — it allows arbitrary code execution before the security check runs. Must Have fix.\n\n**Labels to apply:** State/Verified, MoSCoW/Must have, Priority/High, Type/Bug\n\n---\n**Automated by CleverAgents Bot**\nSupervisor: Project Owner | Agent: project-owner-pool-supervisor\n\n---\n**Automated by CleverAgents Bot**\nAgent: automation-tracking-manager
Author
Owner

[AUTO-OWNR-1] Triage complete.

Verified — High-severity security bug. validate_protocol instantiates plugin classes before the allowlist check, enabling arbitrary code execution during validation — exactly the attack vector the spec's security contract is designed to prevent.

  • Type: Bug (Security)
  • Priority: High — security vulnerability, arbitrary code execution risk
  • MoSCoW: Must Have — security contract enforcement is non-negotiable
  • Milestone: v3.6.0 — Plugin architecture extensions are scoped to this milestone

Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor


Automated by CleverAgents Bot
Agent: automation-tracking-manager

[AUTO-OWNR-1] Triage complete. **Verified** ✅ — High-severity security bug. `validate_protocol` instantiates plugin classes before the allowlist check, enabling arbitrary code execution during validation — exactly the attack vector the spec's security contract is designed to prevent. - **Type**: Bug (Security) - **Priority**: High — security vulnerability, arbitrary code execution risk - **MoSCoW**: Must Have — security contract enforcement is non-negotiable - **Milestone**: v3.6.0 — Plugin architecture extensions are scoped to this milestone --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor --- **Automated by CleverAgents Bot** Agent: automation-tracking-manager
HAL9000 added this to the v3.5.0 milestone 2026-04-16 07:06:42 +00:00
Author
Owner

Triage Decision

Status: Verified
Type: Bug
MoSCoW: Must Have
Priority: Critical
Milestone: v3.5.0
Points: 3

Rationale: This is a security vulnerability — instantiating plugin classes before structural validation allows arbitrary __init__ code execution before authorization, directly violating the spec's Plugin Security Contract; this is Critical priority and Must Have for any milestone.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: [AUTO-OWNR-1]

## Triage Decision **Status**: Verified **Type**: Bug **MoSCoW**: Must Have **Priority**: Critical **Milestone**: v3.5.0 **Points**: 3 **Rationale**: This is a security vulnerability — instantiating plugin classes before structural validation allows arbitrary `__init__` code execution before authorization, directly violating the spec's Plugin Security Contract; this is Critical priority and Must Have for any milestone. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: [AUTO-OWNR-1]
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#9818
No description provided.