Back to skill

Security audit

Context Switch Token Optimizer

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated purpose, but it stores conversation summaries locally and one reset path says the context was cleared while leaving the saved data in place.

Install only if you are comfortable with local retention of conversation summaries and snippets. Treat the reset command as unreliable for data deletion unless it is fixed to overwrite or remove memory/context_switch_state.json, and keep sensitive files out of memory/topic unless you want them loaded into context.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
context-switch-token-optimizer.py:124
Finding

Reset Operations Preserve Persisted Conversation State While Reporting Successful Deletion

Content
View full analysis

Vulnerability Details

File Location: context-switch-token-optimizer.py:124-134
Additional Location: token_optimizer.py:227-245
Vulnerability Type: Improper clearing of persisted sensitive state
Risk Level: Medium

Complete Code Snippets

context-switch-token-optimizer.py:124-134:

python
def reset_context(self) -> Dict:
    """重置上下文"""
    # 重置上下文管理器
    self.context_manager.state = self.context_manager._load_context_state()
    
    # 生成重置报告
    return {
        'action': 'reset_context',
        'timestamp': '2026-03-17T11:00:00',
        'context_cleared': True,
        'token_optimization_active': True,
        'message': '上下文已重置,可以开始新的对话主题'
    }

token_optimizer.py:227-245:

python
def _reset_context(self) -> Dict:
    """重置上下文"""
    original_state = {
        'topic': self.context_manager.state.current_topic,
        'history_size': len(self.context_manager.state.topic_history),
        'memory_loaded': bool(self.context_manager.state.memory_context),
        'switch_count': self.context_manager.state.switch_count
    }
    
    # 重置上下文状态
    self.context_manager.state = self.context_manager._load_context_state()
    
    return {
        'action': 'reset_context',
        'original_state': original_state,
        'memory_cleared': True,
        'context_cleared': True,
        'token_savings': self._estimate_token_savings()
    }

Technical Analysis

Both reset implementations call _load_context_state(). That method reads memory/context_switch_state.json and reconstructs the previously persisted state; it does not create a new empty state, delete the file, or overwrite it with an empty structure.

Consequently, the reset operation restores existing topic history, conversation snippets, loaded memory context, and counters while returning context_cleared: True and, in the optimizer path, memory_cleared: True. The primary CLI --reset option invokes the affected method in `context-switch-token-op ...[truncated 1556 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace state reloading with construction of a new empty ContextState:
python
self.context_manager.state = ContextState(
    current_topic=None,
    topic_history=[],
    memory_context=None,
    last_switch_time=None,
    switch_count=0,
    total_tokens=0,
)
  1. Persist the empty state immediately with save_context_state(), or securely delete the state file if absence represents an empty state.

  2. Use atomic replacement when rewriting the file: write the empty state to a temporary file in the same directory, set restrictive permissions, flush it, and replace the original file.

  3. Clear related in-memory token usage and optimization logs where the reset contract requires a complete reset.

  4. Consolidate the two reset implementations into one shared method to prevent behavioral divergence.

  5. Return context_cleared: true and memory_cleared: true only after persistent clearing succeeds. Propagate write or deletion failures rather than reporting success.

  6. Add regression tests that populate the state, invoke each reset path, instantiate a new manager, and verify that no topic history, snippet, memory context, or counters can be recovered.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (17)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The title and the full usage documentation are presented in Chinese, and the file does not provide an alternative language option or indicate that the locale restriction is optional. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises behavior that reads environment variables and reads/writes files, but the manifest does not declare any tool scope or permissions boundary. This creates a trust and review gap: users and hosting platforms cannot easily assess or constrain the skill's effective capabilities, increasing the chance of unintended file access, state persistence, or environment-variable exposure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest description and main explanatory section are presented in Chinese, but the file does not indicate that the skill is region-specific or that users may choose another language. This creates a natural-language policy concern because it effectively forces a locale/language without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This Python file contains user-facing descriptions, help text, and output messages exclusively in Chinese, indicating the skill is designed to operate in a single language without opt-in or alternative locale support. The policy explicitly flags language or locale constraints when the skill forces a specific language without user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This Python file contains natural-language descriptions that present the skill entirely in Chinese, starting with the module docstring. Under the policy, forcing a specific language or locale without user choice is a natural-language policy violation unless the locale constraint is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill persists conversation-derived state, including topic history, keywords, timestamps, and content snippets, to memory/context_switch_state.json. This expands the data lifetime and exposure surface beyond transient context handling, creating privacy and data-retention risk if sensitive prompts, secrets, or personal data appear in conversations or if local files are accessible to other components/users.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill reads arbitrary matching files from memory/topic and injects their contents into active memory_context during context handling. This undocumented external data ingestion can expose sensitive local information, create prompt/context poisoning risk from untrusted files, and cause the agent to act on data the user did not intend to load.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This markdown file is entirely written as Chinese-only operational guidance, with no indication that language selection is optional or limited to a justified region-specific use case. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This JSON state stores all topic labels and content snippets exclusively in Chinese, indicating the skill's natural-language behavior is tied to a specific language. There is no accompanying indication in the file that users can opt into another language or that the locale restriction is intentionally limited to a Chinese-specific use case.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module description and all user-facing strings are written in Chinese, indicating a fixed language behavior with no visible opt-in or alternative locale handling. Under the stated policy, forcing a specific language without user choice or documented justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The optimizer can automatically compress or reset context and persist those changes via the shared ContextManager state, which may silently discard or alter conversation memory without an explicit user warning or confirmation. In a context-management skill, this is risky because it can cause unintended loss of user state, summaries, or workflow continuity, especially when triggered only by token thresholds.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The report discloses internal implementation details including the state file path (memory/context_switch_state.json), operational counters, feature flags, and environment variable names/values. While not immediately critical, this information can aid reconnaissance by revealing filesystem layout, runtime configuration, and feature toggles that an attacker could use to tailor follow-on attacks or infer system behavior.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

For a skill whose purpose is context switching and token optimization, inspecting process environment variables is not an obvious functional requirement of the core conversation-management task. While used here only for configuration overrides, it still introduces a runtime capability outside the manifest's described scope.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · context_manager.py (reported line 110)May include surrounding context.

python
apply_environment_overrides(cfg)
    lvl = cfg.get("context_switch", {}).get("log_level")
    if lvl:
        logging.getLogger().setLevel(getattr(logging, lvl, logging.INFO))
        if not logging.getLogger().handlers:
            logging.basicConfig(level=getattr(logging, lvl, logging.INFO))
    return cfg

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · context_manager.py (reported line 112)May include surrounding context.

python
if lvl:
        logging.getLogger().setLevel(getattr(logging, lvl, logging.INFO))
        if not logging.getLogger().handlers:
            logging.basicConfig(level=getattr(logging, lvl, logging.INFO))
    return cfg

@dataclass

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file contains a Chinese-only module docstring and later uses Chinese-only print strings for all user-visible output. Under the policy rule, forcing a specific language without user opt-in or a documented regional justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This Python file contains natural-language strings exclusively in Chinese, including the module docstring and printed status messages. Under the stated policy, forcing a specific language without user opt-in can be a locale-policy violation when no alternative or justification is provided.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.