允许在目录中访问文件的安全字符

问题描述:

我有一个PHP脚本,它允许用户通过指定文件名来删除目录中的某些文件(通过下拉菜单 - 但对于恶意更改的人来说这很容易) 。我“清洗”通过执行以下操作允许在目录中访问文件的安全字符

if(preg_match(/'/^[a-zA-Z0-9.]$/'/,$file)) { 
    # do stuff to this particular file 
} 

我相当肯定应该阻止任何人起床到什么讨厌的文件名,但这里的人有大量的知识更多的话,我,我想我会问 - 这里有没有一个洞,还是这会让这种讨厌的东西消失?

我不确定你的正则表达式是否真的有帮助:在该范围之外有有效的字符,你将无法以这种方式删除。

我要做的一件事是在完整的最终路径上执行realpath(),并检查它是否仍然是允许的文件路径的子项。这将阻止../../目录遍历攻击,即使它们使用了一些特殊字符。这应该已经提供了相当好的安全性。

您还可以额外使用扫描​​3210目录和检查结果看,所请求的文件是否确实是在那里(那是不可能的,即使是最偷偷摸摸的目录遍历规避。)

如果你想对此,你可以完全使用另一种方法:不要传输文件名,而是列出你以前指定的列表索引。例如,如果你表明这个名单的用户,并将其保存在临时文本文件或数据库记录:

  1. 的Readme.txt
  2. 许可证
  3. 的Readme.doc

,然后通过只有文本文件或数据库记录的(随机)ID以及要删除的文件的编号:

delete.php?list=xasdafdas&index=3 

you shou对于任何可能的注入和文件名称篡改,ld都有一个无懈可击的解决方案。

您将不得不为每个请求存储单个列表,因为这些文件可能会更改。

+0

我只是担心他们离开那个目录。该目录中的任何内容都是公平的游戏,这些文件只能有a-z,A-Z,0-9和。在文件名中。我想知道如果我只允许这些角色出现在目录中或者破坏真正的破坏时,是否还有一些巧妙的方式。但是,是的,我同意,检查提交的文件名与我想允许删除的文件可能是最安全的。 – Will 2011-01-10 01:53:56

也许你应该改变你的正则表达式中

if(preg_match(/'/^[^a-zA-Z0-9.]+$/'/,$file)) { 
# do stuff to this particular file 
} 
+0

是的,我有regEx错误(所以你实际上)应该是:`/^[a-zA-Z0-9。] + $ /`但问题仍然存在 - 有人仍然可以做一些令人讨厌的那些有效的字符? – Will 2011-01-10 01:37:30

如果你的文件名不是绝对路径,而你总是前缀的目录路径

chdir(...); // change directory to that directory 

// make use the $file is not contains '/' 
$file = basename($file); 

// check $file is not in list of files that you don't allow for delete 
if ($file=='index.php' ...) 
{ 
    // do nothing 
    return false; 
} 


if (is_file($file)) 
{ 
    unlink($file); // or other actions 
} 

这正则表达式匹配几乎任何东西。你的意思是/^[a-zA-Z0-9.]/而不是?这仍然会匹配../../../etc/shadow之类的东西。 /^[a-zA-Z0-9.]+$/(或者简单地/^[\w\d.]+$/)更好,或者您可以根据您创建的下拉列表检查文件名。