前言

本教程基于https://github.com/FuRuiORG/ZJMF-noupstream编写

魔方财务系统(ZJMF)存在一个安全漏洞:/api/pr......接口会返回 upstream_product_shopping_url 等上游敏感信息。

本补丁功能特性

精准拦截-自动识别并隐藏15个上游敏感字段
零配置-即插即用,消耗修改业务代码
覆盖全局-基于输出缓冲,拦截所有JSON响应
深度清理- 梯度下降数据结构
兼容压缩-自动处理Gzip/Deflate压缩响应
性能-轻量级实现,对性能影响<1ms
安全可靠-不影响正常业务逻辑

开始实践

方法一:直接复制(推荐)

点击下载配置好的0-index.php文件,包含完整的拦截器导入代码,修改文件名为


index.php
  1. 复制 upstream_hide.php (点击文字下载) 到项目根目录
    image.png

2.用刚刚下载并且改名的index.php替换掉你的public下的index.php
image.png

注意: 替换前请备份原有的 public/index.php 文件

方法二:手动修改

如果需要保留原有 index.php 的自定义配置,可以手动添加代码:
your-zjmf-installation/
├── app/
├── public/
│   └── index.php          ← 修改此文件
├── upstream_hide.php      ← 新增此文件
├── data/
└── ...
  1. upstream_hide.php 放置在魔方财务系统根目录:
    image.png
  2. 编辑 public/index.php,在 require base.php 后 添加一行代码:
    image.png
// 加载基础文件
require CMF_ROOT . 'vendor/thinkphp/base.php';

// 加载上游信息隐藏拦截器 (ZJMF-noupstream)
require CMF_ROOT . 'upstream_hide.php';  // ← 新增这行

// 执行应用并响应
Container::get('app', [APP_PATH])->run()->send();

image.png

Step 3: 验证安装
访问任意产品详情API,检查返回数据:
预期结果

{
  "api_type": "normal",
  "upstream_pid": 0,
  "upstream_product_shopping_url": null
}

技术原理

image.png

压缩处理机制

针对服务器开启Gzip压缩的场景:

function upstreamHideTryDecompress($buffer) {
    // 检测Gzip格式 (0x1f 0x8b)
    if ($b0 === 0x1f && $b1 === 0x8b) {
        return @gzdecode($buffer);
    }
    
    // 检测Zlib格式 (0x78 0x01/5e/9c)
    if ($b0 === 0x78 && ...) {
        return @gzuncompress($buffer);
    }
    
    // PHP版本兼容处理
    if (version_compare(PHP_VERSION, '7.4', '<')) {
        // PHP 7.2-7.3: 使用inflate_init (如果可用)
        return @inflate_add(@inflate_init(...), $buffer);
    } else {
        // PHP 7.4+: 直接使用gzinflate
        return @gzinflate($buffer);
    }
}

常见问题

Q1: 是否会影响网站性能?

答: 影响极小。性能损耗主要来自:

JSON解析:< 0.5ms
数组遍历:< 0.3ms(取决于数据量)
重新编码:< 0.2ms
总耗时 < 1ms,对用户体验无感知影响。

Q2: 会影响非API请求吗?

答: 不会。脚本会智能检测:

仅处理 {...} 或 [...] 格式的JSON响应
自动跳过HTML页面、图片、CSS/JS静态资源
如果响应不是有效JSON,原样返回不做任何修改

Q3: 如何临时禁用?

答: 注释掉 public/index.php 中的引入行即可:


// require CMF_ROOT . 'upstream_hide.php';  // 临时禁用

要用的时候删除注释就可以了

Q4: 能否自定义要隐藏的字段?

答: 可以!编辑 upstream_hide.php 中的两个配置数组:

// 添加新的隐藏字段
$upstreamHideFields[] = 'your_custom_field';

// 定义替换值
$upstreamReplaceValues['your_custom_field'] = 'safe_value';

Q5: 支持哪些API接口?

答: 由于基于全局输出缓冲,理论上支持所有返回JSON的接口,包括但不限于:

/api/product/prodetail - 产品详情
以及其他所有API端点

Q6: 数据库中的原始数据会被修改吗?

答: 不会。本工具仅在输出层进行拦截,不修改任何数据库记录或源代码逻辑。停止使用后,系统完全恢复原状。

致谢

-感谢魔方财务(ZJMF)团队提供的优秀主机销售系统
-感谢所有贡献者和使用者
-感谢开源社区的反馈和建议
-感谢FuRuiORG