安全决策报告

xhs-crawler

Hardcoded Feishu App Secret exposed in both source code and SKILL.md documentation, plus unpinned Python dependencies with no network isolation, constitute undeclared sensitive credential exposure and dependency supply chain risk.

安装决策优先 来源: 手动上传 扫描时间: 2026/4/3
文件 15
IOC 14
越权项 0
发现 5
最直接的威胁证据
高危
Feishu App Secret hardcoded and documented

FEISHU_APP_ID='cli_a924d921ce7a9cbd' and FEISHU_APP_SECRET='5QG92Lp8kvhAkgpPJTd57fIxshnCebEt' are hardcoded in config.py lines 89-90. SKILL.md lines 64-67 reproduce the exact same credentials in a documentation example block, meaning anyone with repo access or who receives this skill sees the live credentials. This creates a credential-leak blast radius: the Feishu bot can send messages to any group the bot has been added to.

config.py:89

为什么得出这个结论

2/4 个维度触发
通过
声明与实际能力

声明资源与推断能力基本一致。

阻止
隐藏执行与外联

提取到 1 个高危 IOC 或外联信号。

阻止
攻击链与高危发现

报告包含 0 步攻击链,另有 2 项高危或严重发现。

复核
依赖与供应链卫生

发现 3 项需要关注的依赖或供应链线索。

风险分是怎么被拉高的

Hardcoded Feishu credentials in source +15

FEISHU_APP_ID and FEISHU_APP_SECRET hardcoded in config.py (lines 89-90); SKILL.md (lines 64-67) reproduces them verbatim in documentation

Credentials published in documentation +15

SKILL.md exposes real Feishu App Secret in example config block, which constitutes a credential leak to anyone with read access to the repo/skill

Unpinned dependencies with no lock file +8

package.json has no dependencies at all; Python has no requirements.txt — pip install without version pinning allows dependency confusion and supply-chain substitution attacks

Shell execution via Node.js exec() +2

index.js:runPythonScript uses child_process.exec() to invoke python with arbitrary command arguments, declared purpose but broad surface

最关键的证据

高危

Feishu App Secret hardcoded and documented

FEISHU_APP_ID='cli_a924d921ce7a9cbd' and FEISHU_APP_SECRET='5QG92Lp8kvhAkgpPJTd57fIxshnCebEt' are hardcoded in config.py lines 89-90. SKILL.md lines 64-67 reproduce the exact same credentials in a documentation example block, meaning anyone with repo access or who receives this skill sees the live credentials. This creates a credential-leak blast radius: the Feishu bot can send messages to any group the bot has been added to.

config.py:89
Move credentials to environment variables (os.environ.get('FEISHU_APP_ID')) or a .env file added to .gitignore, and remove the credential block from SKILL.md example
高危

No dependency pinning — supply chain risk

package.json has empty dependencies {}; no requirements.txt exists. SKILL.md instructs 'pip install playwright requests' without version pins. This allows dependency confusion attacks or a malicious future release of a transitive dependency to be silently installed.

package.json:9
Add requirements.txt with pinned versions (e.g., playwright==1.40.0 requests==2.31.0) and update package.json dependencies
中危

Node.js exec() with arbitrary command injection surface

index.js:runPythonScript builds a shell command string with user-supplied keyword passed directly into exec(). While the keyword is URI-component free in the current code flow, a future change could introduce injection. The command also uses a 2-minute timeout and 10MB buffer which are appropriate.

index.js:122
Use spawn() with explicit argument array instead of shell string interpolation, or validate the keyword as alphanumeric-only Chinese string
中危

Chrome profile directory stored in user home

XHS_USER_DATA_DIR defaults to Path.home() / 'xhs_chrome_profile', meaning the skill stores browser session data under the user's home directory. This is necessary for cookie persistence but expands the blast radius if the profile is compromised.

config.py:18
Document this clearly and consider using a scoped subdirectory within the skill folder instead of ~/
低危

Pre-scan false positive: IP address misidentified

The pre-scan flagged '143.0.0.0' at config.py:50 as a hardcoded IP. This is actually the Chromium browser version number (143.0.0.0) embedded in the User-Agent string, not a network IP address. No malicious IP C2 indicator.

config.py:46
No action needed; this is a version number, not an IP

声明能力 vs 实际能力

文件系统 通过
声明 READ
推断 WRITE
cookie_manager.py writes cookie.txt; logs/xhs_crawler.log created; all within skill project directory
网络访问 通过
声明 READ
推断 READ
requests to xiaohongshu.com (search API + browser), open.feishu.cn (Feishu OpenAPI); all legitimate service calls documented in SKILL.md
命令执行 通过
声明 WRITE
推断 WRITE
index.js uses child_process.exec() to run python script; python itself uses playwright (browser) subprocess
环境变量 通过
声明 NONE
推断 READ
config.py reads no env vars; but feishu_app_bot.py sends App ID/Secret in POST body to feishu API (acceptable OAuth flow)

可疑产物与外联

高危 IP 地址
143.0.0.0

config.py:50

中危 外部 URL
https://www.xiaohongshu.com/explore

auto_login_with_qrcode.py:96

中危 外部 URL
https://edith.xiaohongshu.com/api/sns/web/v1/search/notes

config.py:30

中危 外部 URL
https://edith.xiaohongshu.com/api/sns/web/v1/feed

config.py:31

中危 外部 URL
https://www.xiaohongshu.com

config.py:40

中危 外部 URL
https://www.xiaohongshu.com/

config.py:43

中危 外部 URL
https://www.xiaohongshu.com/user/profile

cookie_manager.py:82

中危 外部 URL
https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal

feishu_app_bot.py:67

中危 外部 URL
https://open.feishu.cn/open-apis/im/v1/messages

feishu_app_bot.py:109

中危 外部 URL
https://open.feishu.cn/open-apis/im/v1/images

feishu_app_bot.py:222

中危 外部 URL
https://open.feishu.cn/open-apis/im/v1/chats

feishu_app_bot.py:368

中危 外部 URL
https://www.xiaohongshu.com/explore/

xhs_crawler.py:181

依赖与供应链

包名版本来源漏洞备注
playwright * pip No version pinned — SKILL.md says 'pip install playwright' without version
requests * pip No version pinned — SKILL.md says 'pip install requests' without version
node * system No Node.js package.json dependencies declared

文件构成

15 个文件 · 3138 行
Python 10 个文件 · 2525 行Markdown 2 个文件 · 420 行JavaScript 1 个文件 · 175 行JSON 1 个文件 · 17 行Text 1 个文件 · 1 行
需关注文件 · 8
feishu_app_bot.py Python · 444 行
https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal · https://open.feishu.cn/open-apis/im/v1/messages · https://open.feishu.cn/open-apis/im/v1/images · https://open.feishu.cn/open-apis/im/v1/chats
xhs_crawler.py Python · 413 行
https://www.xiaohongshu.com/explore/
auto_login_with_qrcode.py Python · 319 行
https://www.xiaohongshu.com/explore
cookie_manager.py Python · 327 行
https://www.xiaohongshu.com/user/profile
xhs_search_with_browser.py Python · 255 行
https://www.xiaohongshu.com/search_result?keyword=
使用文档.md Markdown · 241 行
https://open.feishu.cn/
index.js JavaScript · 175 行
Node.js exec() with arbitrary command injection surface
config.py Python · 98 行
Feishu App Secret hardcoded and documented · Chrome profile directory stored in user home · Pre-scan false positive: IP address misidentified · 143.0.0.0 · https://edith.xiaohongshu.com/api/sns/web/v1/search/notes · https://edith.xiaohongshu.com/api/sns/web/v1/feed · https://www.xiaohongshu.com · https://www.xiaohongshu.com/
其他文件 · feishu_bot.py · example_openclaw_skill.py · SKILL.md · login.py

安全亮点

All capabilities declared in SKILL.md align with actual implementation — no hidden functionality detected
No base64-encoded payloads, no eval(), no obfuscated JavaScript
No credential harvesting beyond the Feishu app credentials (which are for the bot's own API, not user data theft)
No curl|bash or wget|sh remote script downloads
No access to ~/.ssh, ~/.aws, or other sensitive host credential paths
No reverse shell, no C2 callbacks, no data exfiltration to unknown third-party servers
Playwright import is safely guarded with try/except and PLAYWRIGHT_AVAILABLE flag
Browser automation uses isolated user_data_dir per session for login flow