Consider the following security problem:
I have a static base path ( /home/username/
) to which I append a user-controlled sub-path (say foo/bar.txt
). The content of this file is then read and presented to the user.
In the case described the full path would be: /home/username/foo/bar.txt
Now to the problem. I want to control so that the full path is always a subdirectory of the static base path. In other words I don't want the user to supply a path such that the base path is escaped.
The following full path is OK:
/home/username/foo/bar.txt
Whereas this one is one is clearly not safe:
/home/username/foo/../../../etc/passwd
To complicate matters further the proper solution of chroot:ing to the base path is not available. Due to various reasons the only available solution is to use a regexp to differentiate between safe and unsafe paths.
Please note:
/
. You can simply reject any user input that matches /(^|\\/)\\.\\.(\\/|$)/
That means: if it contains /../
or begins with ../
or ends with /..
or is ..
If you don't want to reject it outright, just strip any "../" from the path, like this :
sed -e 's/\..\///g'
You should be aware that there could be files in the directory hierarchy that you allow that are linked to directories outside of that hierarchy.
Without using chroot I don't think there is a way that you can guarantee for it to be totally safe.
I believe it can't be done using just one single regexp. Regexps can't count anything, while here you definitely need to count the number of ../
However, you may try using recursive regexps and check for recursive nesting of ([[:alpha:]]+/..), like [[:alpha:]]+(\\R)|..
I agree that it is better to forbid ../ at all
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.