{"data":{"skill":{"slug":"chengyi-ai-native-subtitle-quote-image","name":"native-subtitle-quote-image","icon":"📦","repo":"https://github.com/chengyi-ai/native-subtitle-quote-image/tree/f9485e20f03fc0b9e5dfd77d03d5be24f7cebdcd/skills/native-subtitle-quote-image","status":"approved","author":"chengyi-ai","authorVersion":null,"skillstoreRevision":1},"audit":{"id":"2c95d8ff-2040-4669-b700-2c9813e70179","skill_id":"38a27f0a-2639-404c-b296-728d5f9e06b4","version":1,"content_hash":"v3:dd2fcaef932574591f2502a46fb2362cde6fa9a1:aaeafa98bd74bdc8347030e33b5fda699e4c8ac49a83167eee524fb225171c29:091e7b32ba6733ac81d6366bdb426a05e1bd91d5e81726fbf0510f104bc4cdcb:736b696c6c732f6368656e6779692d61692f6e61746976652d7375627469746c652d71756f74652d696d616765:437e5edeac1cab9b2e74910a2f279dec","risk_level":"medium","is_blocked":false,"safe_to_publish":true,"analysis_status":"ok","agent_auto_install_policy":"allowed","manual_install_policy":"allowed","summary":"The static findings are false positives for documented, bounded media processing, fixed update checks, normal file handling, and standard Unicode ranges. A medium residual risk remains because the YouTube recovery workflow can read browser session cookies after user authorization.","remediation":[{"issue":"The URL recovery path reads Chrome session cookies with yt-dlp.","severity":"medium","suggestion":"Keep explicit consent, use only the selected browser profile, never log cookie data, and stop when consent is absent."},{"issue":"External FFmpeg and curl processes run with local or network inputs.","severity":"low","suggestion":"Keep argv-based invocation, validate executable paths, enforce timeouts, and restrict inputs and outputs to user-approved locations."},{"issue":"Downloaded media and temporary frames can contain sensitive user content.","severity":"low","suggestion":"Use private temporary directories, clean up temporary files on failure, and clearly document output retention."}],"risk_factor_evidence":[{"factor":"scripts","evidence":[{"file":"scripts/check_environment.py","line_end":47,"line_start":47},{"file":"scripts/check_environment.py","line_end":87,"line_start":87}]},{"factor":"external_commands","evidence":[{"file":"scripts/check_environment.py","line_end":31,"line_start":31},{"file":"scripts/check_update.py","line_end":120,"line_start":120},{"file":"scripts/native_subtitle_stitch.py","line_end":29,"line_start":29},{"file":"scripts/native_subtitle_stitch.py","line_end":50,"line_start":50},{"file":"SKILL.md","line_end":16,"line_start":14},{"file":"SKILL.md","line_end":18,"line_start":16},{"file":"SKILL.md","line_end":19,"line_start":18},{"file":"SKILL.md","line_end":20,"line_start":19},{"file":"SKILL.md","line_end":20,"line_start":20},{"file":"SKILL.md","line_end":28,"line_start":27},{"file":"SKILL.md","line_end":28,"line_start":28},{"file":"SKILL.md","line_end":44,"line_start":37},{"file":"SKILL.md","line_end":44,"line_start":44},{"file":"SKILL.md","line_end":55,"line_start":46},{"file":"SKILL.md","line_end":57,"line_start":55},{"file":"SKILL.md","line_end":57,"line_start":57},{"file":"SKILL.md","line_end":61,"line_start":59},{"file":"SKILL.md","line_end":70,"line_start":61},{"file":"SKILL.md","line_end":71,"line_start":70},{"file":"SKILL.md","line_end":82,"line_start":71},{"file":"SKILL.md","line_end":85,"line_start":82},{"file":"SKILL.md","line_end":89,"line_start":85},{"file":"SKILL.md","line_end":93,"line_start":89},{"file":"SKILL.md","line_end":103,"line_start":93},{"file":"SKILL.md","line_end":103,"line_start":103},{"file":"SKILL.md","line_end":108,"line_start":105},{"file":"SKILL.md","line_end":112,"line_start":108},{"file":"SKILL.md","line_end":121,"line_start":112},{"file":"SKILL.md","line_end":123,"line_start":121},{"file":"SKILL.md","line_end":128,"line_start":123},{"file":"SKILL.md","line_end":130,"line_start":128},{"file":"SKILL.md","line_end":130,"line_start":130},{"file":"SKILL.md","line_end":146,"line_start":136},{"file":"SKILL.md","line_end":148,"line_start":146},{"file":"SKILL.md","line_end":149,"line_start":148},{"file":"SKILL.md","line_end":155,"line_start":149},{"file":"SKILL.md","line_end":159,"line_start":155},{"file":"SKILL.md","line_end":161,"line_start":159},{"file":"SKILL.md","line_end":161,"line_start":161},{"file":"SKILL.md","line_end":174,"line_start":174},{"file":"SKILL.md","line_end":195,"line_start":178},{"file":"SKILL.md","line_end":195,"line_start":195}]},{"factor":"network","evidence":[{"file":"scripts/check_update.py","line_end":11,"line_start":11},{"file":"scripts/check_update.py","line_end":106,"line_start":106},{"file":"scripts/check_update.py","line_end":114,"line_start":114},{"file":"scripts/check_update.py","line_end":17,"line_start":17},{"file":"scripts/check_update.py","line_end":18,"line_start":18}]},{"factor":"env_access","evidence":[{"file":"scripts/check_update.py","line_end":39,"line_start":39},{"file":"scripts/check_update.py","line_end":47,"line_start":47},{"file":"scripts/check_update.py","line_end":49,"line_start":49}]},{"factor":"filesystem","evidence":[{"file":"scripts/native_subtitle_stitch.py","line_end":12,"line_start":12},{"file":"scripts/native_subtitle_stitch.py","line_end":82,"line_start":82},{"file":"scripts/native_subtitle_stitch.py","line_end":617,"line_start":617},{"file":"scripts/native_subtitle_stitch.py","line_end":107,"line_start":107}]}],"critical_findings":[],"high_findings":[],"medium_findings":[{"title":"Sensitive Browser Session Access","locations":[{"file":"references/yt-dlp-and-transcripts.md","line_end":158,"line_start":152},{"file":"SKILL.md","line_end":195,"line_start":195}],"confidence":0.88,"description":"The YouTube recovery workflow can ask yt-dlp to read Chrome session cookies for a private or verification-gated video. Authorization and no-export rules reduce risk, but a browser session remains sensitive account material.","review_kind":"security","source_category":"semantic","source_severity":"medium","confidence_reasoning":"The cited workflow explicitly requests permission to read Chrome cookies and then passes them to yt-dlp. The same text prohibits exporting them, so the risk is residual sensitive access rather than demonstrated exfiltration."}],"low_findings":[],"dangerous_patterns":[],"files_scanned":10,"total_lines":2140,"audit_model":"codex","audited_at":"2026-09-09T14:05:26.329+00:00","created_at":"2026-09-09T16:05:25.472657+00:00","static_findings":[{"id":"scripts:scripts/check_environment.py:47:python-dynamic-import","file":"scripts/check_environment.py","pattern":"Python dynamic import","snippet":"module = importlib.import_module(name)","category":"scripts","line_end":47,"severity":"medium","line_start":47},{"id":"scripts:scripts/check_environment.py:87:python-dynamic-import","file":"scripts/check_environment.py","pattern":"Python dynamic import","snippet":"imageio_module = importlib.import_module(\"imageio_ffmpeg\")","category":"scripts","line_end":87,"severity":"medium","line_start":87},{"id":"external_commands:scripts/check_environment.py:31:python-subprocess-run","file":"scripts/check_environment.py","pattern":"Python subprocess.run","snippet":"proc = subprocess.run(","category":"external_commands","line_end":31,"severity":"high","line_start":31},{"id":"external_commands:scripts/check_update.py:120:python-subprocess-run","file":"scripts/check_update.py","pattern":"Python subprocess.run","snippet":"proc = subprocess.run(","category":"external_commands","line_end":120,"severity":"high","line_start":120},{"id":"network:scripts/check_update.py:11:python-http-libraries","file":"scripts/check_update.py","pattern":"Python HTTP libraries","snippet":"import urllib.request","category":"network","line_end":11,"severity":"low","line_start":11},{"id":"network:scripts/check_update.py:106:python-http-libraries","file":"scripts/check_update.py","pattern":"Python HTTP libraries","snippet":"request = urllib.request.Request(","category":"network","line_end":106,"severity":"low","line_start":106},{"id":"network:scripts/check_update.py:114:python-http-libraries","file":"scripts/check_update.py","pattern":"Python HTTP libraries","snippet":"with urllib.request.urlopen(request, timeout=timeout) as response:","category":"network","line_end":114,"severity":"low","line_start":114},{"id":"network:scripts/check_update.py:17:hardcoded-url","file":"scripts/check_update.py","pattern":"Hardcoded URL","snippet":"LATEST_API = f\"https://api.github.com/repos/{REPOSITORY}/releases/latest\"","category":"network","line_end":17,"severity":"low","line_start":17},{"id":"network:scripts/check_update.py:18:hardcoded-url","file":"scripts/check_update.py","pattern":"Hardcoded URL","snippet":"RELEASES_URL = f\"https://github.com/{REPOSITORY}/releases\"","category":"network","line_end":18,"severity":"low","line_start":18},{"id":"env_access:scripts/check_update.py:39:python-environment-access","file":"scripts/check_update.py","pattern":"Python environment access","snippet":"override = os.environ.get(\"NATIVE_SUBTITLE_UPDATE_CACHE\")","category":"env_access","line_end":39,"severity":"low","line_start":39},{"id":"env_access:scripts/check_update.py:47:python-environment-access","file":"scripts/check_update.py","pattern":"Python environment access","snippet":"root = Path(os.environ.get(\"LOCALAPPDATA\", Path.home() / \"AppData\" / \"Local\"))","category":"env_access","line_end":47,"severity":"low","line_start":47},{"id":"env_access:scripts/check_update.py:49:python-environment-access","file":"scripts/check_update.py","pattern":"Python environment access","snippet":"root = Path(os.environ.get(\"XDG_CACHE_HOME\", Path.home() / \".cache\"))","category":"env_access","line_end":49,"severity":"low","line_start":49},{"id":"external_commands:scripts/native_subtitle_stitch.py:29:python-subprocess-run","file":"scripts/native_subtitle_stitch.py","pattern":"Python subprocess.run","snippet":"return subprocess.run(","category":"external_commands","line_end":29,"severity":"high","line_start":29},{"id":"external_commands:scripts/native_subtitle_stitch.py:50:python-subprocess-run","file":"scripts/native_subtitle_stitch.py","pattern":"Python subprocess.run","snippet":"proc = subprocess.run(","category":"external_commands","line_end":50,"severity":"high","line_start":50},{"id":"filesystem:scripts/native_subtitle_stitch.py:12:temp-file-creation","file":"scripts/native_subtitle_stitch.py","pattern":"Temp file creation","snippet":"import tempfile","category":"filesystem","line_end":12,"severity":"low","line_start":12},{"id":"filesystem:scripts/native_subtitle_stitch.py:82:temp-file-creation","file":"scripts/native_subtitle_stitch.py","pattern":"Temp file creation","snippet":"fd, tmp = tempfile.mkstemp(suffix=\".png\")","category":"filesystem","line_end":82,"severity":"low","line_start":82},{"id":"filesystem:scripts/native_subtitle_stitch.py:617:python-shutil-operations","file":"scripts/native_subtitle_stitch.py","pattern":"Python shutil operations","snippet":"shutil.copyfile(manifest_path, manifest_target)","category":"filesystem","line_end":617,"severity":"medium","line_start":617},{"id":"filesystem:scripts/native_subtitle_stitch.py:107:python-os-file-operations","file":"scripts/native_subtitle_stitch.py","pattern":"Python os file operations","snippet":"os.unlink(tmp)","category":"filesystem","line_end":107,"severity":"medium","line_start":107},{"id":"obfuscation:scripts/native_subtitle_stitch.py:144:unicode-escape-sequence","file":"scripts/native_subtitle_stitch.py","pattern":"Unicode escape sequence","snippet":"(\"\\u1100\", \"\\u11ff\"),  # 谚文字母","category":"obfuscation","line_end":144,"severity":"low","line_start":144},{"id":"obfuscation:scripts/native_subtitle_stitch.py:145:unicode-escape-sequence","file":"scripts/native_subtitle_stitch.py","pattern":"Unicode escape sequence","snippet":"(\"\\u3040\", \"\\u30ff\"),  # 平假名与片假名","category":"obfuscation","line_end":145,"severity":"low","line_start":145},{"id":"obfuscation:scripts/native_subtitle_stitch.py:146:unicode-escape-sequence","file":"scripts/native_subtitle_stitch.py","pattern":"Unicode escape sequence","snippet":"(\"\\u3130\", \"\\u318f\"),  # 谚文兼容字母","category":"obfuscation","line_end":146,"severity":"low","line_start":146},{"id":"obfuscation:scripts/native_subtitle_stitch.py:147:unicode-escape-sequence","file":"scripts/native_subtitle_stitch.py","pattern":"Unicode escape sequence","snippet":"(\"\\u3400\", \"\\u9fff\"),  # CJK 统一表意文字","category":"obfuscation","line_end":147,"severity":"low","line_start":147},{"id":"obfuscation:scripts/native_subtitle_stitch.py:148:unicode-escape-sequence","file":"scripts/native_subtitle_stitch.py","pattern":"Unicode escape sequence","snippet":"(\"\\uac00\", \"\\ud7af\"),  # 谚文音节","category":"obfuscation","line_end":148,"severity":"low","line_start":148},{"id":"obfuscation:scripts/native_subtitle_stitch.py:149:unicode-escape-sequence","file":"scripts/native_subtitle_stitch.py","pattern":"Unicode escape sequence","snippet":"(\"\\uf900\", \"\\ufaff\"),  # CJK 兼容表意文字","category":"obfuscation","line_end":149,"severity":"low","line_start":149},{"id":"obfuscation:scripts/native_subtitle_stitch.py:150:unicode-escape-sequence","file":"scripts/native_subtitle_stitch.py","pattern":"Unicode escape sequence","snippet":"(\"\\uff66\", \"\\uff9d\"),  # 半角片假名","category":"obfuscation","line_end":150,"severity":"low","line_start":150},{"id":"external_commands:SKILL.md:14:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":16,"severity":"medium","line_start":14},{"id":"external_commands:SKILL.md:16:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":18,"severity":"medium","line_start":16},{"id":"external_commands:SKILL.md:18:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- 脚本从 Skill 内的 `VERSION` 读取本地版本,只访问本项目的 GitHub Latest Release;默认 24 小时内复用一次缓存。","category":"external_commands","line_end":19,"severity":"medium","line_start":18},{"id":"external_commands:SKILL.md:19:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- 结果为 `update_available` 时,用一句话告诉用户当前版本、最新版本和 Release 链接,然后继续当前任务。只提醒,不自动更新、不覆盖本地 Skill。","category":"external_commands","line_end":20,"severity":"medium","line_start":19},{"id":"external_commands:SKILL.md:20:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- 结果为 `up_to_date` 时无需打扰用户。结果为 `unavailable` 时也不要阻塞当前任务;若只是运行环境禁止联网,可申请对 GitHub API 的只读访问并用 `--force","category":"external_commands","line_end":20,"severity":"medium","line_start":20},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 关闭播放器 CC 后,截图里仍有字幕;用户要求保留原字幕 | **原生字幕模式** | 视频画面像素 | `render` |","category":"external_commands","line_end":28,"severity":"medium","line_start":27},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 视频没有需要的烧录字幕,但用户要求把经确认的台词、翻译或观点排成案例风格 | **脚本字幕模式** | 已审核 JSON 中的 `text` | `render-script` |","category":"external_commands","line_end":28,"severity":"medium","line_start":28},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- **YouTube 等 URL**:先读 [references/yt-dlp-and-transcripts.md](references/yt-dlp-and-transcripts.md),","category":"external_commands","line_end":44,"severity":"medium","line_start":37},{"id":"external_commands:SKILL.md:44:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"将 `<SKILL_DIR>` 解析为当前 `SKILL.md` 所在目录的绝对路径;不要假设 Agent 的工作目录就是 Skill 目录。","category":"external_commands","line_end":44,"severity":"medium","line_start":44},{"id":"external_commands:SKILL.md:46:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":55,"severity":"medium","line_start":46},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":57,"severity":"medium","line_start":55},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"核心依赖为 Python 3.10+、Pillow,以及 FFmpeg 或 `imageio-ffmpeg`。URL 模式另需 `yt-dlp` 和 YouTube 完整解析所需的 JavaScrip","category":"external_commands","line_end":57,"severity":"medium","line_start":57},{"id":"external_commands:SKILL.md:59:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":61,"severity":"medium","line_start":59},{"id":"external_commands:SKILL.md:61:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":70,"severity":"medium","line_start":61},{"id":"external_commands:SKILL.md:70:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- 只有自动布局确实不适用时,才传 `--hero-fraction`。","category":"external_commands","line_end":71,"severity":"medium","line_start":70},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- 不覆盖已有成品。只有用户明确要替换时才添加 `--overwrite`。","category":"external_commands","line_end":82,"severity":"medium","line_start":71},{"id":"external_commands:SKILL.md:82:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":85,"severity":"medium","line_start":82},{"id":"external_commands:SKILL.md:85:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":89,"severity":"medium","line_start":85},{"id":"external_commands:SKILL.md:89:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":93,"severity":"medium","line_start":89},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":103,"severity":"medium","line_start":93},{"id":"external_commands:SKILL.md:103:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"单行字幕从 `0.78–0.96` 开始;两行字幕或位置偏高时,先预览再扩大到例如 `0.62–0.96`。","category":"external_commands","line_end":103,"severity":"medium","line_start":103},{"id":"external_commands:SKILL.md:105:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":108,"severity":"medium","line_start":105},{"id":"external_commands:SKILL.md:108:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":112,"severity":"medium","line_start":108},{"id":"external_commands:SKILL.md:112:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```json","category":"external_commands","line_end":121,"severity":"medium","line_start":112},{"id":"external_commands:SKILL.md:121:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":123,"severity":"medium","line_start":121},{"id":"external_commands:SKILL.md:123:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":128,"severity":"medium","line_start":123},{"id":"external_commands:SKILL.md:128:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":130,"severity":"medium","line_start":128},{"id":"external_commands:SKILL.md:130:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"`title` 只用于文件名,不画进图片。`times` 必须来自已回看的稳定帧。输出包含逐张 JPG、`原生字幕时间点.json` 和 `final_contact_sheet.jpg`。","category":"external_commands","line_end":130,"severity":"medium","line_start":130},{"id":"external_commands:SKILL.md:136:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```json","category":"external_commands","line_end":146,"severity":"medium","line_start":136},{"id":"external_commands:SKILL.md:146:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":148,"severity":"medium","line_start":146},{"id":"external_commands:SKILL.md:148:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `t` 必须严格递增且小于视频时长。","category":"external_commands","line_end":149,"severity":"medium","line_start":148},{"id":"external_commands:SKILL.md:149:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `text` 必须是已核对的单行台词;过长时拆句,不靠极小字号硬塞。","category":"external_commands","line_end":155,"severity":"medium","line_start":149},{"id":"external_commands:SKILL.md:155:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":159,"severity":"medium","line_start":155},{"id":"external_commands:SKILL.md:159:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":161,"severity":"medium","line_start":159},{"id":"external_commands:SKILL.md:161:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"脚本会尝试 macOS、Windows 和 Linux 常见 CJK 字体。无法自动找到时,用 `--font /path/to/font.ttc` 指定已获授权的字体。需要调整字幕条在原帧中的垂直采","category":"external_commands","line_end":161,"severity":"medium","line_start":161},{"id":"external_commands:SKILL.md:174:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"发现问题时只调整对应变量:时间点通常移动 `0.3–1.5` 秒;原生字幕被裁时调整 `band` 边界;台词条太高时先恢复自动布局;文字过长时先拆句。连续三轮仍找不到稳定画面时,换片段或报告限制,不","category":"external_commands","line_end":174,"severity":"medium","line_start":174},{"id":"external_commands:SKILL.md:178:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `yt-dlp`:获取用户有权处理的在线视频、元数据和字幕轨;不负责最终渲染。","category":"external_commands","line_end":195,"severity":"medium","line_start":178},{"id":"external_commands:SKILL.md:195:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"登录、年龄验证、机器人验证或用户自己的非公开视频需要 Cookies 时,必须先取得授权;授权后优先让 `yt-dlp` 通过 `--cookies-from-browser chrome` 临时读取","category":"external_commands","line_end":195,"severity":"medium","line_start":195},{"id":"obfuscation:agents/openai.yaml:4:heuristic-very-high-entropy-string-5-87-bits-lik","file":"agents/openai.yaml","pattern":"[HEURISTIC] Very high entropy string (5.87 bits) - likely encoded/encrypted payload","snippet":"使用 $native-subtitle-quote-image 把这个视频或链接做成紧凑字幕拼图；先检查来源、字幕类型和环境，明确原生或脚本字幕模式，再选句、取...","category":"obfuscation","line_end":4,"severity":"high","line_start":4},{"id":"obfuscation:references/end-to-end-workflow.md:1:heuristic-high-file-entropy-7-67-bits-possible-b","file":"references/end-to-end-workflow.md","pattern":"[HEURISTIC] High file entropy (7.67 bits) - possible binary/encrypted content","snippet":"File: references/end-to-end-workflow.md","category":"obfuscation","line_end":1,"severity":"high","line_start":1},{"id":"obfuscation:references/visual-style.md:1:heuristic-high-file-entropy-7-58-bits-possible-b","file":"references/visual-style.md","pattern":"[HEURISTIC] High file entropy (7.58 bits) - possible binary/encrypted content","snippet":"File: references/visual-style.md","category":"obfuscation","line_end":1,"severity":"high","line_start":1},{"id":"obfuscation:references/yt-dlp-and-transcripts.md:155:heuristic-very-high-entropy-string-5-65-bits-lik","file":"references/yt-dlp-and-transcripts.md","pattern":"[HEURISTIC] Very high entropy string (5.65 bits) - likely encoded/encrypted payload","snippet":"是否允许我让 yt-dlp 临时读取 Chrome 中已登录的 YouTube Cookie？它只用于获取这个链接的视频和字幕，不会导出、保存或上传 Cooki...","category":"obfuscation","line_end":155,"severity":"high","line_start":155},{"id":"obfuscation:references/yt-dlp-and-transcripts.md:1:heuristic-high-file-entropy-7-18-bits-possible-b","file":"references/yt-dlp-and-transcripts.md","pattern":"[HEURISTIC] High file entropy (7.18 bits) - possible binary/encrypted content","snippet":"File: references/yt-dlp-and-transcripts.md","category":"obfuscation","line_end":1,"severity":"high","line_start":1},{"id":"obfuscation:SKILL.md:1:heuristic-high-file-entropy-7-54-bits-possible-b","file":"SKILL.md","pattern":"[HEURISTIC] High file entropy (7.54 bits) - possible binary/encrypted content","snippet":"File: SKILL.md","category":"obfuscation","line_end":1,"severity":"high","line_start":1}],"finding_verdicts":[{"id":"scripts:scripts/check_environment.py:47:python-dynamic-import","reason":"The helper is called only with fixed dependency names, and find_spec confirms availability before import. No user-controlled module name reaches the import.","verdict":"false_positive","confidence":0.93},{"id":"scripts:scripts/check_environment.py:87:python-dynamic-import","reason":"The module name is the fixed literal imageio_ffmpeg and is used only to locate its FFmpeg binary. No user-controlled module name is involved.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/check_environment.py:31:python-subprocess-run","reason":"The command is selected by shutil.which and receives fixed version arguments. It only reports installed tool status and does not invoke a shell.","verdict":"false_positive","confidence":0.95},{"id":"external_commands:scripts/check_update.py:120:python-subprocess-run","reason":"The fallback invokes curl with a fixed executable, fixed HTTPS endpoint, and fixed option list. There is no shell interpolation or user-provided command text.","verdict":"false_positive","confidence":0.96},{"id":"network:scripts/check_update.py:11:python-http-libraries","reason":"urllib is used for the documented, read-only GitHub release check. Network access is limited to the fixed repository endpoint.","verdict":"false_positive","confidence":0.98},{"id":"network:scripts/check_update.py:106:python-http-libraries","reason":"The request object targets the fixed GitHub latest-release URL and supplies informational headers only. No arbitrary destination is accepted.","verdict":"false_positive","confidence":0.98},{"id":"network:scripts/check_update.py:114:python-http-libraries","reason":"The URL opener performs a bounded read with a timeout for the update check. It does not upload media, credentials, or user content.","verdict":"false_positive","confidence":0.98},{"id":"network:scripts/check_update.py:17:hardcoded-url","reason":"This URL is the declared repository GitHub API endpoint required for release metadata. A fixed endpoint is safer than an attacker-selected destination.","verdict":"false_positive","confidence":0.99},{"id":"network:scripts/check_update.py:18:hardcoded-url","reason":"This is the fixed public release page used for displaying update information. It is not a hidden or suspicious destination.","verdict":"false_positive","confidence":0.99},{"id":"env_access:scripts/check_update.py:39:python-environment-access","reason":"The environment variable only lets the user choose the update-cache path. It is not used to read secrets or alter execution.","verdict":"false_positive","confidence":0.97},{"id":"env_access:scripts/check_update.py:47:python-environment-access","reason":"LOCALAPPDATA selects the conventional per-user cache directory on Windows. The value is used for local cache placement, not credential access.","verdict":"false_positive","confidence":0.97},{"id":"env_access:scripts/check_update.py:49:python-environment-access","reason":"XDG_CACHE_HOME selects the conventional user cache directory on non-Windows systems. No sensitive environment value is transmitted.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/native_subtitle_stitch.py:29:python-subprocess-run","reason":"FFmpeg is invoked through an argument list with a fixed executable prefix and validated local input paths. Shell interpretation is not enabled.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:scripts/native_subtitle_stitch.py:50:python-subprocess-run","reason":"The metadata probe passes the validated video path as one argv element and does not use shell execution. This is required for media inspection.","verdict":"false_positive","confidence":0.94},{"id":"filesystem:scripts/native_subtitle_stitch.py:12:temp-file-creation","reason":"The tempfile module is used for an intermediate frame, which is standard isolated processing. The temporary file is removed in cleanup logic.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/native_subtitle_stitch.py:82:temp-file-creation","reason":"mkstemp creates a uniquely named temporary PNG before FFmpeg writes the frame. The descriptor is closed and the path is deleted afterward.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/native_subtitle_stitch.py:617:python-shutil-operations","reason":"copyfile duplicates the user-supplied manifest into the selected output directory as part of delivery. It is not an unauthorized system-file operation.","verdict":"false_positive","confidence":0.96},{"id":"filesystem:scripts/native_subtitle_stitch.py:107:python-os-file-operations","reason":"os.unlink removes the intermediate frame created by this run. It is guarded by an existence check and is part of normal cleanup.","verdict":"false_positive","confidence":0.99},{"id":"obfuscation:scripts/native_subtitle_stitch.py:144:unicode-escape-sequence","reason":"The escape range labels Hangul characters for CJK font detection. It is ordinary Unicode handling, not hidden executable content.","verdict":"false_positive","confidence":0.99},{"id":"obfuscation:scripts/native_subtitle_stitch.py:145:unicode-escape-sequence","reason":"The escape range labels Hiragana and Katakana for CJK font detection. It is ordinary Unicode handling, not hidden executable content.","verdict":"false_positive","confidence":0.99},{"id":"obfuscation:scripts/native_subtitle_stitch.py:146:unicode-escape-sequence","reason":"The escape range labels Hangul compatibility characters for font detection. It does not encode or decode a payload.","verdict":"false_positive","confidence":0.99},{"id":"obfuscation:scripts/native_subtitle_stitch.py:147:unicode-escape-sequence","reason":"The escape range covers CJK unified ideographs used to detect text requiring a CJK font. This is transparent presentation logic.","verdict":"false_positive","confidence":0.99},{"id":"obfuscation:scripts/native_subtitle_stitch.py:148:unicode-escape-sequence","reason":"The escape range covers Hangul syllables for font selection. It is a standard character-range check with no obfuscation behavior.","verdict":"false_positive","confidence":0.99},{"id":"obfuscation:scripts/native_subtitle_stitch.py:149:unicode-escape-sequence","reason":"The escape range covers CJK compatibility ideographs for font selection. It is readable Unicode classification logic.","verdict":"false_positive","confidence":0.99},{"id":"obfuscation:scripts/native_subtitle_stitch.py:150:unicode-escape-sequence","reason":"The escape range covers half-width Katakana for font selection. No encoded command or concealed data is present.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:14:ruby-shell-backtick-execution","reason":"The flagged text is a Markdown shell code fence in documentation, not Ruby or runtime backtick execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:16:ruby-shell-backtick-execution","reason":"The flagged text closes a Markdown shell example. Documentation delimiters do not execute commands.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:18:ruby-shell-backtick-execution","reason":"This line documents the read-only update check and contains inline Markdown code. It is not executable Ruby or shell syntax.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:19:ruby-shell-backtick-execution","reason":"This line describes reporting an available release and contains inline Markdown code. It does not execute a command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:20:ruby-shell-backtick-execution","reason":"This line documents an optional read-only retry and contains inline Markdown code. It is instruction text, not runtime backtick execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","reason":"The flagged backticks are Markdown table formatting around a documented render command. No command is executed by the Markdown file.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","reason":"The flagged backticks identify a documented mode and command in a Markdown table. They are not shell execution syntax.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","reason":"The line is prose linking to a reference document and naming yt-dlp with Markdown formatting. It cannot execute a command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:44:ruby-shell-backtick-execution","reason":"The line documents path resolution and uses inline code formatting. It contains no executable backtick expression.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:46:ruby-shell-backtick-execution","reason":"This is the opening fence of a documented shell example. A Markdown fence is not shell execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","reason":"This is the closing fence of a documented shell example. It is inert Markdown text.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","reason":"This dependency description uses inline code names in prose. It is not a command invocation or Ruby backtick expression.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:59:ruby-shell-backtick-execution","reason":"This is the opening fence of a pip command example in documentation. It has no runtime effect by itself.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:61:ruby-shell-backtick-execution","reason":"This is the closing fence of a pip command example. Markdown delimiters are not executed.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:70:ruby-shell-backtick-execution","reason":"This layout rule mentions a command option with inline Markdown formatting. It is non-executable guidance.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","reason":"This overwrite rule mentions a command option in prose. It does not contain runtime shell execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:82:ruby-shell-backtick-execution","reason":"This is the opening fence of a documented sampling command. It is inert Markdown.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:85:ruby-shell-backtick-execution","reason":"This is the closing fence of a documented sampling command. It cannot execute from the reference file.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:89:ruby-shell-backtick-execution","reason":"This is the opening fence of another documented sampling command. It is not executable code in this context.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","reason":"This is the closing fence of a documented sampling command. The scanner matched formatting, not execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:103:ruby-shell-backtick-execution","reason":"This line gives a numeric crop range in prose with inline code formatting. It has no command execution semantics.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:105:ruby-shell-backtick-execution","reason":"This is the opening fence of a documented band-preview command. It is inert Markdown.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:108:ruby-shell-backtick-execution","reason":"This is the closing fence of a documented band-preview command. It does not run a shell.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:112:ruby-shell-backtick-execution","reason":"This is the opening fence of a JSON manifest example. It is documentation, not executable shell syntax.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:121:ruby-shell-backtick-execution","reason":"This is the closing fence of a JSON manifest example. It is inert Markdown formatting.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:123:ruby-shell-backtick-execution","reason":"This is the opening fence of a documented render command. It has no execution effect in SKILL.md.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:128:ruby-shell-backtick-execution","reason":"This is the closing fence of a documented render command. The detected backticks are Markdown delimiters.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:130:ruby-shell-backtick-execution","reason":"This line documents output names with inline code formatting. It is not runtime command execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:136:ruby-shell-backtick-execution","reason":"This is the opening fence of a JSON script example. It is non-executable documentation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:146:ruby-shell-backtick-execution","reason":"This is the closing fence of a JSON script example. Markdown formatting cannot run commands.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:148:ruby-shell-backtick-execution","reason":"This timing rule uses inline code formatting for field names. It is explanatory prose, not shell execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:149:ruby-shell-backtick-execution","reason":"This validation rule uses inline code formatting for a field name. It contains no executable backtick expression.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:155:ruby-shell-backtick-execution","reason":"This is the opening fence of a documented script-render command. It is inert Markdown.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:159:ruby-shell-backtick-execution","reason":"This is the closing fence of a documented script-render command. It does not execute a shell.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:161:ruby-shell-backtick-execution","reason":"This font guidance uses inline code for option names and paths. It is documentation, not runtime execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:174:ruby-shell-backtick-execution","reason":"This rework guidance uses inline code for numeric values and options. It is non-executable Markdown prose.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:178:ruby-shell-backtick-execution","reason":"This cooperation section names external tools in inline Markdown. Naming a tool does not execute it.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:195:ruby-shell-backtick-execution","reason":"This cookie-safety rule contains inline command formatting in prose. It documents controlled use and is not Ruby or shell execution.","verdict":"false_positive","confidence":0.99},{"id":"obfuscation:agents/openai.yaml:4:heuristic-very-high-entropy-string-5-87-bits-lik","reason":"The value is a readable Chinese default prompt in YAML. The entropy heuristic provides no evidence of encoded or encrypted content.","verdict":"false_positive","confidence":0.98},{"id":"obfuscation:references/end-to-end-workflow.md:1:heuristic-high-file-entropy-7-67-bits-possible-b","reason":"The file begins with ordinary Chinese workflow prose and Markdown headings. No binary or encrypted payload is evidenced.","verdict":"false_positive","confidence":0.98},{"id":"obfuscation:references/visual-style.md:1:heuristic-high-file-entropy-7-58-bits-possible-b","reason":"The file begins with ordinary Chinese visual guidance and Markdown. High text entropy alone does not establish obfuscation.","verdict":"false_positive","confidence":0.98},{"id":"obfuscation:references/yt-dlp-and-transcripts.md:155:heuristic-very-high-entropy-string-5-65-bits-lik","reason":"The flagged line is an explicit Chinese consent question about temporary cookie access. It is readable policy text, not an encoded payload.","verdict":"false_positive","confidence":0.97},{"id":"obfuscation:references/yt-dlp-and-transcripts.md:1:heuristic-high-file-entropy-7-18-bits-possible-b","reason":"The file starts with readable Chinese documentation and links to public tool guidance. No binary or encrypted content is evidenced.","verdict":"false_positive","confidence":0.98},{"id":"obfuscation:SKILL.md:1:heuristic-high-file-entropy-7-54-bits-possible-b","reason":"SKILL.md is readable Chinese Markdown with workflow instructions and examples. The heuristic does not identify any encoded or encrypted payload.","verdict":"false_positive","confidence":0.98}],"semantic_findings":[{"title":"Sensitive Browser Session Access","severity":"medium","locations":[{"file":"references/yt-dlp-and-transcripts.md","line_end":158,"line_start":152},{"file":"SKILL.md","line_end":195,"line_start":195}],"confidence":0.88,"description":"The YouTube recovery workflow can ask yt-dlp to read Chrome session cookies for a private or verification-gated video. Authorization and no-export rules reduce risk, but a browser session remains sensitive account material.","confidence_reasoning":"The cited workflow explicitly requests permission to read Chrome cookies and then passes them to yt-dlp. The same text prohibits exporting them, so the risk is residual sensitive access rather than demonstrated exfiltration."}],"subject_marketplace_commit_sha":"dd2fcaef932574591f2502a46fb2362cde6fa9a1","subject_content_hash":"aaeafa98bd74bdc8347030e33b5fda699e4c8ac49a83167eee524fb225171c29","subject_tree_hash":"091e7b32ba6733ac81d6366bdb426a05e1bd91d5e81726fbf0510f104bc4cdcb","subject_plugin_path":"skills/chengyi-ai/native-subtitle-quote-image","audit_payload_hash":"437e5edeac1cab9b2e74910a2f279dec","confirmed_risk_level":"medium","scanner_version":"3.0.0","policy_version":"skillstore-security-audit-policy-v1","subject":{"marketplaceCommitSha":"dd2fcaef932574591f2502a46fb2362cde6fa9a1","contentHash":"aaeafa98bd74bdc8347030e33b5fda699e4c8ac49a83167eee524fb225171c29","treeHash":"091e7b32ba6733ac81d6366bdb426a05e1bd91d5e81726fbf0510f104bc4cdcb","pluginPath":"skills/chengyi-ai/native-subtitle-quote-image","auditPayloadHash":"437e5edeac1cab9b2e74910a2f279dec"},"scannerVersion":"3.0.0","policyVersion":"skillstore-security-audit-policy-v1"},"auditTranslation":null,"localization":{"requestedLocale":"en","contentLocale":"en","availableLocales":["en"],"fallbackToEnglish":false},"attestation":{"availability":"issued","url":"/api/skills/chengyi-ai-native-subtitle-quote-image/audits/1/attestation","status":"active"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"medium","confirmedFindingCount":1,"capabilityReviewCount":0,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"allowed","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"active","verificationState":"not_verified"},"isLatest":true}}