Back to skill

Security audit

Solscribe

Security checks for vulnerabilities and agentic risk

Overview

SolScribe is mostly a local book-writing assistant, but it ships an undisclosed unauthenticated localhost server that can read and modify private manuscript data.

Review before installing. The core local writing workflow is coherent, but do not run server.py unless you are comfortable with any local process being able to access and change the manuscript through localhost:3847. Treat session_logs and backups as sensitive files, and do not rely on the current backup system as a perfect undo or permanent-recovery mechanism.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
server.py:23
Finding

Unauthenticated HTTP Interface Exposes Private Manuscript Data and Modification Operations

Content
View full analysis
Remediation
View remediation
` header for every endpoint other than a minimal health check. 3. Compare credentials using a constant-time comparison function. 4. Store the token in a file readable only by the owning user, such as mode `0600`. 5. Validate browser `Origin` headers against an explicit allowlist and reject unexpected origins. 6. Require `Content-Type: application/json` for JSON endpoints. 7. Separate read, write, delete, and export permissions where practical. 8. Return generic errors that do not expose private content or internal paths. 9. Prefer a Unix-domain socket with restrictive filesystem permissions if the service is intended exclusively for local clients. 10. Add automated tests confirming that unauthenticated requests cannot list, read, modify, delete, or export content. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
solscribe.py:44
Finding

Chapter Rename Operation Orphans Existing Content

Content
View full analysis
= 3: return parts[2].strip() return text ``` ```python def update_chapter(chapter_id, title=None, content=None, status=None): """Update chapter title, content, or status.""" state = load_state() for ch in state["chapters"]: if ch["id"] == chapter_id: if title is not None: ch["title"] = title if status is not None: ch["status"] = status ch["updated"] = datetime.now().isoformat() break save_state(state) if content is not None: chapter = get_chapter(chapter_id) write_chapter_file(chapter, content) backup(f"Update chapter: {title or chapter_id}") return get_chapter(chapter_id) ``` The affected command path is: ```python rename_m = re.match(r"rename\s+chapter\s*(\d+)[:\s]+(.+)", text, re.IGNORECASE) if rename_m: num = int(rename_m.group(1)) new_title = rename_m.group(2).strip() for ch in chapters: if ch["order"] == num: update_chapter(ch["id"], title=new_title) return (f"Renamed Chapter {num} to '{new_title}'.", False) ``` ### Technical Analysis The chapter filename is calcul ...[truncated 1394 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
solscribe.py:277
Finding

Backup Design Fails to Preserve Reliable Historical Versions

Content
View full analysis
50: oldest = backups.pop(0) shutil.rmtree(oldest) ``` ```bash #!/bin/bash # Daily SolScribe backup — runs at 2am every day # Backs up book state, chapters, and pushes to GitHub cd ~/Projects/solscribe python3 -c "from solscribe import backup; backup('Daily backup')" 2>> ~/Projects/solscribe/backups/backup.log ``` The documentation states: ```markdown **Important:** Chapters are never overwritten. `revise chapter N:` replaces content, but the old content is preserved in backups. Nothing is ever permanently lost. ``` ```markdown - **Auto-backup on every write** — timestamped snapshots in `backups/` - **Daily cron** — at 2am Europe/London - **Session logs** — every conversation saved in `session_logs/YYYY-MM-DD.md` ``` ### Technical Analysis Backup directory names have only one-second resolution. Multiple changes made during the same second select the same directory because `mkdir(exist_ok=True)` permits reuse. Files copied by the later backup overwrite files copied by the earlier backup, so distinct historical versions are not guaranteed. Backups are invoked after chapter and state modifications. Consequently, each operation generally captures the new state rather than c ...[truncated 1763 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
server.py:75
Finding

Unbounded HTTP Request Bodies Permit Local Denial of Service

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
solscribe.py:65
Finding

Unescaped Chapter Titles Can Corrupt YAML Frontmatter

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (17)

Scope Creep

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Pushing to GitHub implies network/external repository access, but the declared permissions are only file.read and file.write. This mismatch is a significant security issue because it can conceal unauthorized data egress paths and bypass user expectations about the skill being limited to local filesystem operations.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
95% confidence
Finding

This file starts a local HTTP server, which is a network-facing capability not declared in the skill permissions. Even though it binds to localhost, any local process can interact with it, expanding the attack surface and enabling unintended access to reading, writing, and export functionality through unaudited API calls.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'shell' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The catch-all [plain text] trigger is overly broad for a skill with file.write permission because ordinary conversation text can be reinterpreted as a command to append content or create a chapter. In practice, this increases the chance of unintended file modifications, accidental data creation, or prompt/command confusion when the user did not explicitly intend a write operation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill states that every conversation is saved in session_logs/YYYY-MM-DD.md, but the user-facing description does not clearly foreground this as persistent storage of potentially sensitive material. Because this is a writing assistant that may receive book drafts and personal content from chat, email, or WhatsApp, silent comprehensive logging materially increases privacy and confidentiality risk if the machine, repo structure, or backups are later accessed.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script description explicitly states it 'pushes to GitHub', which introduces outbound data transfer beyond a purely local book-writing companion. That creates a real risk of exfiltrating manuscript content, notes, or other project data to a remote service without that capability being reflected in the stated scope or permissions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

A long-form writing assistant generally justifies local file access, but not silent synchronization to GitHub. Because creative manuscripts may contain unpublished or sensitive material, adding remote repository push capability without clear justification or disclosure makes the skill materially more dangerous in context.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest presents a creative writing assistant, but the code runs a background daemon with local API endpoints. This mismatch is dangerous because users and reviewers may not expect a persistent service process, making it easier for hidden capabilities to evade scrutiny and for other local software to invoke file-affecting operations indirectly.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Implementing a local network service for a book-writing assistant creates an unnecessary control surface relative to the stated purpose. The service exposes chapter access, write routing, and export operations over HTTP without any authentication, so any local process can potentially trigger state changes or data access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The write endpoint forwards arbitrary user text to the skill handler with no visible disclosure of possible downstream state changes. In context, this is risky because the handler may create, update, revise, or delete chapter content, and exposing that over an unauthenticated local HTTP API allows silent manipulation by other local software.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The export endpoint writes a DOCX file to the user's Documents directory without any visible confirmation, warning, or access control in this file. Because the server listens on localhost and lacks authentication, another local process could trigger file creation unexpectedly, causing unwanted persistence of potentially sensitive manuscript content.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The inline comment at L090 states that existing content will be preserved and appended to, but the implementation calls revise_chapter with the new content as replacement. This is an active contradiction between documented intent and actual behavior.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill accepts a user-provided path for DOCX export and writes to it with no restriction to an application-owned directory or extension validation. Because the skill has file.write permission, a caller can cause writes to arbitrary locations the process can access, which exceeds the expected scope of a book-writing companion and can overwrite or plant files in unintended places.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The top-level docstring asserts chapter content remains 'private on-disk only,' suggesting a constrained storage model. However, export_docx saves the compiled manuscript to any caller-supplied output path, which broadens where the content can be written and contradicts the narrow privacy/storage claim in the documentation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill persistently logs full conversation exchanges to disk, which exceeds the stated book-writing/chapter-management behavior and creates a secondary store of user data unrelated to core chapter operations. In a writing assistant context, these messages may include drafts, personal notes, or sensitive manuscript material, increasing unnecessary data retention risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The logging function writes complete user and assistant messages to persistent markdown files without any visible consent, warning, or minimization. This is dangerous because creative-writing conversations often contain personal, proprietary, or sensitive text that users may not expect to be archived outside the chapter files.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Persistently recording full user messages creates a durable repository of potentially sensitive material, including unpublished manuscript text, autobiographical details, or private brainstorming. In this skill's context, that retained data is especially sensitive because the default book title and author suggest memoir/personal writing, making inadvertent privacy harm more likely.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.