用于在Linux环境中构建类似chroot的路径的Regexp
考虑以下安全问题: 我有一个静态基本路径(用于在Linux环境中构建类似chroot的路径的Regexp,regex,linux,security,language-agnostic,Regex,Linux,Security,Language Agnostic,考虑以下安全问题: 我有一个静态基本路径(/home/username/),在其中附加一个用户控制的子路径(比如foo/bar.txt)。然后读取此文件的内容并将其呈现给用户 在所描述的情况下,完整路径为:/home/username/foo/bar.txt 现在来谈谈问题。我想要控制,使完整路径始终是静态基本路径的子目录。换句话说,我不希望用户提供一个路径,这样基本路径就被转义了 以下完整路径正常: /home/username/foo/bar.txt 鉴于这是一个明显不安全的: /home
/home/username/
),在其中附加一个用户控制的子路径(比如foo/bar.txt
)。然后读取此文件的内容并将其呈现给用户
在所描述的情况下,完整路径为:/home/username/foo/bar.txt
现在来谈谈问题。我想要控制,使完整路径始终是静态基本路径的子目录。换句话说,我不希望用户提供一个路径,这样基本路径就被转义了
以下完整路径正常:
/home/username/foo/bar.txt
鉴于这是一个明显不安全的:
/home/username/foo/../../../etc/passwd
使问题进一步复杂化的是,chroot:ing到基本路径的正确解决方案不可用。由于各种原因,唯一可用的解决方案是使用regexp来区分安全路径和不安全路径
鉴于上述问题,什么是合适的regexp
请注意:
- 代码将在Linux下运行。因此,路径分隔符为
/
- 这个问题完全与语言无关
- 请不要建议其他解决问题的方法。我知道有其他更好的方法来解决这个问题(比如chroot:ing),但这个问题仅限于regexp解决方案
/(^ |\/)\.\.\.\(\/|$)/
这意味着:如果它包含
/../
或以./
开头,或以/..
结尾,或是。
,我相信单用一个regexp是做不到的。Regexps不能计算任何东西,而在这里您肯定需要计算/
但是,您可以尝试使用递归regexp并检查([[:alpha:]+/…)的递归嵌套,如[[:alpha:]+(\R)|
我同意最好是完全禁止../如果你不想直接拒绝它,只需从路径中删除任何“./”,如下所示:
sed -e 's/\..\///g'
您应该知道,目录层次结构中可能存在允许链接到该层次结构之外的目录的文件
如果不使用chroot,我认为没有一种方法可以保证它是完全安全的。不存在与语言无关的正则表达式。您使用的是什么regex实现?并非所有PCRE的regex风格都是相同的。您使用的是什么编程语言?巴特:如果您的答案恰好取决于使用的是哪种PCRE regex风格(可能性很小),那么请说明这一假设。但您必须确保,您在“/home/username/”前面加了前缀,否则
~/something
或/var/log
将导致问题。