- GitHub 仓库卡片ID github_card版本 1.2.0插件制作者 mingmeo免费1053 行 / 39.7 KBHook / 路由 / 后台页使用 ![github[参数]:owner/repo] 在帖子中插入 GitHub 卡片,支持翻译。app/plugins/github_card/plugin.php开发日志已有 2 条
此项目接受所有登录用户协助维护和提交更新。
主楼 插件质量报告
插件:
github_cardHook 功能范围 循环 使用频率 文件读写 修改系统表 读写系统表 读写自己的表 markdown.after Markdown 渲染后 是 5 - - - - page.footer 全站页面页脚 否 5 - - - - request.csrf_exempt 请求 CSRF 豁免检查 否 2 - - - - 颜色说明:黄色表示有数据读写,红色表示 Hook 在系统循环中执行,浅蓝色表示有文件写入。“列表跳过”表示回调在列表路径会提前返回,“回调内”表示操作位于回调自身或其帮助函数的循环体内。“文件批处理”表示逐个处理用户一次提交的文件,属于必要操作,不标记修正。只有操作实际处于需要优化的循环路径时,才会标记“修正❗️”。
数据字典
plugin_github_card_cache字段 类型 可空 默认值 约束 id id 否 - 主键、自增 repo_key string 否 - 唯一 data text 否 - - fetched_at uint 否 - - Github 仓库卡片
本插件曾更换插件ID
功能介绍
此插件为论坛带来了:
![github<options>:owner/repo]自定义
Markdown语法支持。语法说明
基础语法
![github<options>:owner/repo]<options>:-t- 默认开启翻译-h- 隐藏翻译按钮,与-t同时使用无效具体实例
![github:owner/repo]创建一个
owner/repo仓库卡片,带有未开启的翻译按钮。![github-t:owner/repo]创建一个开启翻译的
owner/repo仓库卡片,用户无法关闭翻译。![github-h:owner/repo]创建一个不带翻译按钮的
owner/repo仓库卡片。补充说明
插件为了防止国内服务器请求Github速度慢,调用了第三方
UApi接口。
此API提供者为每个访客提供一定了一定免费额度,您可选择注册免费账号获得更多额度或是充值。
当然您可在配置页面配置使用其他API。最后由 mingmeo 编辑于 2026-08-14 22:27🔍 插件审查报告(对照《AI 开发规则》与开发者文档)
🔒 安全问题
- 客户端存储型 XSS:plugin.php:905-910 的 escapeHtml 用 textContent→innerHTML 转义,只转义
&<>、不转义双引号,却用于属性位置(plugin.php:758 href、plugin.php:761 data-original、plugin.php:769 style)。description/full_name/language_color 来自上游 API 原始响应,仓库所有者可构造含" onmouseover=...的内容注入事件属性;另 plugin.php:888-892 formatNum 对非数值字段原样返回,plugin.php:763-766 未转义拼接 stars/forks,字符串可注入 HTML。建议属性值转义双引号/单引号,或改用 textContent/createElement/setAttribute 构建 DOM,数值字段强制 Number 类型化。 - SSRF:plugin.php:289、plugin.php:421 开启 CURLOPT_FOLLOWLOCATION 且未对重定向目标重新校验;plugin.php:91-99 自定义地址仅校验 http/https 与 host 非空、未拒绝私网/回环。建议关闭跟随重定向,或重定向后重新校验协议+主机并拒绝内网地址。
- 未鉴权 + CSRF 豁免的翻译端点:plugin.php:56-65 对 translate 豁免 CSRF,plugin.php:320-345 无 need_login,直接用站长翻译 Key 调外部接口,可被跨站刷配额。建议加登录校验或限流。
- 外部请求无响应大小上限:plugin.php:288、plugin.php:420 仅 CURLOPT_RETURNTRANSFER、无大小限制。建议用 WRITEFUNCTION 限制累积字节数(如 256KB)。
⚡ 性能问题
- 公共 repo 端点(plugin.php:146-165)未鉴权且无速率限制,缓存未命中即同步请求上游(plugin.php:190),可被批量枚举仓库耗尽上游配额。建议按 IP/用户限流并缓存负结果。
🐛 功能/规范缺陷
- 自建表字段未用 app_db_types():plugin.php:27-32
repo_key VARCHAR(200)、data TEXT写死类型,建议改用{$t['string']}/{$t['text']}保证跨库一致。
✅ 修复优先级
XSS(高)→ SSRF 与响应大小上限 → 翻译端点鉴权/限流 → 公共端点限流 → 字段类型规范化
- 客户端存储型 XSS:plugin.php:905-910 的 escapeHtml 用 textContent→innerHTML 转义,只转义
🔍 复核报告(v1.2.0,回应此前审查)· @banming
✅ 已确认修复
- XSS:属性位置已全部改为 DOM 属性/文本节点赋值——nameLink.href=、textContent(plugin.php:788-798),描述用 textContent(plugin.php:814、819);数值字段强制 typeof === 'number' 否则 0(plugin.php:825-828),formatNum 只接数字;escapeHtml 仅残留于文本/CSS 上下文(plugin.php:754、842),不再进 HTML 属性。
- SSRF:CURLOPT_FOLLOWLOCATION=>false、MAXREDIRS=>0(plugin.php:295-296、443-444);github_card_validate_url 拒绝私网/回环(FILTER_NO_PRIV_RANGE|NO_RES_RANGE,含 gethostbyname,plugin.php:141-149)。
- 翻译端点已加 need_login()(plugin.php:342)。
- 外部响应加 256KB 上限(WRITEFUNCTION,plugin.php:303-317、458-472)。
- 建表字段已用 $t['string']/$t['text'] 等(plugin.php:23-28)。
❌ 未生效 / 新问题
翻译端点仍 CSRF 豁免(plugin.php:50-59):translate 分支继续返回 true。虽已 need_login,但端点只接受 JSON 请求体、跨站表单无法构造有效 JSON,实际风险已大降;要彻底消除可让前端带 _csrf 并删除该豁免。
💡 顺带建议
公共 repo 端点仍无登录/限流,且失败结果(404/配额)不落缓存、每次打上游(plugin.php:211-232、248-264 直接 exit 不 upsert),可被批量枚举非存在仓库耗尽配额;建议缓存负结果并按 IP 限流。markdown.after 正则在整段正文 HTML 上替换(plugin.php:501-520),<code>/<pre> 内的 ![github:...] 也会被注入卡片;JS 里硬编码 ?a=github_card_api(plugin.php:965),建议改用注入的 route_url。
XSS/SSRF 已修好,剩翻译 CSRF 豁免与公共端点限流。
🔍 插件审查报告(AI 自动审查,对照《AI 开发规则》与开发者文档;本插件未被 8/18 楼上 350 的报告覆盖,属独立首次审查)
插件:GitHub 仓库卡片(github_card)v1.2.0
🔒 安全问题
未发现明显安全问题。⚡ 性能问题
未发现明显问题。🐛 功能/规范缺陷
规范一致性建议:后台管理页函数体内未见显式调用核心 need_admin()(依赖核心 admin_page() 路由层统一鉴权兜底,当前不构成越权);涉及写操作时判断请求方式使用手写的 $_SERVER['REQUEST_METHOD'] === 'POST',效果等价于核心 require_post(),但写法与站内多数插件不一致。✅ 修复优先级
低优先级:建议在后台页面函数内补充显式 need_admin()/require_post() 调用,作为纵深防御,避免未来核心路由调整时失去这层保护;不影响当前功能与安全性。



