Skip to content

[Bug/Security] 同组织同名用户身份混淆 - Agent A2A通信时错误识别用户 #569

@Clawiee

Description

@Clawiee

Bug: 同组织同名用户身份混淆 - Agent 错误地向错误用户发送消息

Tags: bug, security, user-identification, a2a
Severity: 🔴 Critical (信息泄露风险)
Version: v1.9.3


问题描述

同组织内存在两个同名用户时(如两个"张三"),Agent 在 A2A 通信时会错误识别用户身份,将消息发送给错误的用户。

复现场景

组织内有两个同名用户:
- 用户A(张三):email: zhangsan@company.com
- 用户B(张三):email: zhangsan2@company.com

两个用户都跟 Agent 甲 有过沟通对话

用户B 让 Agent 甲 联系 Agent 乙
↓
Agent 乙 错误地识别用户B为用户A
↓
Agent 乙 把本应发给用户B的消息发给了用户A

影响范围

  1. 信息泄露:用户A可能收到原本发给用户B的私密信息
  2. 隐私侵犯:敏感业务信息被错误用户接收
  3. 信任损害:用户对平台安全性失去信心

可能的原因

1. 用户身份识别仅依赖姓名(display_name)

# 可能的错误代码
user = User.query.filter_by(name="张三").first()  # 总是返回第一个匹配

2. Agent 间消息传递时丢失或错误处理 user_id

当 Agent 甲 通过 send_message_to_agent 联系 Agent 乙 时:

  • 如果依赖"最后对话的用户"来确定发送对象
  • 可能只记录了姓名而非唯一标识符

3. 对话上下文中的用户标识不完整

  • Agent 的对话历史中可能只保存了 display_name
  • 缺少 user_idemail 等唯一标识符

4. A2A 消息路由时缺少用户身份验证

# 可能的错误代码示例
async def send_to_agent(message, target_agent, from_user):
    # 错误:只传递了姓名
    await target_agent.receive(message, user_name=from_user.name)
    
    # 正确应该传递:
    # await target_agent.receive(message, user_id=from_user.id, user_email=from_user.email)

修复建议

方案 1:在消息传递中强制使用唯一标识符

# Agent 间通信时,必须使用 user_id 而非 display_name
async def send_message_to_agent(
    message: str,
    target_agent_id: str,
    sender_user_id: str,  # 必须是唯一标识符
    sender_user_name: str = None,
    sender_user_email: str = None
):
    # 验证 sender_user_id 的有效性
    sender = User.query.filter_by(id=sender_user_id).first()
    if not sender:
        raise ValueError("Invalid sender user_id")
    
    # 存储时使用 user_id,display_name 仅用于展示
    message_record = ChatMessage(
        user_id=sender_user_id,  # 唯一标识
        user_name=sender_user_name,  # 展示用
        ...
    )

方案 2:用户标识符优先级

# 优先使用唯一标识符,fallback 到姓名时增加警告
def identify_user(identifier):
    # 1. 优先使用 user_id
    if identifier.startswith("user_") or is_uuid(identifier):
        return User.query.get(identifier)
    
    # 2. 使用 email(唯一)
    if "@" in identifier:
        return User.query.filter_by(email=identifier).first()
    
    # 3. 最后才用 name,但需要额外确认
    # 如果有多个匹配,抛出异常而非默认第一个
    users = User.query.filter_by(name=identifier).all()
    if len(users) > 1:
        raise AmbiguousUserError(
            f"Multiple users named '{identifier}'. "
            f"Please use user_id or email instead."
        )
    return users.first() if users else None

方案 3:审计日志记录

# 在所有用户相关操作中记录审计日志
audit_log.info(
    "A2A message sent",
    from_user_id=sender_user_id,
    from_user_name=sender_user_name,
    to_agent_id=target_agent_id,
    recipient_assumed_user_id=assumed_user_id,  # Agent乙认为的接收者
    actual_user_id=actual_user_id,  # 实际应该发送给的用户的user_id
)

验证测试用例

def test_same_name_users():
    """
    场景:同一组织内两个同名用户
    预期:Agent 乙 应该准确识别用户B,而非混淆为用户A
    """
    # 创建两个同名用户
    user_a = create_user(name="张三", email="zhangsan@company.com")
    user_b = create_user(name="张三", email="zhangsan2@company.com")
    
    # Agent 甲 与两个用户都有对话
    agent_甲 = create_agent()
    agent_乙 = create_agent()
    
    agent_甲.add_conversation(user_a, "Hello from A")
    agent_甲.add_conversation(user_b, "Hello from B")
    
    # 用户B让Agent甲联系Agent乙
    agent_甲.send_to_agent(
        message="用户B的消息",
        target=agent_乙,
        sender_user_id=user_b.id  # 传递唯一标识符
    )
    
    # 验证:Agent乙应该正确识别为用户B
    received_message = agent_乙.get_last_message()
    assert received_message.user_id == user_b.id
    assert received_message.user_name == "张三"
    assert received_message.user_email == "zhangsan2@company.com"

相关代码位置

需要检查的文件:

  • backend/app/services/message_service.py - 消息服务
  • backend/app/services/agent_manager.py - Agent管理
  • backend/app/tools/send_message_to_agent.py - A2A通信工具
  • backend/app/models/chat_session.py - 对话会话模型
  • backend/app/models/user.py - 用户模型

报告人: xiaoan
报告时间: 2026-05-13
优先级建议: 🔴 Critical(涉及用户隐私和数据安全)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions