T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/local-agent/agent_link.py:121
- Finding
- Inbound Relay Messages Are Accepted Without Authentication<![CDATA[ ## Vulnerability Details **File Location**: `scripts/local-agent/agent_link.py`, lines 121–151 **Vulnerability Type**: Missing message signature verification **Risk Level**: High ### Vulnerable Code ```python if msg_type == "message": from_agent = data.get("from") to_agent = data.get("to") message = data.get("message") msg = Message( from_agent=from_agent, to_agent=to_agent, message=message, timestamp=datetime.now() ) logger.info(f"Received message from {from_agent}: {message[:50]}...") # 调用消息处理器 full_to = f"{self.instance_id}/{self.agent_id}" if to_agent == full_to or to_agent == self.agent_id: for handler in self.message_handlers.values(): try: handler(msg) except Exception as e: logger.error(f"Message handler error: {e}") ``` ### Technical Analysis The client signs outbound messages using HMAC-SHA256, but the inbound message-processing path does not retrieve or verify a signature. It also does not validate a trusted timestamp, nonce, sequence number, or other replay-protection value. Consequently, the values in the `from`, `to`, and `message` fields are treated as authentic solely because they arrived through the currently connected relay. A malicious or compromised relay can therefore assign an arbitrary sender identity and deliver attacker-controlled content to local message handlers. This behavior contradicts the documentation's claim that messages are signed and verified. Transport authentication alone would not fully resolve this issue because the relay itself remains capable of forging messages unless messages are authenticated end to end. ### Attack Path 1. An attacker compromises, impersonates, or operates the configured relay server. 2. The victim client connects and completes the relay's expected registration exchange. 3. The attacker sends a WebSocket frame such as: ```json { "type": ...[truncated 1126 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require every inbound application message to contain a signature generated by the originating instance. 2. Sign a canonical representation containing, at minimum: - Protocol version and message type - Sender and recipient - Message content - Creation timestamp - Cryptographically random nonce or monotonically increasing sequence number 3. Recompute the expected HMAC locally and compare it with `hmac.compare_digest()` rather than ordinary string comparison. 4. Reject missing, malformed, invalid, or stale signatures before constructing the `Message` object or calling handlers. 5. Store recently accepted nonces or sequence numbers and reject duplicates to prevent replay attacks. 6. Use distinct per-instance or per-Agent keys rather than one global shared secret. Alternatively, use asymmetric signatures so a relay can route messages without gaining the ability to forge them. 7. Apply strict schema and size validation to all incoming JSON fields. 8. Add tests demonstrating rejection of forged senders, modified content, stale timestamps, duplicate nonces, and missing signatures. ]]>
