UTF-8有效文件名的正则表达式

6
我正在尝试处理用户上传的文件名。我希望支持所有有效的 UTF-8 字符,但不包括那些可能会对 HTML 网页显示、CLI 接口访问或文件系统存储和检索造成问题的字符。
无论如何,我想到了以下宽松的函数,并且想知道是否足够安全以供使用。我对所有数据库查询使用预处理语句,并且我始终对输出进行 html 编码,但我仍然希望知道这也是一个经过深思熟虑的方法。
// $filename = $_FILES['file']['name'];

$filename = 'Filename 123;".\'"."la\l[a]*(/.jpg
∮ E⋅da = Q,  n → ∞, ∑ f(i) = ∏ g(i), ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β),
  ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (A ⇔ B),
  2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm
sfajs,-=[];\',./09μετράει
าวนั้นเป็นชน
Καλημέρα κόσμε, コンニチハ
()_+{}|":?><';


// Replace symbols, punctuation, and ASCII control characters like \n or [BEL]
$filename = preg_replace('~[\p{S}\p{P}\p{C}]+~u', ' ', $filename);

这种方法对我来说安全吗?我的用户是否适用?

更新

澄清一下,我不使用文件名作为文件系统上的文件名。我生成一个唯一的哈希值并使用它 - 我只需要保存原始名称,因为这是他们识别文件的方式。对于他们来说,SHA1哈希或UUID毫无意义。


这实际上太过激进了。而且大部分这些字符都是由于提供下载的东西本身存在问题。 - Ignacio Vazquez-Abrams
你可以将文件名保存在数据库中,并将上传的文件名设置为记录ID。我认为这是最好的方法。你可以通过.htaccess文件或header函数以相同的名称下载文件。 - Mahoor13
1个回答

2
第一件事情是检查你的输入是否是UTF-8。 mb_internal_encodingmb_check_encoding会帮到你。
你正在使用黑名单,但使用允许输入的白名单是良好的安全实践。 澄清后编辑: 你应该是安全的。记得过滤LmNo,如果你不想召唤Zalgo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接