Back to skill

Security audit

BookStack API

Security checks for vulnerabilities and agentic risk

Overview

This BookStack integration appears purpose-built, but it gives agents broad write/delete access to a live wiki with weak scoping and limited safety guidance.

Review before installing. Use a dedicated least-privilege BookStack API token, prefer read-only permissions unless writes are needed, require explicit confirmation before delete or bulk update requests, and only configure an HTTPS BookStack URL. Keep the local credential file private and out of synced folders or source control.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/bookstack.py:17
Finding
BookStack API Credentials May Be Transmitted over Cleartext HTTP## Vulnerability Details **File Location**: `scripts/bookstack.py:17, 33-39` **Vulnerability Type**: Unencrypted transmission of API credentials **Risk Level**: Medium ### Vulnerable Code ```python BASE_URL = os.getenv('BOOKSTACK_URL', '').rstrip('/') TOKEN_ID = os.getenv('BOOKSTACK_TOKEN_ID', '') TOKEN_SECRET = os.getenv('BOOKSTACK_TOKEN_SECRET', '') # ... url = f"{BASE_URL}/api/{endpoint}" # ... req = urllib.request.Request( url, headers={ "Authorization": f"Token {TOKEN_ID}:{TOKEN_SECRET}", "Content-Type": "application/json", "Accept": "application/json", "User-Agent": "BookStack-CLI/1.0" }, method=method ) ``` ### Technical Analysis The script obtains `BOOKSTACK_URL` from the environment and uses it directly without validating its URL scheme. Consequently, a URL beginning with `http://` is accepted. Every API request includes the BookStack token ID and secret in the `Authorization` header. When HTTP is used, TLS does not protect this header, allowing an attacker with visibility into the network path to read the credentials. Network access and API authentication are necessary for the Skill's declared BookStack integration, but transmitting credentials over an unencrypted channel does not satisfy least-privilege and secure-transport requirements. The issue does not require command execution or malicious code in the repository. Exploitation depends on an HTTP configuration and an attacker able to observe or manipulate the relevant network traffic. ### Attack Path 1. The user or deployment configures `BOOKSTACK_URL` with an `http://` URL. 2. The Skill invokes a BookStack command such as `get_page`, `search`, or an update operation. 3. `api_call()` constructs an HTTP endpoint using the unvalidated base URL. 4. The script sends `BOOKSTACK_TOKEN_ID` and `BOOKSTACK_TOKEN_SECRET` in the cleartext `Authorization` header. 5. A network-positioned attacker captures the request and extracts the token. 6. The att ...[truncated 851 chars]
Remediation
## Remediation Suggestions 1. Parse `BOOKSTACK_URL` with `urllib.parse.urlparse()` before making requests. 2. Require the `https` scheme and a nonempty hostname. 3. Reject unsupported schemes, malformed URLs, fragments, and embedded user information. 4. If cleartext HTTP is needed for isolated local development, require an explicit opt-in environment variable and emit a prominent warning. Restrict the exception to loopback addresses where practical. 5. Use a dedicated BookStack API identity with only the permissions necessary for the intended operations. Avoid granting delete or broad administrative permissions when only search or read access is required. 6. Document certificate-validation requirements and do not introduce an option that disables TLS verification. Example hardening: ```python parsed = urllib.parse.urlparse(BASE_URL) if parsed.scheme != "https" or not parsed.hostname: print("Error: BOOKSTACK_URL must be a valid HTTPS URL") sys.exit(1) if parsed.username or parsed.password or parsed.fragment: print("Error: BOOKSTACK_URL contains unsupported components") sys.exit(1) ```
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (21)

Tainted flow: 'req' from os.getenv (line 33, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
data = {k: v for k, v in data.items() if v is not None}
            req.data = json.dumps(data).encode()
        
        with urllib.request.urlopen(req, timeout=30) as response:
            if response.status == 204:
                return None
            return json.loads(response.read().decode())
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The code substantially matches the declared BookStack integration purpose: it connects to a BookStack instance, authenticates with BookStack API credentials, and supports operations on books, chapters, pages, and search. However, the description explicitly claims full CRUD for books, chapters, pages, and shelves. In the supplied code, shelves only support list_shelves, get_shelf, and create_shelf; there are no update_shelf or delete_shelf commands/functions. That is a concrete description-versus-behavior mismatch. No unrelated or undeclared dangerous capabilities are evident beyond the stated BookStack API interactions.

Vague Triggers

High
Confidence
98% confidence
Finding
The activation guidance is overly broad and triggers on generic phrases like 'update the docs' or 'check the wiki' even without explicit BookStack context. That can cause the agent to invoke this skill in unrelated documentation workflows, potentially sending sensitive content to the configured BookStack instance or performing unintended modifications in the wrong system.

Ae1

High
Category
analysis-evasion
Content
python3 scripts/bookstack.py <command> [args] [options]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

External Script Fetching

High
Category
Supply Chain
Content
capture_output=True, text=True, env={...}
)

# Or use curl for Cloudflare-protected instances
# curl -s -H "Authorization: Token ID:SECRET" \
#   "https://bookstack.example.com/api/pages/24" | python3 -c "..."
```
Confidence
95% confidence
Finding
The example encourages piping content fetched over the network directly into `python3 -c`, which is a classic remote code execution anti-pattern. If the endpoint, transport, credentials, or response are compromised, arbitrary code could execute on the user's machine; in a skill context, this is more dangerous because it normalizes unsafe automation for users interacting with external services.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
| Resource | List | Read | Create | Update | Delete |
|----------|------|------|--------|--------|--------|
| Books | GET /api/books | GET /api/books/{id} | POST /api/books | PUT /api/books/{id} | DELETE /api/books/{id} |
| Chapters | GET /api/chapters | GET /api/chapters/{id} | POST /api/chapters | PUT /api/chapters/{id} | DELETE /api/chapters/{id} |
| Pages | GET /api/pages | GET /api/pages/{id} | POST /api/pages | PUT /api/pages/{id} | DELETE /api/pages/{id} |
| Shelves | GET /api/shelves | GET /api/shelves/{id} | POST /api/shelves | PUT /api/shelves/{id} | DELETE /api/shelves/{id} |
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
| Resource | List | Read | Create | Update | Delete |
|----------|------|------|--------|--------|--------|
| Books | GET /api/books | GET /api/books/{id} | POST /api/books | PUT /api/books/{id} | DELETE /api/books/{id} |
| Chapters | GET /api/chapters | GET /api/chapters/{id} | POST /api/chapters | PUT /api/chapters/{id} | DELETE /api/chapters/{id} |
| Pages | GET /api/pages | GET /api/pages/{id} | POST /api/pages | PUT /api/pages/{id} | DELETE /api/pages/{id} |
| Shelves | GET /api/shelves | GET /api/shelves/{id} | POST /api/shelves | PUT /api/shelves/{id} | DELETE /api/shelves/{id} |
| Search | GET /api/search?query= | — | — | — | — |
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
|----------|------|------|--------|--------|--------|
| Books | GET /api/books | GET /api/books/{id} | POST /api/books | PUT /api/books/{id} | DELETE /api/books/{id} |
| Chapters | GET /api/chapters | GET /api/chapters/{id} | POST /api/chapters | PUT /api/chapters/{id} | DELETE /api/chapters/{id} |
| Pages | GET /api/pages | GET /api/pages/{id} | POST /api/pages | PUT /api/pages/{id} | DELETE /api/pages/{id} |
| Shelves | GET /api/shelves | GET /api/shelves/{id} | POST /api/shelves | PUT /api/shelves/{id} | DELETE /api/shelves/{id} |
| Search | GET /api/search?query= | — | — | — | — |
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
| Books | GET /api/books | GET /api/books/{id} | POST /api/books | PUT /api/books/{id} | DELETE /api/books/{id} |
| Chapters | GET /api/chapters | GET /api/chapters/{id} | POST /api/chapters | PUT /api/chapters/{id} | DELETE /api/chapters/{id} |
| Pages | GET /api/pages | GET /api/pages/{id} | POST /api/pages | PUT /api/pages/{id} | DELETE /api/pages/{id} |
| Shelves | GET /api/shelves | GET /api/shelves/{id} | POST /api/shelves | PUT /api/shelves/{id} | DELETE /api/shelves/{id} |
| Search | GET /api/search?query= | — | — | — | — |

Auth header: `Authorization: Token {TOKEN_ID}:{TOKEN_SECRET}`
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README highlights management capabilities including create, read, update, and delete operations, but does not prominently warn that the skill can alter or remove remote wiki content. Users may assume a documentation/search integration is mostly read-only and authorize actions without understanding the risk of destructive changes.

Session Persistence

Medium
Category
Rogue Agent
Content
## Configuration

Create an API token in BookStack: **Profile > API Tokens > Create Token** (the user's role must have "Access System API" permission).

Add credentials to `~/.clawdbot/clawdbot.json`:
Confidence
78% confidence
Finding
The skill instructs users to persist BookStack API credentials in a local JSON configuration file, creating long-lived session/API material on disk. If the host, account, or repository is compromised, these credentials can be reused to access and modify BookStack content remotely.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The README encourages very broad natural-language triggering such as "update the docs" or "check the wiki" without requiring explicit confirmation that BookStack should be used. In a skill that can create, update, and delete remote content, this increases the chance of unintended invocation and accidental modification of a live knowledge base.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill requires environment-provided credentials and instructs use of a networked Python script, but it does not declare any explicit tool scope such as allowed tools or permissions. This weakens containment and review because an agent may invoke network and secret-bearing operations without clear policy boundaries, increasing the chance of unintended external access or credential use.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill documents create, update, and delete operations without warning that they are data-modifying and may be irreversible. In an agent setting, lack of guardrails around destructive actions increases the risk of accidental page deletion or unintended content changes, especially when combined with broad activation guidance.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This markdown reference includes `delete_book <id>` as a supported command but provides no caution that it will remove content and may be irreversible. For markdown files, destructive behaviors that can affect user data should be accompanied by a clear warning.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The command reference documents `delete_chapter` and `delete_page` but does not warn users that these actions can remove stored content or alter knowledge-base structure. In markdown skill documentation, operations affecting user data should include explicit warnings.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The delete_book operation performs an irreversible DELETE request immediately with no confirmation prompt, dry-run, or force flag. In a documentation-management skill with broad CRUD capability, accidental invocation or prompt/agent misuse could delete knowledge-base content and cause integrity and availability loss.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The delete_chapter command issues a destructive API call without any user warning or confirmation. Given this skill is intended for agent-driven automation around wiki/documentation updates, a mistaken or manipulated request could remove structured documentation content unexpectedly.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The delete_page command permanently deletes a page with no guardrail against accidental or unauthorized destructive use. In the context of a knowledge-base integration used by an autonomous agent, this increases the risk of prompt-driven or operator-error data loss.

Missing User Warnings

Low
Confidence
82% confidence
Finding
The configuration section instructs users to store API credentials locally but gives no security guidance on protecting the token secret. This can lead to insecure handling, accidental sharing of config files, or overprivileged token use, which could expose access to the BookStack API.

Missing User Warnings

Low
Confidence
80% confidence
Finding
The file shows the authorization header format containing `TOKEN_ID` and `TOKEN_SECRET`, but does not caution users that these are sensitive credentials and should not be exposed in logs, shell history, or shared examples. Markdown descriptions should warn about privacy or credential-handling risks when sensitive data is involved.

Static analysis

No suspicious patterns detected.