发布于2026-07-12 阅读(0)
扫一扫,手机访问
文件上传后立刻算个哈希值,这事儿在安全防篡改的场景下越来越常见。但很多开发者容易掉坑里——要么算了但没存对地方,要么存了但从来没验过。下面几个判断,应该能帮你省掉一些不必要的踩坑经历。
上传完成不代表文件可信。服务端必须从临时文件路径重新算一遍,而不是直接对$_FILES数组或前端提交的表单名字做哈希——那不靠谱,那些只是元信息。
这里有个容易被忽略的细节:必须用临时文件的实际物理路径来参与计算。$file->getRealPath()拿到的才是真正的存档位置,而不是什么表单字段名或者内容流。
hash_file('sha256', $file->getRealPath()),对大文件很友好,不占内存file_get_contents()加hash()的组合,文件超过2MB很可能触发内存限制甚至超时md5_file()或sha1_file(),但安全性远不如SHA-256Hash值必须和业务数据强关联,不然就等于白算。常见错误是只存了一个哈希字符串,但没同时记录文件ID、上传用户、时间戳,后期想追溯上下文时根本对不上号。
比较稳妥的做法是在模型层统一处理:上传成功后,把hash、original_name、size、user_id这些字段一起写入附件表(比如叫attachment),而不是塞进JSON字段或者单独的配置文件里。
CHAR(64)(SHA-256)或CHAR(32)(MD5),并且加上索引,方便查重Db::table('attachment')->where('hash', $hash)->find()判断一下是否已经存在。这不强制,但能省带宽,杜绝重复上传有些方案会让前端先算好Hash,随表单一起提交,服务端拿来比对。听起来像是在入口处提前拦截了问题,但实际风险很大:用户能伪造任意Hash值,而且Ja vaScript计算大文件时很容易卡死或出现精度丢失(比如Blob.slice的精度问题在部分场景下并不可靠)。
只有在可信内网环境、同时前端SDK被强管控的情况下,才值得考虑这种模式。生产环境里,建议默认忽略客户端传来的file_hash字段,一切以服务端重算为准。
check_hash => true,并在控制器中明文对比:if ($clientHash !== hash_file('sha256', $file->getRealPath())) { throw new Exception('Hash mismatch'); }FileReader.readAsArrayBuffer,前端算Hash本身就不稳定,别指望它Hash校验不是只做一次的“一次性买卖”。服务器迁移、磁盘故障、甚至误删重传,都可能导致文件内容发生变化,必须要有定期抽检或全量扫描的机制。
写个简单的命令行脚本就能搞定:php think repair:hash --path=public/uploads/ --ext=pdf,docx,遍历目录,和数据库中记录的Hash值逐对比对。
is_writable()检查,或者用flock()避免读到半截内容corrupted,同时禁止前端访问该记录,而不是直接删除filemtime)判断文件是否变更——它可能被touch重置,而且不反映内容的真实差异最容易忽略的一点是:Hash值本身并没有做防篡改保护。如果攻击者能写数据库,他就能同步改掉Hash字段。所以对于关键文件,建议额外加一道签名——比如用私钥对file_id . hash做HMAC-SHA256,校验时一并验证签名的有效性。这样才能真正形成闭环。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8