Skill Trust Decision

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.

Install decision first Source: Manual upload Scanned: Apr 3, 2026
Files 15
Artifacts 14
Violations 0
Findings 5
Most direct threat evidence
High
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

Why this conclusion was reached

2/4 dimensions flagged
Pass
Declared vs actual capability

Declared resources and inferred behavior are broadly aligned.

Block
Hidden execution and egress

1 high-risk artifacts or egress signals were extracted.

Block
Attack chain and severe findings

The report includes 0 attack-chain steps and 2 severe findings.

Review
Dependencies and supply chain hygiene

3 dependency or supply-chain issues need attention.

What drove the risk score up

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

Most important evidence

High

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
High

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
Medium

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
Medium

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 ~/
Low

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

Declared capability vs actual capability

Filesystem Pass
Declared READ
Inferred WRITE
cookie_manager.py writes cookie.txt; logs/xhs_crawler.log created; all within skill project directory
Network Pass
Declared READ
Inferred READ
requests to xiaohongshu.com (search API + browser), open.feishu.cn (Feishu OpenAPI); all legitimate service calls documented in SKILL.md
Shell Pass
Declared WRITE
Inferred WRITE
index.js uses child_process.exec() to run python script; python itself uses playwright (browser) subprocess
Environment Pass
Declared NONE
Inferred 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)

Suspicious artifacts and egress

High IP Address
143.0.0.0

config.py:50

Medium External URL
https://www.xiaohongshu.com/explore

auto_login_with_qrcode.py:96

Medium External URL
https://edith.xiaohongshu.com/api/sns/web/v1/search/notes

config.py:30

Medium External URL
https://edith.xiaohongshu.com/api/sns/web/v1/feed

config.py:31

Medium External URL
https://www.xiaohongshu.com

config.py:40

Medium External URL
https://www.xiaohongshu.com/

config.py:43

Medium External URL
https://www.xiaohongshu.com/user/profile

cookie_manager.py:82

Medium External URL
https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal

feishu_app_bot.py:67

Medium External URL
https://open.feishu.cn/open-apis/im/v1/messages

feishu_app_bot.py:109

Medium External URL
https://open.feishu.cn/open-apis/im/v1/images

feishu_app_bot.py:222

Medium External URL
https://open.feishu.cn/open-apis/im/v1/chats

feishu_app_bot.py:368

Medium External URL
https://www.xiaohongshu.com/explore/

xhs_crawler.py:181

Dependencies and supply chain

PackageVersionSourceKnown vulnNotes
playwright * pip No No version pinned — SKILL.md says 'pip install playwright' without version
requests * pip No No version pinned — SKILL.md says 'pip install requests' without version
node * system No No Node.js package.json dependencies declared

File composition

15 files · 3138 lines
Python 10 files · 2525 linesMarkdown 2 files · 420 linesJavaScript 1 files · 175 linesJSON 1 files · 17 linesText 1 files · 1 lines
Files of concern · 8
feishu_app_bot.py Python · 444 lines
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 lines
https://www.xiaohongshu.com/explore/
auto_login_with_qrcode.py Python · 319 lines
https://www.xiaohongshu.com/explore
cookie_manager.py Python · 327 lines
https://www.xiaohongshu.com/user/profile
xhs_search_with_browser.py Python · 255 lines
https://www.xiaohongshu.com/search_result?keyword=
使用文档.md Markdown · 241 lines
https://open.feishu.cn/
index.js JavaScript · 175 lines
Node.js exec() with arbitrary command injection surface
config.py Python · 98 lines
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/
Other files · feishu_bot.py · example_openclaw_skill.py · SKILL.md · login.py

Security positives

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