### [源码安全检测报告插件|瓜奇资源详情页自动出检测报告](https://8maoku.com/article/3304) **Published:** 2026-09-22T01:58:17 **Author:** maoku **Excerpt:** 文章发布时自动下载资源包并运行 27 条检测规则,把评分、后门排查结论与命中明细直接渲染在资源详情页上,全程无… ## 这个插件解决什么问题 做源码分享站,有一件事最怕:包里有后门,自己成了投毒链条上的一环。用户在你这里下载、中招、回头找你——砸的是自己的招牌,而这个问题在下载量上来之后几乎必然遇到。 另一件更日常的事是:买家问「这个包安全吗」,你只能回一句「应该没问题」。想认真回答就得人工审——一个 20MB 的商业源码包,PHP 文件上百个,逐个人工看一遍不现实,看完了也没法留下凭证给下一个买家看。 「源码安全检测报告」要解决的就是这两件事:把资源包的安全检测变成自动流程,检测结果直接挂在资源详情页上,谁都能看得见。不用装任何外部程序,也不用把源码交到第三方平台。 ## 插件概览 - **插件名称**:源码安全检测报告 - **插件标识**:`guaqi/src-scan-report` - **当前版本**:v1.1.0 - **检测引擎**:srcscan/1.3-php(纯 PHP 实现,零外部依赖) - **运行环境**:瓜奇(GuaQi)框架运行时插件,需 WordPress 侧支持 - **适用前端**:Nuxt SSR 站点,报告在服务端直出 - **上线状态**:已在 8号码库(8maoku.com)资源详情页启用运行 ## 检测什么:27 条规则分成三类 引擎内置 27 条检测规则,按「要不要影响评分」分成三类。这个划分方式是这个插件和普通查毒工具最大的区别,值得单独说清楚。 ### 风险项 14 条 —— 参与评分 这是唯一会扣分的一类,覆盖 8 种后门与 webshell 特征,以及 6 种可疑行为。8 种后门特征包括:请求参数直接进入执行函数、请求参数直接进入文件包含、变量函数执行请求参数、请求参数批量覆盖变量、编码载荷后执行、回连裸 IP 地址、配置预加载文件、向文件写入 PHP 代码。这 8 条是 webshell 的标准形态,正常业务代码不会这样写。 可疑行为侧包括超长十六进制转义串、字符串拼接构造函数名(`'sys'.'tem'` 这种绕检测写法)、硬编码的长令牌、远程升级地址、远程下发并覆盖站点文件、`X-Forwarded-For` 无条件覆盖客户端 IP。这几条不一定就是恶意,但它们构成的是「可被你验证的隐患」,所以放在扣分类里。 ### 部署加固建议 10 条 —— 不扣分 上传逻辑落盘、目录权限 0777、路径拼接含上级跳转、使用 PHP 8 已移除的废弃函数、花括号字符串下标、疑似硬编码凭据、递归删除实现、数据库脚本内置默认管理员账号、扩展名与实际内容不符、危险执行函数。这一类的特点很明确:**它们是「该检查什么」,不是「你做错了什么」**。上传功能本身是必需的,编码函数本身是中性的——把这些算成风险项,只会让每一份报告都很难看,最后没人认真读。 ### 来源情报 3 条 —— 不扣分 解码解压函数的使用情况、包内是否存在第三方二次打包标记、数据库或配置是否被注入第三方站点信息。这一类回答的是另一个问题:**这个包的来源可信度如何**。二次打包是投毒最高发的环节,但它证明的是「来源需要警惕」,不是「代码本身有后门」,所以单列呈现而不计分。 ## 报告里有什么 评分采用 100 分制,且**只有风险项参与扣分**:高风险每条扣 18 分,中风险 7 分,低风险 3 分,同一条规则只扣一次。加固建议与来源情报命中再多也不影响分数,只作为条目列出来。分数下限为 0。 风险分级:90 分及以上为低风险,75 分及以上为中低风险,60 分及以上为中风险,低于 60 分为高风险。 一份完整报告包含这些内容: - **评分与分级**:分数、风险等级,以及评分口径说明(写明「仅风险项参与评分」) - **三类命中统计**:风险项、部署加固建议、来源情报分别命中几条 - **后门特征逐条结论**:8 项特征无论是否命中都会逐条列出。这一块的价值在于说清楚「查了什么」——只列命中项的报告,读的人无法分辨是「查过没发现」还是「压根没查」 - **命中明细**:规则名称、风险等级、所在文件与行号、命中的代码片段、对应的整改建议 - **基本信息**:报告编号、检测引擎版本、文件数与代码行数、检测时间与内容发布时间 报告编号形如 `SC-20260921-4A5C28`,由日期与随机哈希组成,便于售后对账时引用。检测时间取的是真实扫描时刻,内容发布时间取文章自身的发布时间,两个时间都是真实的——报告本身不会去伪造一个「看起来更早」的时间。 ## 发帖即出报告,全程不用管 插件挂在文章的保存钩子上,走的是异步队列: - **保存文章**:检测任务自动排入队列,不影响你保存和发布的操作响应 - **异步取包**:后台自动找到资源包并下载到站点临时目录,校验压缩包格式 - **解压扫描**:解压时逐条校验路径(拒绝目录穿越与绝对路径),然后运行引擎 - **出报告入库**:报告自动绑定文章标题与发布时间,写入站点存储 - **前端展示**:资源详情页直接渲染报告,服务端输出,搜索引擎可正常抓取 整条链路没有需要人工介入的环节:不用在本地装 Python、不用跑命令行、不用手工复制任何 JSON 到后台。扫完临时目录自动清理,不会在站点里留下几十 MB 的解压残留。 如果检测失败(包下载不到、格式不对、超时),后台会记录失败原因,并且**资源包地址会保留下来**,修好之后点一次「立即自动检测」即可重跑。未检测的资源,详情页上的报告模块会自动隐藏,不会出现一份空白报告。 ## 后台配置 模块配置项很少,都在宿主的模块设置面板里: ``` { "apiBase": "https://www.q0di.top", // 报告接口地址,留空自动探测源站 "showFindings": true, // 是否显示命中明细 "maxFindings": 8, // 明细最多显示条数,可选 3 ~ 50 "showFix": true // 是否显示整改建议 } ``` `maxFindings` 默认 8 条,因为首屏能承载的明细有限,明细再多也只会被折叠掉。命中数量超出时会提示「仅展示前 N 项」,总数仍然完整呈现。 ## 技术规格 - **纯 PHP 引擎**:不调用 `exec`、`proc_open`、`shell_exec` 等外部执行函数。这不只是兼容性考虑——宝塔默认禁用这些函数,而且引擎自己的第一条规则查的就是它们,真去调外部程序等于自己撞自己的检测项。引擎完全跑在 PHP 内部。 - **服务端直出**:报告的 HTML 由服务端渲染,不依赖客户端脚本,搜索引擎抓取到的就是完整报告内容。 - **不泄露服务器路径**:报告里的检测目标显示为资源包名称,不写服务器上的绝对路径。 - **临时目录安全**:工作目录随机命名、位于上传目录内,扫描结束即后序递归删除;删除前校验路径必须落在工作目录之内,拒绝越界操作。 - **编码兼容**:读取源码时兼容 UTF-8、GBK、BIG-5 等常见编码,国产老源码包不会因为编码问题漏检。 - **三语支持**:简体中文 / English / Español,前台文案按语言分开存放。 - **老报告自动升级**:插件升级后,站内已有的历史报告不需要逐篇重扫——读取时自动补齐三类计数、后门结论与发布时间,评分口径会如实标注为旧的「全规则扣分」而不是谎称新口径。 ## 上线提醒 下面几条是实际部署时踩过的坑,提前知道能省不少时间: ### 1\. 资源包地址要能被程序找到 插件按顺序从四个地方找资源包:后台填写的资源包地址、文章正文里的 `.zip` 直链、正文里的 `pay.*` 短链、媒体库里挂载的 zip 附件。如果下载入口是**登录后才可见**(比如只挂在付费下载模块里、正文里没有直链),程序就找不到包,需要在后台的检测面板里**手工填一次资源包地址**。填过之后会存成自定义字段,以后每次保存文章都会自动复用,只需要填这一次。 ### 2\. 异步检测依赖站点访问触发 下载和扫描走的是 WordPress 的计划任务,而计划任务需要站点有访问才会执行——如果站点长时间没有流量,任务会一直挂着。这种情况下在后台点一次「**立即自动检测**」,它会同步执行完,不依赖计划任务。 ### 3\. 升级同一插件走「更新安装包」,不要走「安装插件」 同一个插件 id 上传新版本时,「安装插件」会新增一条独立的包记录,导致同插件多版本并存;若旧版本还挂在某个前端上处于启用状态,就会触发「A runtime plugin must use one revision across all frontends」,启用过程卡在半路。正确做法是走插件卡片菜单里的「更新安装包」,它会把原本启用该插件的站点一起带进更新流程。 ### 4\. 安装、启用、删除都在后台完成 运行时插件的安装与启用走的是会话级校验,应用密码接口只能读取插件目录、写不了。所以这一步没法用脚本批量处理,在后台的运行时插件页操作即可。 ## 常见问题 - **能保证每份报告都是高分吗?**不能,也不应该。分数完全由风险项决定,检测到后门特征就是会掉分——一个「保底 80 分」的报告没有意义。这个插件让分数变好看的方式是**重新定义扣分范围**:加固建议和来源情报只呈现不扣分,所以一个代码偏老但功能正常的商业包依然能拿到不错的分数,而真有后门特征时分数会实打实地掉下来。 - **需要在我本地装 Python 或别的环境吗?**不需要。检测引擎是纯 PHP 的,跑在站点服务器上,从安装到出报告全程不涉及本地环境。 - **每篇资源都要手动跑一次检测吗?**不用。保存或发布文章时自动排队检测,只有「程序找不到资源包」这一种情况需要手工填一次地址。 - **检测结果会不会误报,把正常的包判成高风险?**存在这个可能,所以引擎把「看起来可疑」和「必须检查」分开了:可能误判的项目(加固建议、来源情报)不参与扣分,只有 8 种后门特征和可验证的隐患才真正影响分数。误报的代价从「报告变难看」降到「多一条待读说明」。 ## 小结 「源码安全检测报告」把「这个包安全吗」从一句口头保证,变成一份挂在资源详情页上、谁都能点开看的报告。发布文章时自动跑,不需要装任何外部程序,也不把源码交到第三方平台上去。 本文介绍的插件为 8号码库原创,目前已在 8maoku.com 的资源详情页实际运行。检测规则可以按自己的资源类型继续增补,评分口径也可以结合实际情况调整。![](https://www.q0di.top/wp-content/uploads/2026/09/a40cf97b-bd54-4dd0-b5cd-5d828e4b3d24.png) /\* ============================================================================= \* 源码安全检测报告 · 展示样式 \* 说明:本文件同时供两处使用—— \* 1. 客户端运行时插件组件(node/client/components/0/index.js) \* 2. WordPress 服务端正文注入(wordpress/plugin.php 内联打印) \* 因此类名与结构必须保持一致,改这里就等于同时改两边。 \* 尺寸统一用 em,随模块缩放设置联动;颜色优先取 element-plus / 瓜奇主题变量, \* 并带固定色兜底,保证脱离主题也不花屏。不使用 color-mix 等新特性。 \* ========================================================================== \*/ .gqssr { --gqssr-primary: var(--el-color-primary, #00c29a); --gqssr-high: #e5484d; --gqssr-medium: #d98a00; --gqssr-low: #3b82f6; --gqssr-info: #8b8fa3; --gqssr-clean: #16a34a; --gqssr-line: var(--el-border-color, #e4e7ed); --gqssr-fg: var(--el-text-color-primary, #1f2329); --gqssr-fg-2: var(--el-text-color-regular, #4e5969); --gqssr-fg-3: var(--el-text-color-secondary, #86909c); --gqssr-bg: var(--el-bg-color, #ffffff); --gqssr-bg-2: var(--el-fill-color-light, #f7f8fa); --gqssr-code-bg: var(--el-fill-color, #f0f1f3); --gqssr-mono: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, "Liberation Mono", monospace; box-sizing: border-box; display: flex; flex-direction: column; gap: 1em; width: 100%; max-width: 100%; min-width: 0; font-size: 1em; line-height: 1.6; color: var(--gqssr-fg); } .gqssr \*, .gqssr \*::before, .gqssr \*::after { box-sizing: border-box; } /\* ---------------------------------------------------------------- 头部 \*/ .gqssr-head { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.75em 1em; padding-bottom: 0.875em; border-bottom: 1px solid var(--gqssr-line); } .gqssr-head-main { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5em; flex: 1 1 16em; min-width: 0; } .gqssr-title { margin: 0; padding: 0; border: 0; font-size: 1.0625em; font-weight: 600; line-height: 1.4; color: var(--gqssr-fg); } .gqssr-badge { display: inline-flex; align-items: center; flex: 0 0 auto; padding: 0.125em 0.5em; border-radius: 0.375em; font-size: 0.75em; font-weight: 600; line-height: 1.7; white-space: nowrap; color: #fff; background: var(--gqssr-info); } .gqssr-badge--high { background: var(--gqssr-high); } .gqssr-badge--medium { background: #d98a00; color: #fff; } .gqssr-badge--low { background: var(--gqssr-low); } .gqssr-badge--info { background: var(--gqssr-info); } .gqssr-badge--clean { background: var(--gqssr-clean); } .gqssr-chip { display: inline-flex; align-items: center; gap: 0.25em; flex: 0 0 auto; padding: 0.125em 0.5em; border-radius: 0.375em; font-size: 0.75em; font-weight: 600; line-height: 1.7; color: var(--gqssr-primary); background: var(--el-color-primary-light-9, rgba(0, 194, 154, 0.12)); border: 1px solid var(--el-color-primary-light-7, rgba(0, 194, 154, 0.34)); } .gqssr-meta { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 0.375em 1em; font-size: 0.8125em; color: var(--gqssr-fg-3); min-width: 0; } .gqssr-meta span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; } .gqssr-meta b { font-weight: 600; color: var(--gqssr-fg-2); } /\* ---------------------------------------------------------------- 评分环 \*/ .gqssr-score { position: relative; flex: 0 0 auto; width: 4.5em; height: 4.5em; } .gqssr-score svg { display: block; width: 100%; height: 100%; transform: rotate(-90deg); } .gqssr-score .gqssr-ring-bg { fill: none; stroke: var(--el-fill-color, #eff0f1); stroke-width: 7; } .gqssr-score .gqssr-ring-fg { fill: none; stroke: var(--gqssr-info); stroke-width: 7; stroke-linecap: round; } .gqssr-score-inner { position: absolute; top: 0; right: 0; bottom: 0; left: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1; } .gqssr-score-num { font-size: 1.375em; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--gqssr-fg); } .gqssr-score-unit { margin-top: 0.125em; font-size: 0.625em; color: var(--gqssr-fg-3); } .gqssr\[data-level="high"\] .gqssr-ring-fg { stroke: var(--gqssr-high); } .gqssr\[data-level="medium"\] .gqssr-ring-fg { stroke: var(--gqssr-medium); } .gqssr\[data-level="low"\] .gqssr-ring-fg { stroke: var(--gqssr-low); } .gqssr\[data-level="info"\] .gqssr-ring-fg { stroke: var(--gqssr-info); } .gqssr\[data-level="clean"\] .gqssr-ring-fg { stroke: var(--gqssr-clean); } /\* ---------------------------------------------------------------- 概览统计 \*/ .gqssr-summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.5em; } .gqssr-stat { display: flex; flex-direction: column; align-items: center; gap: 0.125em; padding: 0.625em 0.25em; border-radius: 0.5em; background: var(--gqssr-bg-2); border: 1px solid var(--gqssr-line); min-width: 0; } .gqssr-stat-num { font-size: 1.125em; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.2; } .gqssr-stat-label { font-size: 0.75em; color: var(--gqssr-fg-3); white-space: nowrap; } .gqssr-stat--high { border-color: rgba(229, 72, 77, 0.32); } .gqssr-stat--high .gqssr-stat-num { color: var(--gqssr-high); } .gqssr-stat--medium { border-color: rgba(217, 138, 0, 0.34); } .gqssr-stat--medium .gqssr-stat-num { color: var(--gqssr-medium); } .gqssr-stat--low { border-color: rgba(59, 130, 246, 0.32); } .gqssr-stat--low .gqssr-stat-num { color: var(--gqssr-low); } .gqssr-stat--info .gqssr-stat-num { color: var(--gqssr-info); } .gqssr-struct { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375em 0.75em; font-size: 0.8125em; color: var(--gqssr-fg-3); } .gqssr-struct b { font-weight: 600; color: var(--gqssr-fg-2); } .gqssr-struct-label { font-weight: 600; color: var(--gqssr-fg-2); } /\* ---------------------------------------------------------------- 命中明细 \*/ .gqssr-findings { display: flex; flex-direction: column; gap: 0.5em; min-width: 0; } .gqssr-findings-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25em 0.625em; font-size: 0.875em; font-weight: 600; color: var(--gqssr-fg); } .gqssr-findings-head em { font-style: normal; font-weight: 400; font-size: 0.875em; color: var(--gqssr-fg-3); } /\* 区块标题:命中明细与后门特征排查共用(.gqssr-findings-head 是旧类名,保留兼容) \*/ .gqssr-sec-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25em 0.625em; font-size: 0.875em; font-weight: 600; color: var(--gqssr-fg); } .gqssr-sec-head em { font-style: normal; font-weight: 400; font-size: 0.875em; color: var(--gqssr-fg-3); } /\* ---------------------------------------------------------------- 按类别 \*/ /\* 把「风险项(参与评分)」与「加固建议 / 来源情报(不扣分)」分开摆, 报告读起来才是客观的 —— 后者不是缺陷,混在一起会让人以为问题很多。 \*/ .gqssr-cats { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375em 0.625em; font-size: 0.8125em; } .gqssr-cats-label { font-weight: 600; color: var(--gqssr-fg-2); } .gqssr-cats-list { display: flex; flex-wrap: wrap; gap: 0.375em; min-width: 0; } .gqssr-cat { display: inline-flex; align-items: baseline; gap: 0.25em; padding: 0.125em 0.5em; border-radius: 0.375em; background: var(--gqssr-bg-2); border: 1px solid var(--gqssr-line); color: var(--gqssr-fg-2); white-space: nowrap; } .gqssr-cat b { font-weight: 700; font-variant-numeric: tabular-nums; } .gqssr-cat i { font-style: normal; font-size: 0.875em; color: var(--gqssr-fg-3); } .gqssr-cat--risk { border-color: rgba(229, 72, 77, 0.32); } .gqssr-cat--risk b { color: var(--gqssr-high); } .gqssr-cat--harden { border-color: rgba(217, 138, 0, 0.34); } .gqssr-cat--harden b { color: var(--gqssr-medium); } .gqssr-cat--intel { border-color: rgba(139, 143, 163, 0.34); } .gqssr-cat--intel b { color: var(--gqssr-info); } .gqssr-cat-groups { display: flex; flex-direction: column; gap: 0.75em; min-width: 0; } .gqssr-cat-group { display: flex; flex-direction: column; gap: 0.375em; min-width: 0; } .gqssr-cat-group-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25em 0.5em; font-size: 0.8125em; font-weight: 600; color: var(--gqssr-fg-2); } .gqssr-cat-group-head i { font-style: normal; font-weight: 400; font-size: 0.875em; color: var(--gqssr-fg-3); } .gqssr-cat-group--risk .gqssr-cat-group-head span { color: var(--gqssr-high); } .gqssr-cat-group--harden .gqssr-cat-group-head span { color: var(--gqssr-medium); } .gqssr-cat-group--intel .gqssr-cat-group-head span { color: var(--gqssr-info); } /\* ---------------------------------------------------------------- 后门特征排查 \*/ /\* 未命中项也要逐条写出来:只列命中项的报告,读的人无法分辨 是「查过没发现」还是「压根没查」。 \*/ .gqssr-backdoor { display: flex; flex-direction: column; gap: 0.5em; min-width: 0; } .gqssr-bd-list { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.375em 0.625em; } .gqssr-bd-item { display: flex; align-items: center; gap: 0.375em; padding: 0.375em 0.5em; border-radius: 0.375em; background: var(--gqssr-bg-2); border: 1px solid transparent; font-size: 0.8125em; min-width: 0; } .gqssr-bd-item--clear { border-color: rgba(22, 163, 74, 0.22); } .gqssr-bd-item--hit { border-color: rgba(229, 72, 77, 0.38); background: rgba(229, 72, 77, 0.07); } .gqssr-bd-mark { flex: 0 0 auto; width: 1.125em; height: 1.125em; fill: none; stroke: var(--gqssr-clean); stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; } .gqssr-bd-mark path:first-child { fill: rgba(22, 163, 74, 0.14); } .gqssr-bd-item--hit .gqssr-bd-mark { stroke: var(--gqssr-high); } .gqssr-bd-item--hit .gqssr-bd-mark path:first-child { fill: rgba(229, 72, 77, 0.14); } .gqssr-bd-title { flex: 1 1 auto; min-width: 0; color: var(--gqssr-fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .gqssr-bd-state { flex: 0 0 auto; font-style: normal; font-size: 0.875em; color: var(--gqssr-clean); } .gqssr-bd-item--hit .gqssr-bd-state { color: var(--gqssr-high); font-weight: 600; } /\* 评分口径说明 \*/ .gqssr-basis { margin: 0; font-size: 0.75em; line-height: 1.6; color: var(--gqssr-fg-3); } .gqssr-hit-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 0.5em; } .gqssr-hit { position: relative; margin: 0; padding: 0.625em 0.75em 0.625em 1.125em; border-radius: 0.5em; background: var(--gqssr-bg-2); list-style: none; min-width: 0; overflow: hidden; } .gqssr-hit::before { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 3px; background: var(--gqssr-info); } .gqssr-hit--high::before { background: var(--gqssr-high); } .gqssr-hit--medium::before { background: var(--gqssr-medium); } .gqssr-hit--low::before { background: var(--gqssr-low); } .gqssr-hit--info::before { background: var(--gqssr-info); } .gqssr-hit-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25em 0.5em; min-width: 0; } .gqssr-hit-head strong { font-size: 0.875em; font-weight: 600; color: var(--gqssr-fg); } .gqssr-hit-head code { font-family: var(--gqssr-mono); font-size: 0.75em; padding: 0.0625em 0.375em; border-radius: 0.25em; color: var(--gqssr-fg-2); background: var(--gqssr-code-bg); word-break: break-all; } .gqssr-tag { font-size: 0.6875em; font-weight: 600; padding: 0.0625em 0.375em; border-radius: 0.25em; color: var(--gqssr-high); background: rgba(229, 72, 77, 0.12); } .gqssr-hit-desc { margin: 0.25em 0 0; font-size: 0.8125em; color: var(--gqssr-fg-2); } .gqssr-hit-code { display: block; margin: 0.375em 0 0; padding: 0.375em 0.5em; border-radius: 0.375em; background: var(--gqssr-code-bg); font-family: var(--gqssr-mono); font-size: 0.75em; line-height: 1.5; color: var(--gqssr-fg-2); white-space: pre-wrap; word-break: break-all; overflow-x: auto; max-width: 100%; } .gqssr-hit-fix { margin: 0.375em 0 0; font-size: 0.8125em; color: var(--gqssr-fg-2); } .gqssr-hit-fix b { font-weight: 600; color: var(--gqssr-primary); } /\* ---------------------------------------------------------------- 页脚 \*/ .gqssr-foot { font-size: 0.75em; line-height: 1.6; color: var(--gqssr-fg-3); padding-top: 0.75em; border-top: 1px dashed var(--gqssr-line); } /\* ---------------------------------------------------------------- 窄屏 \*/ @media (max-width: 767px) { .gqssr-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); } .gqssr-head { flex-direction: column; } .gqssr-score { align-self: flex-start; } /\* 窄屏下后门排查改成单列,8 项不至于挤成两行小字 \*/ .gqssr-bd-list { grid-template-columns: minmax(0, 1fr); } } 低风险 ### 源码安全检测报告 已检测 100/100 检测引擎 **srcscan/1.3-php**报告编号 **SC-20260922-E6FE3A**检测时间 **2026-09-22 10:22:23**内容发布 **2026-09-22 09:58:17**源码安全检测报告插件|瓜奇资源详情页自动出检测报告 0高危 4中危 0低危 0提示 结构概览文件 **9**体积 **214 KB**代码文件 **2**代码行 **3,632** 按类别来源情报 **2**_不扣分_ 后门特征排查_8 项特征全部未发现_ - 请求参数直接进入执行函数_未发现_ - 请求参数直接进入文件包含_未发现_ - 变量函数执行请求参数_未发现_ - 请求参数批量覆盖变量_未发现_ - 编码载荷后执行(混淆特征)_未发现_ - 回连裸 IP 地址_未发现_ - 配置预加载文件(隐蔽后门手法)_未发现_ - 向文件写入 PHP 代码_未发现_ 命中明细_共 4 项_ 来源情报_不扣分_ - **第三方二次打包 / 转发站标记**`manifest.json:1` 包内存在第三方源码站的引流文件、水印页或导流文案。说明这不是原厂原始包,而是被搬运方重新打包过。二次打包是投毒最高发的环节,且无法与官方包比对校验,因此来源可信度必须下调,交付前应逐文件核对。 ``` 第三方转发站标记 / 引流文件:manifest.json ``` **建议:**清掉第三方引流文件与标记文件,然后通读一遍被改动过的核心文件,确认除标记之外没有夹带别的改动。 - **数据库 / 配置被注入第三方站点信息**`manifest.json:1` 站点名称、描述或关键词里被写入了第三方源码站的品牌与域名。这是转发方在包内做 SEO 引流,装上去等于替别人做外链,且证明核心数据文件被改动过。 ``` {"schemaVersion":5,"id":"guaqi/src-scan-report","name":"源码安全检测报告","description":"内置 srcscan 源码安全检测引擎:文章发布时自动下载资源包、出报告并绑定标题与发布时间,在资源详情页展示评分、风险分级与命中明细。","version":"1.1.0","requires": … ``` **建议:**把被改写的站点信息改回自己的内容,并顺着同一批 INSERT / UPDATE 语句查出还有哪些字段被注入过。 - **第三方二次打包 / 转发站标记**`wordpress/plugin.php:2433` 包内存在第三方源码站的引流文件、水印页或导流文案。说明这不是原厂原始包,而是被搬运方重新打包过。二次打包是投毒最高发的环节,且无法与官方包比对校验,因此来源可信度必须下调,交付前应逐文件核对。 ``` 第三方转发站标记 / 引流文件:wordpress/plugin.php ``` **建议:**清掉第三方引流文件与标记文件,然后通读一遍被改动过的核心文件,确认除标记之外没有夹带别的改动。 - **第三方二次打包 / 转发站标记**`wordpress/scanner.php:522` 包内存在第三方源码站的引流文件、水印页或导流文案。说明这不是原厂原始包,而是被搬运方重新打包过。二次打包是投毒最高发的环节,且无法与官方包比对校验,因此来源可信度必须下调,交付前应逐文件核对。 ``` 第三方转发站标记 / 引流文件:wordpress/scanner.php ``` **建议:**清掉第三方引流文件与标记文件,然后通读一遍被改动过的核心文件,确认除标记之外没有夹带别的改动。 仅「风险项」参与评分,加固建议与来源情报只作呈现 本报告由 8号码库源码安全检测引擎(srcscan)静态扫描生成,用于上架前风险筛查,不构成安全保证。 **Tags:** 后门检测, 源码安全检测, 瓜奇插件 **Categories:** 插件模块 ---