先看现象。用户上传的图片带着相机写入的 EXIF,既有拍摄地经纬度也有设备序列号,入库前只用 Pillow 转了一次 JPEG,元数据原样保留,安全审计直接在对象存储里抽出了完整坐标。
把日志和配置对完,能解释这个现象的基本就这几处。转码只改像素,没有清空 EXIF 段。也可能是缩略图里还留着原始元数据的副本。
少数情况下是上传接口按扩展名校验,不解析文件内部结构。
不容易想到的是,CDN 缓存的原始文件也被直接公开。
动手时先读一张图的 EXIF 看有哪些字段
python -c "from PIL import Image;im=Image.open('a.jpg');print(dict(im.getexif()))"
随后重新保存时把元数据全部去掉
python -c "from PIL import Image;Image.open('a.jpg').save('a_clean.jpg',quality=88,exif=b'')"
接着用 exiftool 复核输出是否还有 GPS
exiftool -GPS:all -SerialNumber a_clean.jpg
等前面都确认过,再在上传链路加一步统一清洗
python sanitize_upload.py --dir uploads --strip exif,gps --dry-run
怎么算真的好了,看的是同一批现象。抽查一百张已入库图片,GPS 与序列号字段全部为空,图片仍可正常预览,尺寸和色彩没有变化。
转码不等于脱敏,元数据会跟着文件走,上传入口统一重写图像比事后扫对象存储可靠。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
