上传的文件怎么确认它真是图片?扩展名和 Content-Type 能信吗?校验到什么程度才算够?这篇只验证防御端:拿一份朴素实现和一份校验内容的实现,用各种「像又不像」的文件逐个对照,还记录了我自己代码里一个会误拒中文文件名的缺陷。
真正的 PNG,x.png,image/png → 200 {"accepted": true, "client_mimetype": "image/png", "name": "x.png"}
纯文本,x.png,声明 image/png → 200 {"accepted": true, "client_mimetype": "image/png", "name": "x.png"}
纯文本,X.PNG,声明 image/png → 200 {"accepted": true, "client_mimetype": "image/png", "name": "X.PNG"}
真正的 PNG,x.txt,image/png → 400 {"accepted": false}上一篇:路径穿越与文件下载;下一篇:Host Header 校验。
真正的 PNG → 200 {"original": "photo.png", "saved_as": "49fda2d0cad242aca0c7a35d04e53666.png", "size": 74}
真正的 JPEG,扩展名 jpeg → 200 {"original": "p.jpeg", "saved_as": "64811b8bf522417790e234373204c7ef.jpg", "size": 633}
纯文本冒充 PNG → 400 {"error": "文件内容不是允许的图片类型"}
PNG 内容,扩展名写成 jpg → 400 {"content": "png", "error": "扩展名与内容不一致", "ext": "jpg"}
PNG 签名 + 后面是垃圾 → 400 {"detail": "OSError", "error": "图片无法解析"}
扩展名不在白名单 → 400 {"error": "扩展名不允许", "ext": "svg"}
没有扩展名 → 400 {"error": "扩展名不允许", "ext": ""}
文件名含路径与空格 → 200 {"original": "my_pic.png", "saved_as": "ba3ff713f92743be81e16d723dce9063.png", "size": 74}
中文文件名 → 400 {"error": "扩展名不允许", "ext": ""}
磁盘上保存的文件: ['49fda2d0….png', '64811b8b….jpg', 'ba3ff713….png'] (名字是随机的 uuid,不是用户给的)
没有 f 字段 → 400 {"error": "没有文件"}上传约 100 KB → 200 上传约 199 KB → 200 上传约 201 KB → 413 上传约 1000 KB → 413
被截断的 PNG(签名与头部完整,数据缺失) → 400 {"detail": "UnidentifiedImageError", "error": "图片无法解析"}本篇是防御向的验证:没有构造任何恶意文件,「冒充」用的是一段普通文本。