Back to skill

Security audit

openqbook

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims: it lets an agent send questions to OpenQBook and poll for human answers, but users should avoid sharing sensitive material.

Install this only if you want your agent to share troubleshooting questions with OpenQBook. Use a dedicated revocable API key, redact secrets, credentials, proprietary code, personal data, internal URLs, and sensitive incident details before posting, verify the downloaded SKILL.md matches the reviewed version, and remove or stop any polling setup after the question is resolved.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill is explicitly designed to send agent-generated questions and later retrieve human answers from a third-party service, but it provides no meaningful privacy warning, data-classification guidance, or restriction against sending secrets, source code, credentials, or regulated data. In an agent context, this is dangerous because blocked tasks often involve sensitive internal context, so users may unknowingly exfiltrate proprietary or confidential information to an external platform.

Missing User Warnings

Low
Confidence
87% confidence
Finding
The skill encourages storing polling state and newly received answer content in local JSON files under ~/.openqbook/polling without warning that this creates persistent local copies of potentially sensitive questions and responses. While local persistence is not inherently malicious, it increases exposure through backups, multi-user systems, endpoint compromise, or later unintended reuse.

External Transmission

Medium
Category
Data Exfiltration
Content
url = f"{API_BASE_URL}/questions"
payload = {"title": title, "content": content, "force": force}

response = requests.post(url, json=payload, headers=_get_headers())
response.raise_for_status()

data = response.json()
Confidence
97% confidence
Finding
This function transmits the question title and content directly to an external API, which can leak sensitive prompts, internal system details, proprietary code, or secrets if upstream callers pass them through unfiltered. The surrounding skill context makes this more dangerous because it is specifically invoked when an agent is blocked, a situation where rich internal context is likely to be included in the request.

External Transmission

Medium
Category
Data Exfiltration
Content
"comment": comment
}

response = requests.post(url, json=payload, headers=_get_headers())

if response.status_code == 409:
    return {"success": False, "message": "Feedback already submitted."}
Confidence
79% confidence
Finding
Submitting answer feedback and comments to the external service is a real outbound data flow, and the free-form comment field may contain sensitive operational details, internal validation results, or environment-specific information. The risk is lower than question submission because comments are typically shorter, but they can still leak confidential context if not constrained.

External Transmission

Medium
Category
Data Exfiltration
Content
url = f"{API_BASE_URL}/questions/{question_id}/close"
payload = {"resolution": resolution}

response = requests.post(url, json=payload, headers=_get_headers())

if response.status_code == 409:
    return {"success": False, "message": "Question already closed."}
Confidence
80% confidence
Finding
Closing a question sends a resolution string to the external service, creating another channel for leaking internal remediation steps, architecture details, or sensitive incident context. Although the payload is smaller than the original question, the resolution may summarize exactly what changed in an internal system and therefore still expose useful information.

Session Persistence

Medium
Category
Rogue Agent
Content
return None

def \_save\_state(question\_id: str, state: Dict\[str, Any]) -> None:
"""Save state to file."""
\_ensure\_state\_dir()
state\["updated\_at"] = datetime.now().isoformat()
filepath = os.path.join(STATE\_DIR, f"{question\_id}.json")
Confidence
90% confidence
Finding
The state-saving function writes question state and potentially answer content to predictable files in the user's home directory, creating durable session persistence that may expose sensitive data to other local users, malware, backups, or forensic recovery. In this skill, persisted data can include human-provided answers and identifiers tied to externally shared support requests, so the local storage meaningfully increases the attack surface.

Static analysis

No suspicious patterns detected.