T05 · Unauthorized Access and Privilege Escalation
- Location
SKILL.md:49- Finding
Deliberate Bypass of Subagent File-Access Controls Through Symlinks
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent financial-content workflow, but it deliberately bypasses subagent file-access limits and includes unsafe pickle loading from auto-discovered local state files.
Install only if you trust the publisher and the local RLM state files. Before use, remove or replace the symlink workaround with an explicit approved-file import flow, and avoid running the cache builder on any state.pkl whose origin is not fully trusted. Review final content manually before it is copied to the shared threads folder, especially holdings claims and investment-position language.
SKILL.md:49Deliberate Bypass of Subagent File-Access Controls Through Symlinks
scripts/build_extraction_cache.py:57Arbitrary Code Execution Through Unsafe Pickle Deserialization
The skill advertises a broad end-to-end content pipeline, but the described behavior also includes undeclared access to local state under ~/.claude and pickle deserialization workflows. This mismatch makes risk review harder and can conceal sensitive local-file access or unsafe deserialization behind an apparently benign content-generation purpose.
These instructions provide a concrete step-by-step method for bypassing subagent file-access restrictions by symlinking blocked external PDFs into the project. That is a policy-evasion pattern: it defeats sandbox assumptions and could be repurposed to expose arbitrary external files to less-trusted components.
Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.
def extract_context_labels(text: str, window_start: int, window_size: int = 500) -> Dict[str, Any]:
"""
Extract context labels from text window around a data point.
Looks for:
- Product/server type (e.g., "HGX B300 8-GPU server", "GB300 rack")
Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.
def extract_context_labels(text: str, window_start: int, window_size: int = 500) -> Dict[str, Any]:
"""
Extract context labels from text window around a data point.
Looks for:
- Product/server type (e.g., "HGX B300 8-GPU server", "GB300 rack")
The skill instructs reading and writing files extensively, but it does not declare an explicit tool scope such as allowed-tools or permissions. That creates an authorization ambiguity where an operator may invoke the skill without realizing it can access local files and modify artifacts, increasing the risk of unintended filesystem access.
The trigger phrases are broad enough to invoke the skill during normal conversation, including generic requests like 'create content' or 'make a post.' Broad activation increases the chance of unintended execution of a workflow that reads local files, writes drafts, and may publish outputs.
The skill claims subagent access is confined to the project directory, then instructs creating a symlink so blocked external files appear inside the project. This is effectively guidance to bypass path-based restrictions and undermines the intended trust boundary for subagent file access.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
key_metrics = attr_map['topics'][topic]['key_metrics']
**Step 3b: Write using cache labels and attribution:**
```markdown
## Content
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
### Step 2b: Query All 7 Models
**NEVER assume a stock isn't held without checking ALL 7 models.**
**RECOMMENDED: Use tradebook for accurate entry prices and current status**
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
### Step 2b: Query All 7 Models
**NEVER assume a stock isn't held without checking ALL 7 models.**
**RECOMMENDED: Use tradebook for accurate entry prices and current status**
The skill includes an explicit publish-to-final-folder capability, moving from draft generation into deployment of ready-to-post content. Any skill that can publish or stage final outputs in shared locations raises integrity risks, especially if triggered broadly or used without a human approval gate.
The publishing instructions write into a shared final folder without an explicit warning or required user confirmation at the point of action. That can lead to accidental disclosure, overwrite, or premature staging of content in a location assumed to contain approved material only.
The skill includes commands to enumerate filesystem contents under /Users/Shared/ksvc/pdfs. While not inherently malicious, enumeration of local directories reveals environmental structure and can aid broader data discovery beyond the user's immediate request.
Research PDFs: /Users/Shared/ksvc/pdfs/
ls -la /Users/Shared/ksvc/pdfs/ | tail -5
The style guide explicitly encourages definitive investment-position language such as 'I'm long X because Y' and 'Here's why I'm long...' without requiring hedging, educational framing, or a disclaimer. In a content pipeline designed to generate publishable Twitter posts from research PDFs, this increases the chance of producing prescriptive financial content that could be interpreted as investment advice or manipulative promotion.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Single PDF:
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
topic = "memory_pricing"
source_tag = attr_map['topics'][topic]['tag'] # "GFHK"
# Write with attribution
write(f"{source_tag}'s BOM breakdown shows: ...")
# → "GFHK's BOM breakdown shows: ..."
# Not: "Goldman's BOM breakdown" (wrong attribution)
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.
Fix:
# Check if state.pkl exists
ls -la ~/.claude/skills/rlm-repl/scripts/.claude/rlm_state/state.pkl
# If not, run RLM first:
cd ~/.claude/skills/rlm-repl/scripts
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.
Fix:
# Check if state.pkl exists
ls -la ~/.claude/skills/rlm-repl/scripts/.claude/rlm_state/state.pkl
# If not, run RLM first:
cd ~/.claude/skills/rlm-repl/scripts
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.
"""
import sys
# Add rlm-v3 scripts to sys.path so pickle can resolve LazyContext class
rlm_v3_dir = Path.home() / '.claude/skills/rlm-v3/scripts'
if str(rlm_v3_dir) not in sys.path and rlm_v3_dir.exists():
sys.path.insert(0, str(rlm_v3_dir))
try:
The script performs risky deserialization of a pickle file without any prominent user-facing warning or consent step, so users may treat it as a normal cache-building utility while it can execute code as a side effect of loading state. Because this tool is designed for analyst workflows and automatically searches common state locations, the absence of warning materially raises the likelihood of unsafe use.
The script deserializes a local state.pkl using pickle.load(), which can execute attacker-controlled code during loading if the pickle file is replaced or poisoned. In this skill, the script auto-discovers state files from multiple predictable locations under the user's home directory, increasing the chance it will consume untrusted or stale data without explicit trust validation.
sys.path.insert(0, str(rlm_v3_dir))
try:
with open(state_path, 'rb') as f:
return pickle.load(f)
except (AttributeError, ModuleNotFoundError):
# LazyContext class not importable — fall back to loading without it
# This means lazy states can't be loaded, but eager states work fine
This markdown file includes commands that create an extraction cache at a user-specified path and later inspect the created file, but it does not warn that the operation writes to disk and may overwrite an existing file. Because SQP-2 applies to markdown files when descriptions omit warnings about behavior affecting user data or system integrity, this is a valid missing-warning issue.
The example explicitly opens draft/2026-02-05-topic-assets/rlm-extraction-cache.json in write mode and dumps JSON content, which will create or overwrite the file. The surrounding markdown does not disclose this filesystem impact, so the skill description omits a user warning for a data-affecting operation.
No suspicious patterns detected.