T07 · Tool Hijacking and Spoofing
- Location
src/FeishuCardSender.js:102- Finding
Fabricated Message Delivery and OpenClaw Tool Spoofing
- Content
View full analysis
Vulnerability Details
File Location:
src/FeishuCardSender.js:102-128; result propagation inindex.js:89-103
Vulnerability Type: Simulated API invocation and fabricated success response
Risk Level: HighVulnerable Code:
javascript async sendMessage(content, target = null) { try { // 这里模拟调用OpenClaw的message工具 // 在实际环境中,这里会调用真实的API console.log('🔄 调用OpenClaw message工具...'); console.log('📤 消息内容:', JSON.stringify(content, null, 2)); if (target) { console.log(`🎯 发送目标: ${target}`); } // 模拟API调用延迟 await new Promise(resolve => setTimeout(resolve, 500)); // 模拟成功响应 return { success: true, messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, timestamp: new Date().toISOString() }; } catch (error) { console.error('消息发送失败:', error); throw error; } }The fabricated result is subsequently returned to callers as a successful delivery:
javascript const result = await this.sender.sendCard(renderedCard, target); return { success: true, messageId: result.messageId, templateType, format, timestamp: new Date().toISOString(), duration: Date.now() - startTime };Technical Analysis
The JavaScript sender claims to invoke the OpenClaw message tool, but it performs no API or tool call. Instead, it waits for 500 milliseconds and creates a random, locally generated message identifier. The package entry point then reports unconditional success without verifying whether the underlying sender returned a successful result.
This behavior spoofs a legitimate tool operation. Applications cannot distinguish a real message delivery from the simulated response and may treat operational notifications, alerts, or workflow messages as delivered when they were never sent.
Attack Path
- An application calls
quickSend()or `FeishuCar ...[truncated 861 chars]
- An application calls
- Remediation
View remediation
Remediation Suggestions
- Replace the simulation with a real, authenticated message client or an explicitly injected OpenClaw tool adapter.
- Fail closed when no real transport is configured.
- Generate no local message identifier unless clearly marked as a local correlation ID.
- Propagate the actual transport result instead of returning unconditional success.
- Change
index.jsto inspectresult.successand return failure when delivery fails. - Add integration tests that verify message existence through the provider response rather than accepting a locally generated identifier.
- Clearly separate demo or mock implementations from production exports.
