T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:455
- Finding
- Batch pruning silently discards retained memory records from earlier batches## Vulnerability Details **File Location**: `SKILL.md`, lines 455–469 **Vulnerability Type**: Logic error causing destructive data loss **Risk Level**: High **Vulnerable Code**: ```python for i in range(0, len(memories), batch_size): batch = memories[i:i + batch_size] for memory in batch: memory['relevance_score'] = calculate_relevance_score(memory, "") kept, pruned = prune_low_value_memories(batch) pruned_count += len(pruned) log(f"Batch {i // batch_size + 1}: pruned {len(pruned)} memories") log(f"Total pruned: {pruned_count} memories") return kept ``` ### Technical Analysis The `kept` variable is overwritten during every loop iteration. Consequently, the function returns only the retained records from the final batch rather than all retained records across all batches. This defect becomes active whenever the number of memory records exceeds `batch_size`, which defaults to 50. Records that pass the relevance threshold in earlier batches are omitted from the returned collection. The usage examples elsewhere in the document save returned memory collections, so passing this incomplete result to the documented save operation can overwrite the active memory store and permanently remove valid records. This is an integrity and availability vulnerability in the Skill's memory-management logic. Exploitation does not grant operating-system privileges, but it can destroy Agent state, safety context, decisions, and audit history within the affected workspace. ### Attack Path 1. An attacker or untrusted workload causes the active memory collection to exceed the configured batch size. 2. Important target records are positioned in any batch other than the final batch. 3. Batch pruning evaluates those records and correctly places retained records into the local `kept` variable. 4. A later loop iteration overwrites `kept` with the retained records from the next batch. 5. The function retu ...[truncated 791 chars]
- Remediation
- ## Remediation Suggestions Accumulate retained records across every batch instead of returning the final batch's local result: ```python def batch_prune_memories(memories, batch_size=50): all_kept = [] pruned_count = 0 for i in range(0, len(memories), batch_size): batch = memories[i:i + batch_size] for memory in batch: memory['relevance_score'] = calculate_relevance_score(memory, "") batch_kept, batch_pruned = prune_low_value_memories(batch) all_kept.extend(batch_kept) pruned_count += len(batch_pruned) if len(all_kept) + pruned_count != len(memories): raise RuntimeError("Memory-count invariant failed") return all_kept ``` Additional hardening should include: - Add tests covering zero, one, and multiple batches. - Verify that `retained_count + pruned_count == input_count` before saving. - Reject duplicate or missing memory identifiers. - Save changes atomically to a temporary file and replace the original only after validation. - Keep a recoverable backup or transaction journal before overwriting active memory.
