T09 · Insecure Skill Coding Practices
- Location
index.ts:20- Finding
Embedding API credentials and memory contents may be transmitted over plaintext HTTP
- Content
View full analysis
Vulnerability Details
File Location:
index.ts:20-24andindex.ts:32-47
Vulnerability Type: Plaintext transmission of sensitive information
Risk Level: HighVulnerable Code
typescript const DEFAULT_CONFIG = { embedding: { apiKey: '', baseUrl: 'http://your-api-server:3000/v1', model: 'm3e-large' }, dbPath: '~/.openclaw/data/memory-m3e.db', autoCapture: false, autoRecall: false, indexInterval: 600000 };typescript async function getEmbedding(text, config) { const response = await fetch(`${config.embedding.baseUrl}/embeddings`, { method: 'POST', headers: { 'Authorization': `Bearer ${config.embedding.apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ model: config.embedding.model, input: [text] // array format }) }); if (!response.ok) { const errText = await response.text(); throw new Error(`Embedding API error: ${response.status} ${errText}`); } const data = await response.json(); return data.data[0].embedding; }The insecure HTTP configuration is also promoted in
SKILL.md:24:json "baseUrl": "http://your-embedding-server"Technical Analysis
The plugin sends an API credential in the
Authorizationheader and user-controlled memory or query text in the request body. The default configuration and documented setup permit and promote anhttp://embedding endpoint, while the implementation performs no protocol validation.HTTP does not provide transport encryption, endpoint authentication, or message integrity. An attacker with a network position between the OpenClaw host and the embedding service can inspect the bearer token and text, modify requests or responses, or impersonate the embedding service.
The affected flows include:
memory_store, which sends the complete text being persisted.- `memory_r ...[truncated 1550 chars]
- Remediation
View remediation
Remediation Suggestions
- Require
https://embedding endpoints during plugin registration and reject insecure schemes before any tool is exposed. - If local development requires plaintext HTTP, permit it only through an explicit opt-in setting and restrict it to loopback addresses such as
127.0.0.1,::1, orlocalhost. - Replace all documented HTTP examples with HTTPS endpoints and clearly state that memory contents are sent to the configured external service.
- Use standard TLS certificate verification. If private certificate authorities are required, configure a trusted CA rather than disabling certificate checks.
- Scope API keys to the minimum required service permissions, rotate any credential previously transmitted over HTTP, and impose usage limits where supported.
- Consider applying request timeouts and response-size limits to reduce exposure to a malicious or compromised endpoint.
- Avoid propagating complete remote response bodies in errors because they may contain sensitive service data that could subsequently enter logs.
Example validation:
typescript function validateEmbeddingUrl(baseUrl) { const url = new URL(baseUrl); if (url.protocol !== 'https:') { const isLoopback = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '::1'; if (!isLoopback) { throw new Error('The embedding baseUrl must use HTTPS.'); } } return url.toString().replace(/\/$/, ''); }- Require
