T08 · Insecure Dependencies
- Location
SKILL.md:41- Finding
Unpinned and Unreviewable Runtime Dependency Installation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a clear reposting purpose, but it asks the agent to extract browser login cookies and store them locally using missing unaudited code.
Review before installing. Only run this skill if you are comfortable letting it use your Bilibili browser session to upload under your account. Prefer an isolated browser profile and dedicated Bilibili account, audit or obtain the missing scripts first, avoid sharing logs that contain cookies, protect or delete credentials.json after use, and rotate the session if exposed.
SKILL.md:41Unpinned and Unreviewable Runtime Dependency Installation
SKILL.md:44Broad Browser Cookie Access Delegated to Missing and Unauditable Code
SKILL.md:154Instruction Encourages Access to Other Agents and Session Records
The skill requires extracting Bilibili cookies from local browsers using browser_cookie3 and writing them into credentials.json. Accessing browser session cookies is highly sensitive because those tokens can authenticate as the user and be reused for account actions if exposed, logged, or mishandled.
| `yt-dlp` | 公开下载 IG Reel(无需 IG 账号) | `brew install yt-dlp` 或 `pip install yt-dlp` |
| `ffmpeg` | 截视频第 1 秒做封面 | `brew install ffmpeg` |
| `browser_cookie3` | 从浏览器拉 B 站 cookie(首次必跑) | `pip install browser_cookie3` |
| B 站 cookie | **分发包里 credentials.json 是占位模板**,首次使用前必须自己刷 | `python3 scripts/setup_cookies.py`(自动探测浏览器;支持 chrome/edge/brave/arc/vivaldi/firefox/safari 等,不限 Chrome) |
**无 WebBridge 也能跑**——caption 通过 `yt-dlp --write-info-json` 拿(fallback)。
The YARA match is justified here because the skill contains information-stealer-like behavior: it instructs automatic detection of installed browsers and extraction of cookies from them. Although the apparent goal is account setup for Bilibili uploads rather than overt malware, the technique is the same high-risk credential-harvesting pattern and is dangerous in an agent skill context.
yt-dlp | 公开下载 IG Reel(无需 IG 账号) | brew install yt-dlp 或 pip install yt-dlp |
| ffmpeg | 截视频第 1 秒做封面 | brew install ffmpeg |
| browser_cookie3 | 从浏览器拉 B 站 cookie(首次必跑) | pip install browser_cookie3 |
| B 站 cookie | 分发包里 credentials.json 是占位模板,首次使用前必须自己刷 | python3 scripts/setup_cookies.py(自动探测浏览器;支持 chrome/edge/brave/arc/vivaldi/firefox/safari 等,不限 Chrome) |
无 WebBridge 也能跑——caption 通过 yt-dlp --write-info-json 拿(fallback)。
对每个 IG 链接串行执行:
reel/DYyvKNpEdoo/ 的 DYyvKNpEdoo./scripts/prepare_media.sh <shortcode> [/tmp/ig_link_bili]
<shortcode>.mp4 + <shortcode>.info.json(含 uploader/like_count/description)+ <shortcode>thumb.jpgThe file structure explicitly includes a setup script that pulls cookies from the local browser and writes them to credentials.json. Even though this supports the upload workflow, it normalizes automated access to local credentials and increases the chance of unauthorized account use or secret leakage through files and logs.
├── SKILL.md ← 你正在看的
├── config.example.json ← 可选配置模板(复制为 config.json 设固定的分区/标签/标题前缀)
├── scripts/
│ ├── setup_cookies.py ← 首次必跑:从本机浏览器抓 B 站 cookie 写入 credentials.json(支持多浏览器,自动验真)
│ ├── prepare_media.sh ← 一步:下载 mp4 + 截封面 + 拉元数据 JSON
│ ├── upload_one.py ← 单条上传 wrapper(分区/标签走参数或 config.json,不写死)
│ └── verify_upload.py ← B 站 API 验真(带重试)
Referencing credentials.json.template is less severe than active harvesting, but the overall pattern centers local credential material in filesystem artifacts. If operators convert templates into real credential files in the working tree, those secrets may be accidentally exposed, copied, or mishandled.
├── bilibili_uploader/ ← 自包含 B 站上传库(拷自 wscats/bilibili-all-in-one)
│ ├── main.py
│ ├── src/
│ ├── credentials.json.template ← cookie 模板(真 credentials.json 由 setup_cookies.py 生成,已 .gitignore)
│ └── requirements.txt
├── examples/ ← 几个测试链接
└── references/ ← 已知坑、失败案例
This section explicitly tells the operator to generate a real credentials.json from a logged-in browser session. That is credential acquisition from local browser state, which is dangerous because it grants the skill access to authenticated account sessions outside a least-privilege model.
记忆锚点:任何"上游抽风 / 风控 / 服务器挂"的判断,必须有本机近 30 分钟的诊断证据支撑,且没被别的 agent 反例证伪。否则就是脑补。
分发包里的 bilibili_uploader/credentials.json 是占位模板(YOUR_SESSDATA_HERE),直接用必然 403。
首次使用前在某个浏览器登录 bilibili.com,然后跑:
The instructions pair browser_cookie3 installation with immediate use to pull browser cookies. This is a classic credential-access pattern: the tool reads sensitive browser-stored authentication state that can be abused for account takeover or unauthorized posting if leaked.
记忆锚点:任何"上游抽风 / 风控 / 服务器挂"的判断,必须有本机近 30 分钟的诊断证据支撑,且没被别的 agent 反例证伪。否则就是脑补。
分发包里的 bilibili_uploader/credentials.json 是占位模板(YOUR_SESSDATA_HERE),直接用必然 403。
首次使用前在某个浏览器登录 bilibili.com,然后跑:
pip install browser_cookie3
The skill directs extraction of a full cookie 'triple' from the same browser session and writes it to credentials.json, then uses it for login verification. This is dangerous because it automates collection and persistence of reusable session secrets that can authenticate as the user to Bilibili APIs.
pip install browser_cookie3 python3 scripts/setup_cookies.py # 自动探测;或 --browser firefox 指定
脚本从**同一浏览器同一会话**取三件套(`sessdata`+`bili_jct`+`buvid3`,缺一或混源必 -101,见 `references/pitfalls.md` §8)、写入 credentials.json、并验真。过期了重跑同一条命令。
**撞墙症状(必认)**:`upload_one.py` 抛 `Expecting value: line 1 column 1` + `curl api.bilibili.com/x/web-interface/nav`
返 `isLogin: false` —— **几乎一定是本机 cookie 失效**(不是 B 站上游),先 `python3 scripts/setup_cookies.py` 重刷再说。
The shell snippet reads sessdata directly from credentials.json and sends it in a curl Cookie header. This creates a concrete path for sensitive session material to be exposed in shell history, process listings, logs, or copied troubleshooting output, making account compromise more likely.
返 isLogin: false —— 几乎一定是本机 cookie 失效(不是 B 站上游),先 python3 scripts/setup_cookies.py 重刷再说。
30 秒判定:
SESSDATA=$(python3 -c "import json,pathlib; print(json.loads(pathlib.Path('bilibili_uploader/credentials.json').read_text())['sessdata'])")
curl -sS -m 10 "https://api.bilibili.com/x/web-interface/nav" -b "SESSDATA=$SESSDATA" | python3 -c "import json,sys; print('isLogin:', json.load(sys.stdin)['data']['isLogin'])"
# false → 重刷 cookie;true → 才考虑按 §7 决策树查上游
The troubleshooting table instructs refreshing credentials.json by extracting browser cookies after logging into Bilibili. This reinforces unsafe secret-handling practices and encourages repeated access to local browser authentication state, expanding exposure and operational risk.
| `yt-dlp` 报 HTTP 4xx/5xx | VPN/网络问题,确认能访问 instagram.com |
| `yt-dlp` 报 "Sign in to view" | 该 Reel 是非公开的,换链接 |
| `upload_one.py` 返 "video not found" | 没跑 `prepare_media.sh`,或 shortcode 拼错 |
| `upload_one.py` 返 "cookie expired" | `bilibili_uploader/credentials.json` 需要更新——在 Chrome 登录 B 站后用 `browser_cookie3` **三件套一起**提取。详见 `references/pitfalls.md` §6 §8 |
| `verify_upload.py` 返 PENDING | 正常,等 1-2 分钟再 retry |
| `verify_upload.py` 返 FAIL 多次 | B 站可能真把这条拒收了(站内外重复 / 版权)——别再传,告知用户 |
| `upload_one.py` 抛 `Expecting value: line 1 column 1` JSON 解析失败 | preupload 返了 HTML 不是 JSON。**先不要判定"CDN 抽风"**——按 `references/pitfalls.md` §7 决策树跑 Step 1-3 诊断:curl preupload 看状态码 + curl `api.bilibili.com/x/web-interface/nav` 验 `isLogin` 字段。**可能是 SESSDATA 空 / 三件套不配套(§8)/ skill 自带 cookie 是空(§9)/ ig-link-bili 池与主池不同步(见上方"credentials.json 与主池独立"pitfall)**,不一定都是 B 站上游问题。**必须先验登录态再归因**。 |
This diagnostic path explicitly tells the operator to inspect login state using SESSDATA and discusses empty or mismatched cookie sets. Because it operationalizes direct handling of live session tokens during debugging, it materially increases the risk of disclosure or misuse of reusable credentials.
| `upload_one.py` 返 "cookie expired" | `bilibili_uploader/credentials.json` 需要更新——在 Chrome 登录 B 站后用 `browser_cookie3` **三件套一起**提取。详见 `references/pitfalls.md` §6 §8 |
| `verify_upload.py` 返 PENDING | 正常,等 1-2 分钟再 retry |
| `verify_upload.py` 返 FAIL 多次 | B 站可能真把这条拒收了(站内外重复 / 版权)——别再传,告知用户 |
| `upload_one.py` 抛 `Expecting value: line 1 column 1` JSON 解析失败 | preupload 返了 HTML 不是 JSON。**先不要判定"CDN 抽风"**——按 `references/pitfalls.md` §7 决策树跑 Step 1-3 诊断:curl preupload 看状态码 + curl `api.bilibili.com/x/web-interface/nav` 验 `isLogin` 字段。**可能是 SESSDATA 空 / 三件套不配套(§8)/ skill 自带 cookie 是空(§9)/ ig-link-bili 池与主池不同步(见上方"credentials.json 与主池独立"pitfall)**,不一定都是 B 站上游问题。**必须先验登录态再归因**。 |
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
from main import BilibiliAllInOne
async def main():
bilibili = BilibiliAllInOne(credential_file="/path/credentials.json")
pub = bilibili.publisher
# 1) 看预上传(这是上传库真实请求形态)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
from main import BilibiliAllInOne
async def main():
bilibili = BilibiliAllInOne(credential_file="/path/credentials.json")
pub = bilibili.publisher
# 1) 看预上传(这是上传库真实请求形态)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
from main import BilibiliAllInOne
async def main():
bilibili = BilibiliAllInOne(credential_file="/path/credentials.json")
pub = bilibili.publisher
# 1) 看预上传(这是上传库真实请求形态)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
from main import BilibiliAllInOne
async def main():
bilibili = BilibiliAllInOne(credential_file="/path/credentials.json")
pub = bilibili.publisher
# 1) 看预上传(这是上传库真实请求形态)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
from main import BilibiliAllInOne
async def main():
bilibili = BilibiliAllInOne(credential_file="/path/credentials.json")
pub = bilibili.publisher
# 1) 看预上传(这是上传库真实请求形态)
The documentation instructs operators to add rejected authors to a runtime blacklist, directly contradicting the skill manifest's claim that it does not do author blacklisting. This kind of hidden policy divergence is dangerous because it changes operational behavior in ways users are explicitly told will not happen, enabling undisclosed content suppression and making the skill's real behavior less auditable.
The documentation centers on maintaining a local credentials.json containing active Bilibili session material. Storing reusable session credentials in a file is sensitive and increases the risk of account compromise if the file is copied, logged, bundled with the skill, or read by other processes.
- 第一次超时直接重试(`prepare_media.sh` 暂未加 retry,可手动重跑)
- VPN 不稳时常见
## 6. credentials.json 过期(症状表 + 怎么修)
**症状**:`upload_one.py` 返 `cookie expired` 或 `csrf 校验失败`。
The setup flow explicitly uses browser_cookie3 to extract browser cookies for bilibili.com, which is behavior strongly associated with credential harvesting. In this skill context it appears intended for legitimate account automation rather than malware, but it still crosses a sensitive boundary by pulling reusable auth material from the browser into a script-managed file.
��次超时直接重试(prepare_media.sh 暂未加 retry,可手动重跑)
症状:upload_one.py 返 cookie expired 或 csrf 校验失败。
修法(一条命令,三件套自动从同一会话拉 + 自动验真):
pip install browser_cookie3 # 首次
python3 scripts/setup_cookies.py # 自动探测浏览器;或 --browser firefox 指定
返回 ✓ 成功!...isLogin=True, @你的用户名 即成功。脚本内部保证 SESSDATA / bili_jct / buvid3
来自同一浏览器同一会话(见 #8 为何必须同源),并写入 bilibili_uploader/credentials.json。
症状:
upload_one.py → {"success": false, "error": "Expecting value: line 1 column 1 (char 0)"}
脚本 traceback 指向 publisher._preupload 里 resp.json() 解析失败——B 站返回的不是 JSON,
This text explicitly states that browser-derived session secrets are written into bilibili_uploader/credentials.json. Persisting live session cookies to disk creates a durable credential target that can be stolen and reused to impersonate the account.
python3 scripts/setup_cookies.py # 自动探测浏览器;或 --browser firefox 指定
返回 `✓ 成功!...isLogin=True, @你的用户名` 即成功。脚本内部保证 SESSDATA / bili_jct / buvid3
来自**同一浏览器同一会话**(见 #8 为何必须同源),并写入 `bilibili_uploader/credentials.json`。
## 7. preupload 403 诊断决策树(**2026-06-07 修订**)
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
# Step 1: 看 preupload 真实状态码
curl -sS -m 10 -o /dev/null -w "preupload=%{http_code}\n" \
"https://member.bilibili.com/preupload?name=test.mp4&size=1024&r=upos&profile=ugcupos%2Fbup&ssl=0&version=2.14.0&build=2140000&upcdn=bda2&probe_version=20221109"
# Step 2: 验主站 + 通用 API(区分"全站挂"还是"只有 member 域挂")
The diagnostic command reads and prints portions of credentials.json, including lengths and prefixes of sensitive values. Even partial credential disclosure can leak enough metadata for attackers or appear in logs, transcripts, or terminal history where secrets should not be exposed.
诊断:
python3 -c "import json; c=json.load(open('/path/credentials.json')); [print(f'{k}: {v[:30]}... (len={len(v)})') for k,v in c.items()]"
# 看 SESSDATA 是不是空字符串(len=0)
The documentation instructs extraction of SESSDATA, bili_jct, and buvid3 from the browser and writing them to credentials.json. This is credential harvesting from browser storage for reuse outside the browser session boundary, which materially increases the blast radius of any local compromise or misuse.
**修法**(**三个字段必须从同一浏览器同一次会话拉**——`setup_cookies.py` 已替你保证这点):
1. 在某个浏览器登录 `bilibili.com`(**不要**隐身模式)
2. 跑 `python3 scripts/setup_cookies.py`(自动探测;或 `--browser <name>` 指定)
3. 脚本会从该浏览器的同一会话取三件套、写入 `credentials.json`(小写 key)、并调 nav API 验 `isLogin`
4. 看到 `✓ 成功!...isLogin=True` 即可
> 想手抄底层逻辑(脚本干的事):`browser_cookie3.<browser>(domain_name="bilibili.com")` 遍历
The documented check reads the sessdata field from credentials.json and prints it, which normalizes direct inspection of secret values. Even if the expected value is empty in the template, using the same pattern against a populated file would expose active credentials in terminals, logs, or chat transcripts.
- ❌ 单字段替换("只刷 SESSDATA"没用)
- ❌ 拿空 SESSDATA 的 credentials.json 凑合
## 9. `ig-link-bili` skill 自带 credentials.json 的 SESSDATA 是空字符串
**症状**:
- `python3 -c "import json; c=json.load(open('credentials.json')); print(c.get('sessdata', 'MISSING'))"` 返空字符串
The remediation directs users to run a setup script that populates credentials.json with real browser-derived cookies and validates them. This operationalizes credential extraction and local persistence of reusable session secrets, which is risky even if intended for legitimate automation.
- `python3 -c "import json; c=json.load(open('credentials.json')); print(c.get('sessdata', 'MISSING'))"` 返空字符串
- 直接用 skill 自带的 cookie 跑 upload → 必然 403
**真因**:skill 安装时自带的 `credentials.json` 是个**占位模板**(作者为安全故意不放真 cookie),SESSDATA 字段是 `""`。**`bili_jct` 和 `buvid3` 倒是有,但单凭这两个不算登录**(见 #8)。
**修法**:**首次使用前跑一次** `python3 scripts/setup_cookies.py`(见 #6/#8)——它把真 cookie 写进
占位的 `credentials.json` 并验真。过期了重跑同一条命令即可。
This note confirms that setup_cookies.py writes real cookies into the placeholder credentials.json and reuses them for operation. The danger is the same: durable session theft risk if the file is mishandled, copied, or accessible to other software.
**真因**:skill 安装时自带的 `credentials.json` 是个**占位模板**(作者为安全故意不放真 cookie),SESSDATA 字段是 `""`。**`bili_jct` 和 `buvid3` 倒是有,但单凭这两个不算登录**(见 #8)。
**修法**:**首次使用前跑一次** `python3 scripts/setup_cookies.py`(见 #6/#8)——它把真 cookie 写进
占位的 `credentials.json` 并验真。过期了重跑同一条命令即可。
**预防**(未来 PR):`upload_one.py` 启动时可自检——读到 SESSDATA 为占位/空,直接提示
"请先跑 `scripts/setup_cookies.py`"再退出。**当前 wrapper 没这层保护**。