Back to skill

Security audit

Edith Senso Knowledge

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but it handles API keys and user questions in ways that could expose sensitive data or allow unsafe shell execution.

Review this skill before installing. It appears intended for Senso.ai knowledge-base search, not deception, but users should only use it if they are comfortable sending their questions and relevant document passages to Senso.ai. API keys should be configured through a proper secret store rather than pasted into chat, and the curl examples should be replaced with safely serialized requests before use.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:38
Finding

Shell Command Injection Through Unsafe Request-Data Interpolation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 38–42 and 67–71
Vulnerability Type: Command injection caused by unsafe interpolation of untrusted input into shell commands
Risk Level: High

Vulnerable code at lines 38–42:

bash
curl -s -X POST "https://sdk.senso.ai/api/v1/search" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ${SENSO_API_KEY}" \
  -d '{"query": "<user's question>", "top_k": 5}'

Vulnerable code at lines 67–71:

bash
curl -s -X POST "https://sdk.senso.ai/api/v1/generate" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ${SENSO_API_KEY}" \
  -d '{"query": "<user question>", "context": "<concatenated search result passages>"}'

Technical Analysis

The skill instructs the agent to invoke curl through the exec tool and replace placeholders inside single-quoted shell arguments. The values placed into these arguments can include a user-controlled question and, for the generation endpoint, passages returned by an external API.

A single quote in either value can terminate the shell's quoted argument. Additional shell operators can then be interpreted as commands rather than request data. Manual JSON construction also mishandles legitimate quotation marks, backslashes, control characters, and newlines, even when an input is not intentionally malicious.

The second command increases the exposed input surface because both the user's query and externally sourced document passages may be inserted into the command. The vulnerability is exploitable when an agent implements the documented placeholders through direct textual substitution before passing the resulting command to a shell.

Attack Path

  1. An attacker supplies a knowledge-base query containing a single quote followed by shell syntax and an attacker-selected command.
  2. The skill places the query into the single-quoted -d argument through direct placeholder s ...[truncated 1277 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not construct shell commands by substituting user questions or retrieved passages into command strings.
  • Prefer a structured HTTP client or tool that accepts the URL, headers, and JSON body as separate typed parameters without invoking a shell.
  • Serialize request bodies with a standard JSON library so quotation marks, backslashes, newlines, and control characters are escaped correctly.
  • If shell execution is unavoidable, pass untrusted values through environment or positional-argument boundaries and generate the body with a safe serializer, such as:
    bash
    payload="$(jq -n --arg query "$USER_QUERY" --argjson top_k 5 \
      '{query: $query, top_k: $top_k}')"
    
    curl -sS -X POST "https://sdk.senso.ai/api/v1/search" \
      -H "Content-Type: application/json" \
      -H "X-API-Key: ${SENSO_API_KEY}" \
      --data-binary "$payload"
    
  • Apply the same serialization controls to search-result passages sent to the generation endpoint.
  • Do not use eval, dynamically generated scripts, or nested shell expansion to execute the request.
  • Add tests containing single quotes, double quotes, command substitutions, shell separators, backslashes, and multiline input to verify that all values remain inert JSON data.
  • Run the execution tool under least privilege with restricted filesystem and network access to limit impact if another injection defect is introduced.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:27
Finding

Insecure API-Key Collection and Persistent Storage

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 27–32
Vulnerability Type: Plaintext secret disclosure and storage through conversational memory or unspecified configuration
Risk Level: Medium

Vulnerable code:

text
The user must have a Senso.ai API key. If they haven't configured one yet, tell them:

1. Sign up at https://senso.ai and create a project
2. Go to Settings > API Keys and generate a new key
3. Tell OpenClaw: "My Senso API key is sk-..." and store it for future use

The API key should be stored in OpenClaw's memory/config as `SENSO_API_KEY`.

Technical Analysis

The setup workflow explicitly asks users to disclose an API key in a conversational message and directs the agent to persist it in unspecified “memory/config.” It does not require a dedicated secret manager, encryption at rest, restrictive filesystem permissions, log redaction, access isolation, or a defined retention policy.

Conversational input may be retained in session histories, telemetry, debug logs, backups, or long-term agent memory. Storing a credential in general-purpose memory can also expose it to unrelated skills, future prompts, or users who can inspect that state. Assigning the value to SENSO_API_KEY does not by itself guarantee secure storage.

Attack Path

  1. The user follows the documented setup instructions and posts the Senso API key in chat.
  2. The plaintext key becomes part of the conversation record and is copied into persistent memory or configuration.
  3. The conversation, logs, backups, memory store, or configuration is accessible to another user, skill, plugin, local process, or system administrator beyond the intended secret boundary.
  4. That party extracts the key and authenticates to the Senso API as the affected user or project.
  5. The exposed credential remains usable until it expires or is manually revoked.

Impact Assessment

Exposure of the key may permit unauthorize ...[truncated 528 chars]

Remediation
View remediation

Remediation Suggestions

  • Do not instruct users to paste API keys into chat or other conversational channels.
  • Provide a dedicated secret-entry interface or require out-of-band configuration through an approved operating-system, platform, or cloud secret manager.
  • Store only a secret reference in agent memory; keep the credential itself outside general-purpose memory and configuration.
  • Ensure the secret value is encrypted at rest and in transit, access-controlled to the specific skill, and unavailable to unrelated tools or sessions.
  • Prevent secret values from appearing in prompts, command traces, telemetry, debug logs, error messages, and backups.
  • If an environment variable is used at runtime, populate it from the secret manager and restrict process and configuration access according to least privilege.
  • Document credential rotation and revocation procedures, and advise users to revoke any key previously entered into conversation history.
  • Use narrowly scoped, project-specific credentials with expiration and service-side rate limits where supported.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The activation criteria are broad enough to match common requests like 'look up' or 'find information,' which can cause the skill to trigger when the user may not specifically intend to send content to Senso.ai. In this skill, unintended activation matters because it results in external transmission of user queries to a third-party API.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs sending the user's question to Senso.ai and later may also send concatenated document passages to the generate endpoint, but it does not provide an explicit user-facing warning or consent cue about this third-party transmission. This creates a privacy and data-handling risk, especially for sensitive enterprise documents or spoken queries captured through smart glasses.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The skill uses an external curl call to transmit the user's question and an API key to a third-party endpoint, and elsewhere instructs optionally sending concatenated search-result passages for generation. External transmission is expected for this integration, but it remains security-relevant because ambiguous triggering or lack of disclosure can expose sensitive queries and document content outside the local agent environment.

Content

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

Use the exec tool to call the Senso.ai search endpoint:

bash
curl -s -X POST "https://sdk.senso.ai/api/v1/search" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ${SENSO_API_KEY}" \
  -d '{"query": "<user's question>", "top_k": 5}'