Back to skill

Security audit

Research Library

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local research-library skill, but it needs Review because its URL import and project-path handling create concrete file and network safety risks.

Review before installing. Prefer the ClawHub-reviewed package path over the unpinned pip name, run it as a normal user, avoid importing untrusted URLs or FTP links, use simple safe project IDs, and assume indexed metadata and exports may include sensitive file contents, GPS, author, or device information.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
reslib/cli.py:539
Finding

Unrestricted Remote Document Retrieval Enables Server-Side Request Forgery and Resource Exhaustion

Content
View full analysis
bool: """Check if a string is a URL.""" try: result = urlparse(s) return result.scheme in ("http", "https", "ftp") except Exception: return False ``` ```python if is_url(path): source_url = path # Download the file if not quiet and not json_output: echo_info(f"Downloading from {path}...") try: import urllib.request import tempfile # Create temp file with appropriate extension parsed = urlparse(path) ext = Path(parsed.path).suffix or ".bin" with tempfile.NamedTemporaryFile(suffix=ext, delete=False) as tmp: urllib.request.urlretrieve(path, tmp.name) file_path = Path(tmp.name) except Exception as e: echo_error(f"Failed to download: {e}") ctx.exit(1) ``` ### Technical Analysis The `add` command retrieves a user-supplied URL without validating its destination. The implementation accepts HTTP, HTTPS, and FTP URLs, but does not: - Reject loopback, link-local, private, multicast, or reserved IP addresses. - Block cloud instance metadata endpoints. - Validate DNS resolutions before connecting. - Revalidate destinations after HTTP redirects. - Apply explicit connection or read timeouts. - Impose a maximum response or downloaded-file size. - Restrict remote retrieval to approved domains. Consequently, a caller can direct the process to request services that are reachable from the machine running the CLI but are not reachable from the caller's own network position. Redirects and DNS rebinding may also bypass checks if only the original URL is validated in a future partial fix. Because the downloaded response is subsequently hashed, copied into the attac ...[truncated 2009 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
reslib/cli.py:597
Finding

Unsanitized Project Identifier Allows Attachment Writes Outside the Data Directory

Content
View full analysis
bool: """Check if a project exists, creating it if auto-create is enabled.""" cursor = conn.execute("SELECT id FROM projects WHERE id = ?", (project_id,)) if cursor.fetchone(): return True # Auto-create project conn.execute( "INSERT INTO projects (id, name) VALUES (?, ?)", (project_id, project_id.replace("-", " ").title()) ) conn.commit() return True ``` ```python # Copy file to attachments directory dest_dir = attachments_dir / project / datetime.now().strftime("%Y-%m") dest_dir.mkdir(parents=True, exist_ok=True) dest_path = dest_dir / f"{file_hash[:8]}_{file_path.name}" if not dest_path.exists(): shutil.copy2(file_path, dest_path) ``` ### Technical Analysis The user-controlled `project` value is used directly as a filesystem path component. `validate_project_exists()` only creates a database record; it does not validate the identifier as a safe single path segment. Python path composition does not enforce containment: - A project value containing `../` can traverse above `attachments_dir`. - An absolute project path can replace the preceding `attachments_dir` portion entirely. - Nested separators allow callers to create an arbitrary directory hierarchy. The destination filename contains a generated hash prefix, which limits direct control over the final filename. Nevertheless, the directory location is attacker-controlled, and a copy of an attacker-selected source file can be placed anywhere writable by the process. The application does not resolve the destination and confirm that it remains beneath the configured attachment root before calling `mkdir()` and `copy2()`. ### Attack Path 1. The atta ...[truncated 1493 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
reslib/worker.py:916
Finding

Extraction Timeout Leaves Parser Threads Running Indefinitely

Content
View full analysis
ExtractionResult: """ Run extraction with timeout. Uses a separate thread with join timeout to enforce extraction limits. """ result_holder = {"result": None, "error": None} def do_extract(): try: result_holder["result"] = self.extractors.extract(path, mime_type) except Exception as e: result_holder["error"] = e thread = threading.Thread(target=do_extract) thread.start() thread.join(timeout=timeout) if thread.is_alive(): # Extraction timed out # Note: We can't actually kill the thread in Python, but we can # proceed and let it finish in the background raise ExtractorTimeoutError( f"Extraction timed out after {timeout}s for {path}" ) if result_holder["error"]: raise result_holder["error"] return result_holder["result"] ``` ### Technical Analysis The code presents the thread join interval as an extraction timeout, but it only limits how long the worker waits. Python cannot safely terminate the running thread, so a timed-out parser continues executing in the background. The spawned thread is also non-daemonic by default. A hung parser can therefore remain active indefinitely and may prevent clean process termination. When multiple extraction jobs time out, each job can leave another active parser thread behind. The normal worker loop then continues to accept further jobs and spawn additional threads. The nominal worker-count limit consequently does not bound the actual number of concurrent extraction operations. Document parsers process complex, attacker-influenced formats such as PDFs and images. Malformed ...[truncated 1255 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
_meta.json:31
Finding

Unpinned Registry Installation Instruction Can Resolve to Unreviewed Package Code

Content
View full analysis
=8.0", "pdfplumber>=0.10", "pytesseract>=0.3.10" ] ``` ### Technical Analysis The metadata directs users to install `research-library` from the Python package registry by name without an exact version, artifact hash, verified source URL, or immutable commit reference. The audited artifact does not contain packaging metadata such as `pyproject.toml`, `setup.py`, or a lock file that establishes a verifiable relationship between the reviewed files and the package obtained by the documented `pip install research-library` command. As a result, following the installation instruction may retrieve code different from the audited artifact. Registry ownership changes, package-name collisions, dependency confusion, or a compromised release account could cause installation of attacker-controlled code. Python package installation may execute build backend or setup logic before the package is used. The broad `>=` dependency constraints also permit future dependency versions that were not included in this audit. ### Attack Path 1. A user follows the documented command `pip install research-library`. 2. The package installer resolves the mutable registry name rather than the locally reviewed artifact. 3. A malicious, compromised, or unrelated distribution is returned under that name, or a mutable transitive dependency resolves to a compromised release. 4. Package build or installation logic executes with the user's privileges. 5. The installed package can then access the same files, environment, network, and user permissions available to the Python installation process. This ...[truncated 604 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Rogue AgentSelf-Modification, Session Persistence
Findings (35)

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

The documented behavior claims a local research library with search, isolation, backup, restore, and async extraction, but the available evidence instead emphasizes test execution and subprocess usage without demonstrating those core features. This mismatch is dangerous because users and orchestrators may trust the declared purpose while the skill performs other actions, including running pytest via subprocess, which can execute arbitrary code in the repository context.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The restore command documentation does not clearly warn that restoring a backup can overwrite the current database state and discard more recent changes. In a local research library handling user documents and metadata, ambiguous restore guidance can cause destructive data loss, especially when paired with --force and automation.

Content

No source excerpt is available for this finding.

Context Leakage

High
Category
Data Exfiltration
Confidence
75% confidence
Finding

Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Content

Scanner excerpt · reslib/search.py (reported line 355)May include surrounding context.

python
snippet += "..."
        return snippet[:max_length]
    
    # Extract context around match
    start = max(0, match_idx - context_words)
    end = min(len(words), match_idx + context_words + 1)

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · reslib/worker.py (reported line 581)May include surrounding context.

python
if released_count:
                logger.info(f"Released {released_count} in-progress jobs back to queue")
            
            # Clear state
            self._worker_threads.clear()
            self._heartbeat_thread = None

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

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.

Content

Scanner excerpt · RESEARCH-LIBRARY-SKILL.md (reported line 139)May include surrounding context.

Manage Projects

bash
reslib projects list
reslib projects create --name "CNC Tool Changer"
reslib projects archive arduino  # Soft-delete old project

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file documents reslib backup and especially reslib restore as normal commands, but it does not warn that restore can replace or roll back the user's local library state. Because restore affects stored user data and system state, the skill description should disclose that impact before users run it.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises capabilities that imply file access, shell execution, and possibly network use, but it does not declare any explicit tool scope or permissions boundary. In a skill ecosystem, this increases the chance that an agent invokes the skill with broader privileges than users expect, enabling unintended file modification, command execution, or outbound access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Backup and restore operations inherently carry overwrite and data-loss risk, but the skill documentation does not warn users about destructive restore behavior or recovery limitations. In a system handling local research data, an unsafe restore flow could overwrite current state, corrupt projects, or lead to irreversible loss.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
74% confidence
Finding

The skill persists and organizes user research artifacts, links, tags, and project state over time, but there is no clear disclosure of retention boundaries, lifecycle controls, or safeguards around stored session-like knowledge. Persistent cross-referenced data can accumulate sensitive project context and later be surfaced unexpectedly through search, export, or restore operations.

Content

Scanner excerpt · SKILL.md (reported line 69)May include surrounding context.

md
- `reslib get` — View document details
- `reslib archive` / `reslib unarchive` — Manage documents
- `reslib export` — Export as JSON/Markdown
- `reslib link` — Create document relationships
- `reslib projects` — Manage projects
- `reslib tags` — Manage tags
- `reslib status` — System overview

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

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.

Content

Scanner excerpt · docs/CLI-REFERENCE.md (reported line 205)May include surrounding context.

text

**Options:**
- `-f, --force` — Archive without confirmation

**Examples:**

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

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.

Content

Scanner excerpt · reslib/cli.py (reported line 1002)May include surrounding context.

python
```

**Options:**
- `-f, --force` — Archive without confirmation

**Examples:**

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

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.

Content

Scanner excerpt · reslib/cli.py (reported line 1353)May include surrounding context.

python
```

**Options:**
- `-f, --force` — Archive without confirmation

**Examples:**

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
88% confidence
Finding

A restore --force option removes the confirmation barrier for an operation that can overwrite current state, making destructive restoration easier in scripts or by mistaken invocation. In the context of a local-first document library with backups and project data, this materially increases the risk of accidental or automated data loss.

Content

Scanner excerpt · docs/CLI-REFERENCE.md (reported line 382)May include surrounding context.

md
**Options:**
- `--list` — List available backups instead of restoring
- `-f, --force` — Restore without confirmation

**Examples:**

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file documents a bulk operation that archives every research item in a project using xargs with reslib archive {} --force. Although archiving is described elsewhere as reversible, this example encourages a sweeping data-modifying action without any warning to verify the target project or review the matched IDs before execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The guide explicitly documents extraction of sensitive metadata such as EXIF GPS coordinates and PDF author/creation data, but it does not warn users that this metadata may contain personal, location, or organizational information. In a local-first research library that indexes many file types, silently extracting and surfacing such metadata increases the risk of privacy leakage through search, display, export, backups, or cross-project references.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · docs/EXTRACTION-GUIDE.md (reported line 366)May include surrounding context.

Install All

bash
pip install pdfplumber pillow pytesseract
sudo apt install tesseract-ocr  # Debian/Ubuntu

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The URL validator permits ftp, http, and https, enabling network retrieval beyond a strictly local workflow. Supporting FTP is especially risky because it is plaintext and unauthenticated by default, increasing exposure to tampering, credential leakage, and unsafe remote ingestion.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The add command accepts arbitrary URLs and downloads them directly, which contradicts the stated local-first model and expands the attack surface to remote content ingestion. This can enable SSRF-style access to internal services if the CLI runs in a trusted environment, or at minimum cause unexpected network egress and ingestion of untrusted files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The export command writes document content, tags, links, and potentially extracted full text to an output file, but there is no confirmation prompt or explicit user-facing warning immediately before the write. Although the command name implies export, the code path performs a potentially privacy-impacting file write of stored research contents without additional disclosure at the point of action.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The confidence heuristic rewards text containing a hard-coded set of common English words, which disadvantages documents in other languages without offering user choice or documenting the limitation. This effectively bakes in an English-first assumption in natural-language processing behavior, which can violate language/locale neutrality expectations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The image extractor explicitly converts EXIF metadata into searchable text and includes sensitive fields such as GPSInfo, CameraOwnerName, BodySerialNumber, XPAuthor, and related identifiers in returned extraction results. In a research library that indexes and cross-references files, this can unintentionally expose location, device, and owner-identifying information to users, logs, search indexes, backups, or downstream consumers without consent or disclosure.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

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.

Content

Scanner excerpt · reslib/queue.py (reported line 146)May include surrounding context.

python
deduplicate: bool = True
    ) -> Optional[int]:
        """
        Add a job to the extraction queue.
        
        Args:
            attachment_id: ID of attachment to process

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The class docstring and init documentation say the ranking engine can be initialized with custom confidence, recency, and relevance weights, implying instance-specific scoring behavior. However, score() and score_with_breakdown() delegate to compute_rank_score(), which always uses the module-level constants CONFIDENCE_WEIGHT, RECENCY_WEIGHT, and RELEVANCE_WEIGHT instead of self.confidence_weight, self.recency_weight, and self.relevance_weight.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest emphasizes a local-first research library with search, but this file is specifically documented as a full-text search engine. In addition to searching, the constructor creates directories and may create a new database schema, which is materially broader than read/query behavior for a search component.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The manifest states 'Project isolation with cross-references,' which implies boundaries between projects with limited exceptions for linked items. This file includes unrestricted search across all projects, allowing enumeration of content from every project rather than only isolated per-project access with cross-reference traversal.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.