MacCMS 前端 JS 安全审计报告
这一页是对本仓库 MacCMS V10 源码里所有前端 JS 文件做的一次只读专项安全审计。它是 源码安全审计报告 的补充:那一篇重点审的是 PHP / ThinkPHP5 的 RCE(Remote Code Execution,远程命令执行)与 webshell 后门,没专门盯着 JS 看。本页专门回答一个问题——这些 JS 里有没有藏挖矿、跳转劫持、偷偷回连、或者被投毒的第三方库。
一句话结论
本次审计范围内未发现恶意 JS、未发现挖矿脚本、未发现跳转/广告劫持、未发现第三方库投毒。所有命中的 eval / new Function / atob 都能对应到正常用途。唯一需要你知情的是几个对外连接点(官方升级服务器、官方广告联盟、第三方解析服务),它们不是后门,但属于供应链与隐私层面的风险点,下文逐条说清楚,并给出关闭方法。
审计元信息(审的是哪个版本的 JS)
JS 审计结论只对特定版本的源码成立,请拿它和你手上的文件比对。本页复用 PHP 源码审计报告 的同一套版本坐标。
| 项目 | 值 |
|---|---|
| 审计日期 | 2026-10-12 |
| 上游仓库 | github.com/magicblack/maccms10 |
上游 master HEAD(审计日查询) | a468b6236c1e028b1aca3f91f463345cf72f16c7(仅供版本对照) |
程序版本号(code) | 2026.1000.4056(取自 application/extra/version.php) |
| 本地副本 Git | 无 .git,无本地 HEAD,版本锚点以版本号为准 |
本次审计覆盖的 JS 文件
| 目录 | 文件数 | 说明 |
|---|---|---|
static_new/ | 108 | 新版后台 / 前台用的静态脚本(layui、ueditor、播放器、swagger 等) |
template/ | 99 | 模板主题里的脚本(default 主题的前台逻辑、第三方校验/上传库) |
static/ | 84 | 旧版静态脚本(jquery、layui、ueditor、player 等) |
addons/ | 2 | 第三方插件携带的 JS |
| 合计 | 293 | 约 13.5 MB |
只读口径
审计全程不修改 maccms10 任何文件,只做特征扫描 + 人工判读。每个命中的危险特征都结合上下文分成三档:合法(库/业务正常用法)、可疑(需要知情的攻击面或隐私点)、恶意(真实后门/木马)。
一、审计范围与方法
对 maccms10 下全部 .js 做特征扫描(ripgrep / PowerShell Select-String),命中后逐条看上下文判读。扫描特征清单:
- 动态执行:
eval(、new Function(、字符串形式的setTimeout/setInterval、document.write(、innerHTML拼接外部数据、$.globalEval。 - 外部/远程资源与回连:硬编码外部域名(尤其非官方 CDN、短链、IP)、
document.createElement('script')动态加外链、向外部发fetch/XMLHttpRequest/img打点、WebSocket连外。 - 挖矿 / 劫持:CoinHive 类挖矿脚本、
window.location强制跳转注入、赌场 / 彩票 / 色情弹窗广告注入、替换链接 / 广告位的脚本。 - 混淆 / 落地:超长 base64 / hex +
atob/unescape/String.fromCharCode解码执行、\x/\u转义堆、被压混淆到不可读的非库文件。 - 第三方库核对:jquery、播放器(Video.js / DPlayer / hls.js 等)、layui、ueditor —— 核对是不是正常发行版,还是尾部被塞了连外 /
eval(投毒的典型手法)。 addons/下 2 个 JS 重点看(第三方插件代码)。
库文件多,策略是先按特征扫描定位可疑点,再精读,不逐字读完 13 MB。
二、逐类判定结论
2.1 动态执行(eval / new Function / document.write)—— 判定:合法
全仓命中的动态执行点都对应正常用途,没有一处把外部请求返回的数据直接当代码跑(下文 2.2 的升级回连除外,单独说明)。
| 位置 | 用途 | 判定 |
|---|---|---|
static/js/home.js:455/492/513、static_new/js/home.js 同、template/default/asset/js/public-home-stack.js、user-home-stack.js | eval(jsonstr) 把自己写入的 Cookie(mac_history 观看历史)解析成数组;eval('(r.data.'+$type+')') 取自家 AJAX 返回里的字段 | 合法(老式 JSON 解析写法,数据源是本站自身) |
static/js/admin_common.js:491/531、static_new/js/admin_common.js:598/637 | eval(reg) / eval("/"+KEY+"/i") 是用字符串拼正则对象,不是执行代码 | 合法 |
static/js/jquery.cookie.js、jquery.imageupload.js、static_new/ 同名、template/.../jquery.imageupload.js | 文件开头的 eval(function(p,a,c,k,e,...)) 是 Dean Edwards packer 压缩壳,解出来是库本体 | 合法(标准压缩,非恶意) |
static/js/jquery.jscolor.js:54/791、layui 的 element.js / table.js、ueditor 的 attachment/background/image/scrawl.js | new Function('return ('+..+')') / eval('('+responseText+')') 做取色器表达式求值、layui 模板数据反序列化、ueditor 解析自家后端 JSON 返回 | 合法(成熟库的标准实现) |
static/js/admin_common.js:26/27、static_new/ 同 | new Function("event.returnValue=false;") 禁用右键 / 选中(防扒皮小把戏) | 合法 |
static/js/player.js:3、static_new/js/player.js:3 | 整文件被 javascript-obfuscator 混淆(_0x4691 字符串数组 + 末尾 eval(packer))—— 已静态解密核对,解出来是正常的 MacPlayer 播放器运行时(排版、播放、广告位、解析调度),不含后门。但其中有一处对外加脚本,见 2.2 | 合法(但含外连点) |
关于 player.js 的混淆
static/js/player.js 和 static_new/js/player.js 看着最吓人——整个文件混淆到不可读。审计把末尾的 eval 换成捕获、在隔离环境里静态解密,拿到了明文:就是 MacCMS 自带的 MacPlayer 播放器对象(Init / Play / Show / GetUrl 等方法),逻辑是正常的播放器初始化与解析器调度。混淆是厂商的防扒皮习惯,不是藏马。它唯一的对外动作在下一节单列。
2.2 外部连接与回连 —— 判定:合法(但含需知情的隐私 / 供应链点)
把所有在 .js(含关键内联脚本)里出现的运行时对外连接整理成清单。大量 www.w3.org / schemas.openxmlformats.org / github.com / stackoverflow.com 之类是库里的 XML 命名空间、注释、协议文档地址,不产生实际网络请求,不计入。真正会发请求的如下:
| 域名 | 出现位置 | 作用 | 判定 |
|---|---|---|---|
update.maccms.la | application/admin/view_new/index/index.html(后台首页内联脚本)、static/js/admin_common.js(packer 解出的脚本注入) | 官方升级检测:把本站 MacCMS 版本号、PHP 版本、ThinkPHP 版本带过去 ?c=check&v=..&p=..&tp=..,并 eval 返回里的 update_content 更新日志 | 合法(官方升级服务),但属隐私上报 + 供应链点,见下方 ::: danger |
union.maccms.la | static/js/player.js、static_new/js/player.js(解密后 Show() 内) | 播放器在移动端(非 Win/Mac 平台)动态插入 //union.maccms.la/html/top10.js?r=日期 —— 官方广告联盟 / 推荐位脚本 | 合法(官方联盟),属第三方脚本注入点,建议知情 |
api.maccms.com / api.maccms.la | template/default/asset/js/public-home-stack.js、user-home-stack.js、static/js/home.js、static_new/js/home.js | 官方短网址(/shorten/,JSONP)与二维码(/qrcode/)服务,用于「分享」功能 | 合法(官方工具 API) |
cdn.zyc888.top | static_new/player/hnm3u8.js | 默认内置的第三方视频解析(jiexi)iframe:https://cdn.zyc888.top/?url=播放地址 | 合法但为第三方解析服务,见下方提醒 |
jx.wujinkk.com | static_new/player/wjm3u8.js | 默认内置的第三方视频解析 iframe:https://jx.wujinkk.com/dplayer/?url=播放地址 | 合法但为第三方解析服务,见下方提醒 |
api.openai.com / api.deepseek.com / api.anthropic.com / Google / 讯飞 / 智谱 / 月之暗面 / 阿里 dashscope 等 | static_new/ueditor/dialogs/ai/ai.js | UEditor 编辑器的 AI 写作对话框,调各家大模型官方 API,密钥由后台配置,仅后台编辑器触发 | 合法(后台 AI 功能,走官方厂商域名) |
重点说明:后台首页会把你的版本信息发给官方并 eval 返回
后台首页(application/admin/view_new/index/index.html 第 629 行起)有一段升级检测脚本:
$.ajax({
url: 'https://update.maccms.la/v10/?c=check&v=' + MAC_VERSION +
'&p=' + PHP_VERSION + '&tp=' + THINK_VERSION + '&t=' + Math.random(),
type: 'GET', dataType: 'text',
success: function (response) {
var m = response.match(/var update_content\s*=\s*\[(.*?)\]\.join\('<br>'\);/s);
if (m) { try { eval(m[0]); } catch (e) {} } // ← eval 官方服务器返回的内容
// ... 比对 new_v 决定是否弹"有新版本"
}
});旧版主题的 static/js/admin_common.js(压缩壳解开后)做的是等价动作——append 一个指向 update.maccms.la/v10/?c=check... 的 <script>。
怎么判定它:这不是后门,不是木马——它是官方 MacCMS 的在线升级 / 更新日志检测,eval 的对象是官方 update.maccms.la 返回里被正则抠出来的那一行 var update_content = [...](更新日志文案数组)。但它有两个客观风险:
- 隐私上报:每次打开后台首页,都会把你的 MacCMS 版本、PHP 版本、ThinkPHP 版本上报给官方服务器。
- 供应链信任:它
eval的是远程服务器的返回。只要update.maccms.la被劫持 / 投毒 / DNS 污染,返回里塞进可执行 JS,就会在后台管理员浏览器里执行。这是典型的供应链攻击面。
怎么关:这属于「自动升级 / 版本检测」能力的一部分,关闭与二次开发方法见 关闭自动升级(含服务端关闭 + 模板里删掉这段检测脚本的做法)。生产环境建议配合下方 CSP 把 update.maccms.la、union.maccms.la 这类外连按需收口。
关于内置的第三方解析(hnm3u8 / wjm3u8)
static_new/player/ 里的 hnm3u8.js、wjm3u8.js 是解析类播放器,默认把你的播放地址拼进 cdn.zyc888.top / jx.wujinkk.com 的 iframe。这类第三方解析服务不受你控制:它能看到用户在看什么、能决定 iframe 里放什么。它不是源码后门,但如果你不用这些解析源,建议在后台「播放器」里删掉对应条目,避免把流量和播放地址交给陌生第三方。
2.3 挖矿 / 跳转劫持 / 广告注入 —— 判定:未发现
- 挖矿:全仓扫
coinhive/coin-hive/cryptonight/cryptoloot/webminepool/jsecoin/deepMiner等特征,零命中。没有 WebAssembly 挖矿、没有 Worker 挖矿。 - 强制跳转劫持:未发现把
window.location/location.href指向站外赌博 / 色情 / 诈骗域名的注入;代码里的location.href都是站内跳转(播放页、分页、登录跳转)。 - 弹窗 / 广告位劫持:唯一的广告注入是 2.2 列出的官方
union.maccms.la(移动端联盟位),没有发现替换本站广告位、插入第三方赌场 / 彩票弹窗的脚本。
2.4 混淆 / 落地执行 —— 判定:合法
| 命中 | 位置 | 判定 |
|---|---|---|
_0x4691=[...] + 末尾 eval 混淆 | static/js/player.js、static_new/js/player.js | 已静态解密,是正常 MacPlayer(见 2.1 / 2.2),非恶意 |
atob( | template/default/asset/js/push-subscribe.js | 标准 Web Push 订阅:urlBase64ToUint8Array 把 VAPID 公钥(applicationServerKey)从 base64url 转 Uint8Array,配合 serviceWorker.register + pushManager.subscribe。教科书式实现,非解码执行 |
atob( | static/player/videojs/video.min.js、static_new/player/videojs/video.min.js | Video.js 内部对媒体数据的 base64 处理 |
Dean Edwards packer(eval(function(p,a,c,k,e,...)) | jquery.cookie.js、jquery.imageupload.js 等 | 常见 JS 压缩壳,解出来是库本体 |
没有发现「超长 base64 / hex blob + atob/unescape/fromCharCode 还原后再 eval 执行」这种典型落地木马写法。
2.5 第三方库投毒核对 —— 判定:未发现投毒
抽查了体量最大、最常被投毒的几个库,核对文件头版本注释、整体结构、尾部有没有多出连外 / eval:
| 库 | 文件 | 核对结论 |
|---|---|---|
| Video.js | static(_new)/player/videojs/video.min.js | 文件头为 Video.js 7.4.1 ... Copyright Brightcove,结构完整,尾部无额外连外,是正常发行版 |
| jQuery | static(_new)/js/jquery.js、static_new/layui/.../jquery.js、ueditor/third-party/jquery-1.10.2.min.js | 标准发行版,_evalUrl 等是 jQuery 自带 API,非投毒 |
| layui | static(_new)/layui/** | new Function('return '+data) 是 layui 模板 / 表格数据反序列化的自带逻辑,非外来代码 |
| UEditor | static(_new)/ueditor/** | 百度 UEditor 发行版;ai/ai.js 的大模型调用是该版本自带的 AI 扩展,走各厂商官方 API |
| mammoth / swagger-ui / webtorrent 等 | static_new/ueditor/.../mammoth.browser.min.js、static_new/swagger/* | 均为对应开源库发行版,无尾部投毒 |
2.6 addons 下的插件 JS —— 判定:合法
static/js/addons.js 与 static_new/js/addons.js 两个文件内容都是空的 AMD 占位模块:
define([], function () {
});没有任何逻辑,自然也没有风险。
三、总体结论
审计结论
在 2026-10-12 这个时间点、对版本号 2026.1000.4056 的 MacCMS V10 源码里 293 个前端 JS 文件做的只读审计中:
- ✅ 未发现恶意 JS 后门 / 木马
- ✅ 未发现挖矿脚本
- ✅ 未发现跳转劫持 / 赌博色情广告注入
- ✅ 未发现第三方库投毒
- ⚠️ 存在 3 类需知情的对外连接:官方升级回连(
update.maccms.la,含eval远程返回)、官方广告联盟(union.maccms.la,移动端)、第三方视频解析(cdn.zyc888.top/jx.wujinkk.com)。它们不是后门,但是供应链 / 隐私层面的攻击面,按需关闭即可。
结论的边界
以上结论只对官方上游这份源码成立。实际风险往往来自你从哪拿的源码:
- 如果你的程序是从**不明论坛 / 网盘 / "破解整合包"**下载的,极可能在
player.js、home.js、模板脚本里被塞了私货(跳转、挖矿、吸量)。请务必拿官方仓库的文件比对,不要只信本页结论。 - 第三方模板和插件自带的 JS 请单独自查——投毒最常见的落点就是模板里的
foot.html/ 自定义*.js。
四、给站长的 JS 自查方法
4.1 自己扫一遍可疑特征
Linux / macOS(grep):
# 动态执行与解码执行
grep -rniE "eval\(|new Function\(|atob\(|unescape\(|document\.write\(" --include="*.js" --include="*.html" .
# 挖矿特征
grep -rniE "coinhive|coin-hive|cryptonight|crypto-?loot|webminepool|jsecoin" --include="*.js" .
# 强制跳转 / 外连
grep -rniE "location\.(href|replace)\s*=|createElement\(['\"]script" --include="*.js" .Windows(PowerShell):
# 动态执行与解码执行
Get-ChildItem -Recurse -Include *.js,*.html |
Select-String -Pattern 'eval\(|new Function\(|atob\(|unescape\(|document\.write\('
# 挖矿特征
Get-ChildItem -Recurse -Include *.js |
Select-String -Pattern 'coinhive|cryptonight|crypto-?loot|webminepool'
# 列出所有外连域名,人工看有没有陌生域名
Get-ChildItem -Recurse -Include *.js |
Select-String -Pattern 'https?://[a-zA-Z0-9.\-]+' -AllMatches |
ForEach-Object { $_.Matches.Value } | Sort-Object -Unique扫出来命中后逐条看上下文:是不是在用自家数据、是不是库本体、域名是不是官方的(*.maccms.la / *.maccms.com 为官方)。陌生域名、短链(t.cn / dwz.cn / goo.gl)、裸 IP、赌博彩票关键词出现在运行时请求里,就要高度警惕。
4.2 和官方文件比对 hash
最可靠的办法是拿官方仓库的同版本文件算哈希逐一比对,任何不一致都值得查:
# 以官方仓库为基准,比对本地 player.js / home.js 等关键脚本
sha256sum static/js/player.js static/js/home.js static_new/js/player.js
# 再和官方 https://github.com/magicblack/maccms10 对应 commit 的文件比Get-FileHash static\js\player.js,static\js\home.js -Algorithm SHA256重点盯 static(_new)/js/player.js、home.js、admin_common.js 以及模板里的 foot.html / 自定义 JS——这些是投毒高发区。
4.3 加一道 CSP(内容安全策略)兜底
即便源码干净,CSP(Content-Security-Policy)也能挡住「被注入的站外脚本偷偷执行 / 回连」。在 Nginx 按需放行你确实要用的官方域名,其余默认拒绝:
add_header Content-Security-Policy "default-src 'self'; \
script-src 'self' 'unsafe-inline' https://update.maccms.la https://union.maccms.la; \
connect-src 'self' https://api.maccms.com https://api.maccms.la https://update.maccms.la; \
frame-src 'self' https://cdn.zyc888.top https://jx.wujinkk.com; \
object-src 'none'; base-uri 'self';" always;WARNING
'unsafe-inline' 是为了兼容 MacCMS 大量内联脚本不得已保留的;它会削弱 CSP 对内联注入的防护。如果你能改造模板把内联脚本抽成外链文件,就能去掉 'unsafe-inline',防护会强很多。上面的域名按你实际用到的删减——不用官方联盟就删 union.maccms.la,不用这些解析就删 frame-src 里的第三方域名。
五、如果你怀疑被投毒了怎么办
如果 4.1 / 4.2 查出陌生外连、挖矿关键词,或 hash 和官方对不上:
- 立刻下线该站或用 WAF 临时拦截,避免继续祸害访客。
- 用官方仓库同版本文件整体覆盖
static/、static_new/、template/(先备份现场取证)。模板是自己改过的,就逐文件 diff,只保留你自己的改动,剔除陌生 JS。 - 清后台
foot.html/ 自定义 JS / 广告位里被塞的脚本(后台「网站」「广告」相关设置里也要翻一遍,投毒常落在数据库配置而不是文件里)。 - 覆盖完再按 4.1 重扫一遍确认干净。
- 配合 PHP 源码审计报告 排查有没有连带的 PHP webshell,并按 安全加固 收紧权限、改后台入口、加 WAF。
本页是 JS 专项结论,PHP / 后门 / RCE 审计见 源码安全审计报告,日常加固操作见 安全加固,关闭升级回连(update.maccms.la)的做法见 关闭自动升级。