Back to skill

Security audit

Context Compressor

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed context-compression helper, but it can turn user or assistant conversation text into privileged system messages, which needs careful review before use.

Install only if you are comfortable with the host agent rewriting conversation history and adding summaries or notes as system messages. Prefer using it after changes that keep summaries in a lower-trust memory channel, preserve source roles, redact secrets and personal data, and require explicit user control for high-risk sessions.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/strategies.py:103
Finding

Conversation summaries promote untrusted message content to system-level instructions

Content
View full analysis

Vulnerability Details

File Location: scripts/strategies.py:103-149
Vulnerability Type: Prompt-injection privilege elevation through unsafe role conversion
Risk Level: Medium

Vulnerable Code

python
# Generate summary
summary_parts = []
user_topics = []
assistant_actions = []
tool_results = []

for msg in old_messages:
    role = msg.get("role", "unknown")
    content = msg.get("content", "")

    if not content or content == "[工具输出已清理-超时]":
        continue

    if role == "user":
        # Extract the user's request topic using the first 100 characters
        topic = content[:100].strip()
        if len(content) > 100:
            topic += "..."
        user_topics.append(topic)
    elif role == "assistant":
        # Extract the assistant's action
        action = content[:100].strip()
        if len(content) > 100:
            action += "..."
        assistant_actions.append(action)
    elif role == "tool":
        # Briefly record the tool result
        tool_name = msg.get("name", "unknown_tool")
        tool_results.append(f"{tool_name}")

# Build summary text
if user_topics:
    summary_parts.append(f"用户请求({len(user_topics)}条): " + "; ".join(user_topics[:5]))
    if len(user_topics) > 5:
        summary_parts[-1] += f" ...等{len(user_topics)}条"

if assistant_actions:
    summary_parts.append(f"助手操作({len(assistant_actions)}条): " + "; ".join(assistant_actions[:5]))
    if len(assistant_actions) > 5:
        summary_parts[-1] += f" ...等{len(assistant_actions)}条"

if tool_results:
    unique_tools = list(set(tool_results))
    summary_parts.append(f"使用工具({len(tool_results)}次): " + ", ".join(unique_tools[:10]))

summary_text = "[历史对话摘要] " + " | ".join(summary_parts) if summary_parts else "[历史对话摘要] 无重要内容"

# Build the new message list
summary_msg = {
    "role": "system",
    "content": summary_text,
    "_is_summary": True,
    "_summari
...[truncated 2129 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not place summaries derived from user or tool content into a system message. Use a non-privileged role or a dedicated metadata field interpreted by trusted application code.
  2. Preserve provenance for every summarized item, including its original role and message identifier.
  3. If system-level placement is unavoidable, prepend a fixed developer-controlled instruction stating that the enclosed material is untrusted quoted data and must never be interpreted as instructions.
  4. Place summaries inside explicit data delimiters and ensure user-controlled text cannot terminate or imitate those delimiters.
  5. Use a summarization process that extracts factual state rather than copying leading message text verbatim.
  6. Add adversarial tests using instructions at the beginning of old user messages. Verify that compression never changes their authority or emits them as executable system instructions.
  7. Apply output validation to reject or neutralize instruction-like summary content before constructing the compressed context.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/strategies.py:217
Finding

Structured note extraction injects attacker-controlled text into the system prompt

Content
View full analysis

Vulnerability Details

File Location: scripts/strategies.py:217-294
Vulnerability Type: Prompt injection through unsafe structured-note promotion
Risk Level: Medium

Vulnerable Code

python
# Key information patterns
PATTERNS = [
    (r"(?:决策|决定|结论|确定)[::]\s*(.+?)(?:\n|$)", "decision"),
    (r"(?:发现|结果|输出)[::]\s*(.+?)(?:\n|$)", "finding"),
    (r"(?:重要|关键|注意)[::]\s*(.+?)(?:\n|$)", "important"),
    (r"(?:错误|问题|bug|缺陷)[::]\s*(.+?)(?:\n|$)", "issue"),
    (r"(?:方案|计划|策略)[::]\s*(.+?)(?:\n|$)", "plan"),
]

def apply(self, messages: list) -> Tuple[list, bool]:
    notes = []

    for msg in messages:
        content = msg.get("content", "")
        role = msg.get("role", "")

        # Extract only from assistant and user messages
        if role not in ("assistant", "user"):
            continue

        for pattern, note_type in self.PATTERNS:
            matches = re.findall(pattern, content, re.IGNORECASE)
            for match in matches:
                match = match.strip()
                if match and len(match) > 5:
                    notes.append({
                        "type": note_type,
                        "content": match[:200],
                        "source_role": role,
                    })

    if not notes:
        return messages, False

    # Build structured notes
    notes_by_type = {}
    for note in notes:
        t = note["type"]
        if t not in notes_by_type:
            notes_by_type[t] = []
        notes_by_type[t].append(note["content"])

    type_labels = {
        "decision": "决策",
        "finding": "发现",
        "important": "重要信息",
        "issue": "问题/错误",
        "plan": "方案/计划",
    }

    notes_parts = []
    for note_type, items in notes_by_type.items():
        label = type_labels.get(note_type, note_type)
        unique_items = list(dict.fromkeys(items))[:5]
        notes_parts.append(f"{l
...[truncated 3132 chars]
Remediation
View remediation

Remediation Suggestions

  1. Never append text extracted from user messages directly to an existing system prompt.
  2. Store notes in structured application metadata with explicit fields for value, source role, source message identifier, and trust level.
  3. If notes must be sent to the model, use a lower-privilege role and a fixed trusted instruction explaining that notes are untrusted evidence, not commands.
  4. Replace broad regular-expression extraction with schema-based state updates validated by trusted application logic.
  5. Reject imperative or policy-like content from structured notes, particularly phrases that attempt to override instructions, disclose data, or invoke tools.
  6. Keep user-derived notes separate from assistant-derived notes and never merge either into developer-authored policy text.
  7. Make delimiters fixed and non-overridable, and encode extracted values as data rather than concatenating them into free-form instructions.
  8. Add regression tests for every recognized marker followed by adversarial instructions. Tests should assert that extracted user content never receives the system role and is never appended to the original system prompt.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

StructuredNoteExtractor uses regexes to lift potentially sensitive statements from user/assistant messages into persistent notes appended to a system message. This increases both retention and exposure risk because high-salience items like decisions, findings, issues, or plans often contain confidential information and are preserved in privileged context.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill advertises automatic compression when context exceeds a threshold, but the trigger semantics are not tightly specified in the skill file itself. Ambiguous auto-triggering can cause compression to run in unintended situations, potentially discarding or summarizing security-relevant context, instructions, or evidence needed for safe agent behavior.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Several trigger phrases, such as generic 'context compress' and 'token 超限', are broad enough to match routine conversation or loosely related requests. In an agent system, overly broad triggers can invoke the skill unexpectedly, leading to unwanted modification of active context and increasing the chance that important constraints, recent evidence, or tool outputs are hidden or reduced.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code file contains natural-language documentation and usage context entirely in Chinese, including the module description and method docstrings, without indicating that the skill is region-specific or that users may opt into another language. Per the policy, forcing a specific language without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The summarizer copies raw user content into a retained summary message, which can re-surface sensitive data that the compressor was supposed to minimize. Even truncated text may still expose credentials, personal data, or confidential requests, and placing it in a summary can prolong retention across turns.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

ConversationSummarizer injects a synthesized system message derived from prior conversation content without preserving trust boundaries. Because system messages typically outrank user/assistant content, summarized user text or injected phrases can gain undue authority and influence later behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

StructuredNoteExtractor copies content extracted from user/assistant messages into a system-role message, which changes the privilege level of untrusted conversational text. This can turn ordinary text containing instructions, secrets, or prompt-injection content into higher-priority guidance that later model turns may follow or preserve more strongly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Structured note extraction promotes matched user and assistant text into the system prompt, again crossing a trust boundary. Regex-matched snippets like plans, decisions, findings, or 'important' text may include attacker-controlled instructions or sensitive content, which then persist as privileged context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This Python test file contains natural-language docstrings and console output exclusively in Chinese, including the module description and execution instructions. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation, and no language choice or locale justification is present in the file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

This markdown file presents all user-facing guidance exclusively in Chinese, and there is no indication that the skill is region-specific or that users can choose another language. 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

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

Natural-language descriptions, comments, and injected marker strings are consistently Chinese-only, which can force a specific language/locale on users or operators who did not choose it. The file does not indicate that the language is configurable, optional, or justified as a region-specific skill.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.