Back to skill

Security audit

BookStack

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward BookStack API helper, but users should configure it only with HTTPS and a limited API token.

Install only if you trust the BookStack instance you configure. Use an HTTPS URL, avoid HTTP even for temporary setups, create a dedicated least-privilege API token, and be careful with delete/update commands because the script does not add an extra confirmation step.

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:14
Finding

BookStack API Credentials May Be Transmitted over an Untrusted Transport

Content
View full analysis

Vulnerability Details

File Location: scripts/bookstack.py, lines 14-41
Vulnerability Type: Missing HTTPS enforcement for authenticated API requests
Risk Level: Medium

Vulnerable Code

python
# Configuration from environment
BASE_URL = os.getenv('BOOKSTACK_URL', '').rstrip('/')
TOKEN_ID = os.getenv('BOOKSTACK_TOKEN_ID', '')
TOKEN_SECRET = os.getenv('BOOKSTACK_TOKEN_SECRET', '')

def api_call(method, endpoint, data=None, params=None):
    """Make API call to BookStack"""
    if not BASE_URL or not TOKEN_ID or not TOKEN_SECRET:
        print("❌ Error: BOOKSTACK_URL, BOOKSTACK_TOKEN_ID, and BOOKSTACK_TOKEN_SECRET required!")
        print("   Set them as environment variables or in your gateway config.")
        sys.exit(1)
    
    url = f"{BASE_URL}/api/{endpoint}"
    
    if params:
        url += '?' + urllib.parse.urlencode(params)
    
    try:
        req = urllib.request.Request(
            url,
            headers={
                "Authorization": f"Token {TOKEN_ID}:{TOKEN_SECRET}",
                "Content-Type": "application/json",
                "Accept": "application/json"
            },
            method=method
        )
        
        if data:
            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:

Technical Analysis

The script accepts BOOKSTACK_URL directly from the environment and does not parse its scheme or require HTTPS. It subsequently places the long-lived BookStack token ID and secret in the Authorization header of every API request.

If BOOKSTACK_URL uses plain HTTP, neither the credentials nor the request and response content receive transport-layer confidentiality or integrity protection. An attacker able to observe or alter network traffic could capture the token, modify API operations, or tamper with returned content.

The standard URL-opening behavior also ...[truncated 1882 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse BOOKSTACK_URL with urllib.parse.urlparse() before making any request.
  2. Require the https scheme by default and reject HTTP, unsupported schemes, missing hostnames, fragments, and embedded user information.
  3. If local development requires HTTP, permit it only through an explicit opt-in setting and restrict it to loopback hosts such as localhost, 127.0.0.1, or ::1.
  4. Disable redirects for authenticated requests or implement a redirect handler that allows only same-origin HTTPS redirects. Reject HTTPS-to-HTTP downgrades and changes to the scheme, hostname, or effective port.
  5. Use a least-privilege BookStack API token dedicated to this integration.
  6. Rotate the token immediately if it may previously have been used over HTTP or sent to an untrusted endpoint.
  7. Document HTTPS as mandatory rather than presenting it only as an example configuration.

Example validation logic:

python
parsed = urllib.parse.urlparse(BASE_URL)

if (
    parsed.scheme != "https"
    or not parsed.hostname
    or parsed.username is not None
    or parsed.password is not None
    or parsed.fragment
):
    raise ValueError(
        "BOOKSTACK_URL must be a valid HTTPS URL without embedded credentials"
    )

Redirect restrictions must additionally be implemented in the HTTP client because initial URL validation alone does not constrain subsequent redirect destinations.

Vulnerability Patterns
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (35)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/bookstack.py (reported line 47)May include surrounding context.

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The code substantially matches the stated BookStack integration purpose: it uses BookStack API endpoints, supports listing/getting/creating/updating/deleting books, chapters, and pages, provides search, and handles both HTML and Markdown page content. However, the description explicitly claims full CRUD for shelves, while the code only includes list_shelves, get_shelf, and create_shelf. There are no update_shelf or delete_shelf commands. This is a material description-to-behavior mismatch, though limited in scope; no unrelated or undeclared sensitive capabilities were observed.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/bookstack.py list_books

Static analysis

No suspicious patterns detected.