跳转到正文
报告库
用途分类 / 其他用途

Lark Contact Skill 安全审计

作者说它能做什么(原文)

飞书 / Lark 通讯录:按姓名 / 邮箱解析成 open_id,或按 open_id 反查姓名 / 部门 / 邮箱 / 联系方式 / 个人状态 / 签名,以及按关键词搜索当前用户可见的机器人 / 智能体(agent)。当用户提到一个名字要下一步发消息 / 排日程,或拿到 open_id 想查具体信息时使用。不负责部门树遍历、按部门列员工、组织架构图,这类需求走原生 OpenAPI。

第三方安全检查结论

发现安全风险

已检查文件
4
发现的风险
1
会不会运行危险命令?检查是否下载程序后直接运行、让他人远程控制电脑,或藏起要运行的命令。未发现风险
会不会泄露文件和密钥?检查是否发送含密码或密钥的文件,以及代码里是否直接写了密钥。发现 1 项风险
中风险

无关键词筛选可批量枚举同事并暴露不必要的个人与关系数据

原文依据:5 处
发现了什么

文档允许只用布尔筛选、无需姓名或邮箱关键词,示例会列出所有曾聊过且已离职的同事。查询结果还可包含个人邮箱、部门、签名、账号状态以及是否聊过和 P2P 会话 ID。虽然受当前账号可见范围限制,这仍可能远超完成一次联系人解析所需的数据。

为什么需要注意

若代理对含糊请求执行此类广泛搜索,结果可能在模型上下文、终端输出或后续回复中暴露同事的联系方式、组织归属、离职状态和联系关系。批量 open_id 查询最多可一次回填 100 人,扩大单次泄露范围。

文档明确允许不提供姓名、邮箱或 ID,仅凭布尔筛选进行查询,并给出枚举所有“聊过天的离职同事”的可执行示例。返回契约包含个人/企业邮箱、部门、签名、账号状态,以及 P2P 会话 ID 和聊天关系;这些信息可能超出解析单个联系人的必要范围。风险发生在代理依照宽泛请求或自行选择该筛选方式时,但数据仍受当前用户身份的可见范围限制。用户可要求作者默认禁止 filter-only 枚举、限制返回字段,并在批量查询前确认范围与用途。

references/lark-contact-search-user.md:14来自说明文档打开原文件
`--query` / `--queries` / `--user-ids` / bool filter 至少传一个。bool filter 显式传 `=false` 会报错——不传等于不过滤。
查看另外 4 个位置
references/lark-contact-search-user.md:46来自说明文档打开原文件
# filter-only 枚举:列出所有"聊过天的离职同事"(无关键词)lark-cli contact +search-user --has-chatted --left-organization```
references/lark-contact-search-user.md:8来自说明文档打开原文件
- ✅ 已知姓名 / 邮箱 / 「聊过的人」想找出 open_id- ✅ 已知一组 open_id 想批量校验或回填字段(`--user-ids`,最多 100,支持 `me`)- ✅ 按聊天关系 / 在职状态 / 租户边界 / 企业邮箱等维度筛选员工- ❌ 已知 open_id 想发消息 → 直接走 `lark-im`,不经过本命令
references/lark-contact-search-user.md:100来自说明文档打开原文件
| `localized_name` | string | 按 `--lang` / brand 选出的展示名 | 始终非空(兜底为 open_id) || `email` | string | 个人邮箱 | 可能为空 || `enterprise_email` | string | 企业邮箱 | 可能为空 || `is_activated` | bool | 是否已激活飞书账号(未激活也可投递消息,但用户可能看不到) | 可能 false || `is_cross_tenant` | bool | 是否跨租户用户(同公司=false,外部联系人=true) | — || `p2p_chat_id` | string | 与当前用户的 P2P 会话 ID(`oc_...`);空表示从未私聊过。可作为接受 `--chat-id` 的 IM 命令的输入 | 可能为空 || `has_chatted` | bool | `p2p_chat_id != ""` 的派生字段 | — || `department` | string | 部门路径,服务端可能用 `-` 拼层级,层级数不固定。**按可子串匹配的字符串处理** | 可能为空 || `signature` | string (optional) | 用户个性签名;空时字段不出现 | 可能不出现 || `chat_recency_hint` | string | 最近联系的提示文案,仅供展示 | 可能为空 |
SKILL.md:63来自说明文档打开原文件
- **41050 / Permission denied** 受当前身份的可见范围限制(三条命令都可能遇到)。细节见 [`lark-shared`](../lark-shared/SKILL.md)。- **跨租户用户**(`is_cross_tenant=true`)多数业务字段为空字符串,这是飞书可见性规则,下游做空值兜底。- **ID 类型**:`+get-user` 可通过 `--user-id-type` 使用 `open_id`、`union_id` 或 `user_id`;`+search-user` 使用用户 open_id;`+search-bot` 不支持按 ID 查询,它按关键词搜索并返回机器人 open_id。
会不会删除文件或一直在后台运行?检查是否大范围删除文件、改写磁盘,或设置自动启动。未发现风险
会不会绕过安全保护?检查是否跳过网站安全验证、开放过多文件权限,或取消操作前的确认。未发现风险
会不会误导 AI 或隐藏内容?检查工作说明是否要求 AI 忽略你的指令、干扰检查结果,或夹带看不见的文字。未发现风险
会不会偷偷改推广链接或收款方?检查是否强制替换推广链接或收款对象,同时要求隐瞒更改。未发现风险

Skill 逻辑拆解

5 个说明模块

该 Skill 依赖 `lark-cli`,并按当前 user 或 bot 身份查询飞书通讯录;两种身份是独立路径,返回范围受当前身份可见权限限制。

查看原文
SKILL.md:6来自说明文档打开原文件
metadata:  requires:    bins: ["lark-cli"]  cliHelp: "lark-cli contact --help"---
SKILL.md:13来自说明文档打开原文件
**user 身份和 bot 身份是两条完全独立的路径**。先确定当前身份,再按下表选命令:
SKILL.md:63来自说明文档打开原文件
- **41050 / Permission denied** 受当前身份的可见范围限制(三条命令都可能遇到)。细节见 [`lark-shared`](../lark-shared/SKILL.md)。- **跨租户用户**(`is_cross_tenant=true`)多数业务字段为空字符串,这是飞书可见性规则,下游做空值兜底。

用户身份可按姓名、邮箱或手机号搜索人员,也可按最多 100 个 open_id 批量取回姓名、邮箱、部门、账号状态、会话标识及签名等资料。

查看原文
references/lark-contact-search-user.md:18来自说明文档打开原文件
|---|---|| `--query <text>` | 关键词(姓名 / 邮箱 / 手机号),≤ 50 rune || `--queries <csv>` | 多个关键词并行搜,**最多 20 条**;与 `--query` / `--user-ids` 互斥;输出新 shape(见下) || `--user-ids <csv>` | open_id 列表,≤ 100;支持 `me` 表示自己;与 `--query` 同传时把搜索范围限定在该集合 || `--has-chatted` | 仅搜聊过天的 |
references/lark-contact-search-user.md:98来自说明文档打开原文件
|---|---|---|---|| `open_id` | string | 稳定标识,后续命令的输入 | 始终非空 || `localized_name` | string | 按 `--lang` / brand 选出的展示名 | 始终非空(兜底为 open_id) || `email` | string | 个人邮箱 | 可能为空 || `enterprise_email` | string | 企业邮箱 | 可能为空 || `is_activated` | bool | 是否已激活飞书账号(未激活也可投递消息,但用户可能看不到) | 可能 false || `is_cross_tenant` | bool | 是否跨租户用户(同公司=false,外部联系人=true) | — || `p2p_chat_id` | string | 与当前用户的 P2P 会话 ID(`oc_...`);空表示从未私聊过。可作为接受 `--chat-id` 的 IM 命令的输入 | 可能为空 || `has_chatted` | bool | `p2p_chat_id != ""` 的派生字段 | — || `department` | string | 部门路径,服务端可能用 `-` 拼层级,层级数不固定。**按可子串匹配的字符串处理** | 可能为空 || `signature` | string (optional) | 用户个性签名;空时字段不出现 | 可能不出现 || `chat_recency_hint` | string | 最近联系的提示文案,仅供展示 | 可能为空 |

该 Skill 明确要求:如果搜索有多个匹配项且下一步会发消息或邀请会议,应先让用户选择,不能自动采用第一条结果。

查看原文
SKILL.md:50来自说明文档打开原文件
搜索命中多条且后续操作有副作用(发消息、邀请会议等),把候选列给用户挑;不要擅自选第一条。
references/lark-contact-search-user.md:76来自说明文档打开原文件
搜常见姓名常返回多条同名结果。后续操作若有副作用(发消息、邀请会议等),把候选列给用户挑;**不要擅自选**。筛选信号(可信度从高到低):`chat_recency_hint`(近期联系过) > `enterprise_email` 前缀 > `department` 关键词。`localized_name` 同名时无区分作用。

该 Skill 还能搜索当前用户可见的机器人或智能体,并返回其 open_id、单聊 ID、租户标识和简介;此操作要求 `search:bot` 权限。

查看原文
references/lark-contact-search-bot.md:3来自说明文档打开原文件
按关键词搜索当前用户可见的机器人。仅支持 user 身份,需要 `search:bot` 权限。
references/lark-contact-search-bot.md:31来自说明文档打开原文件
|---|---|---|---|| `open_id` | string | 机器人 ID | 始终非空 || `name` | string | 机器人名称 | 空字符串 || `description` | string | 机器人简介 | 字段省略 || `chat_id` | string | 与机器人的单聊 ID | 空字符串 || `enable_join_group` | bool | 是否允许加入群聊 | — || `is_agent` | bool | 是否是智能体 | — || `tenant_id` | string | 租户标识 | 字段省略 || `match_segments` | string[] | 命中的文本片段 | 无命中时为 `[]` |
从这里开始 · 工作说明SKILL.md
lark-contact
连线表示工作说明包含的模块,不是实际运行顺序。点击模块可查看原文。

文件引用关系图

3 处引用
哪些文件发起引用引用了什么
连线表示真实的文件引用,不是运行顺序。点击节点可高亮相关连线,并查看具体文件和原文位置。虚线表示还有文件需要定位。
文件与检查记录4 个文件

检查范围与遗漏

逐文件查看涉及的内容

下方列出本次涉及的原文范围;纳入检查不代表已查清所有问题。

  • SKILL.md已纳入全文
  • references/lark-contact-get-user.md已纳入全文
  • references/lark-contact-search-bot.md已纳入全文
  • references/lark-contact-search-user.md已纳入全文

这份报告只针对上方版本。我们看了拿到的代码和说明文件,没有实际运行 Skill,也没有检查它另外安装的软件包。因此,这不是“保证安全”的承诺;换了版本或使用环境,结果也可能不同。

  • SKILL.md工作说明
  • references/lark-contact-get-user.md配套文件
  • references/lark-contact-search-bot.md配套文件
  • references/lark-contact-search-user.md配套文件

代码和说明中提到的操作

运行命令
SKILL.md:35来自说明文档打开原文件
```bashlark-cli contact +search-user --query "张三" --has-chatted --as user
SKILL.md:42来自说明文档打开原文件
```bashlark-cli schema contact.user_profiles.batch_query
SKILL.md:56来自说明文档打开原文件
```bashlark-cli contact +search-bot --query '会议助手' --as user
读取了多少行
277
文件校验值(用于核对版本)
c4aa6c9bdd0a77ca91e3721198a8c4faa95aee250f69841765ca50fedfc77e39