I'm writing a personal wiki-style program in Python that stores text files in a user configurable directory.
The program should be able to take a string (e.g. foo
) from a user and create a filename of foo.txt
. The user will only be able to create the file inside the wiki directory, and slashes will create a subdir (e.g. foo/bar
becomes (path-to-wiki)/foo/bar.txt
).
What is the best way to check that the input is as safe as possible? What do I need to watch out for? I know some common pitfalls are:
../
\0
I realize that taking user input for filenames is never 100% safe, but the program will only be run locally and I just want to guard for any common errors/glitches.
You can enforce the user to create a file/directory inside wiki by normalizing the path with os.path.normpath and then checking if the path begins with say '(path-to-wiki)'
os.path.normpath('(path-to-wiki)/foo/bar.txt').startswith('(path-to-wiki)')
To ensure that the user's entered path/filename doesn't contain anything nasty, you can force the user to enter a path or filename to either of Lower/Upper Alpha, Numeric Digits or may be hyphen or underscore.
Then you can always check the normalized filename using a similar regular expression
userpath=os.path.normpath('(path-to-wiki)/foo/bar.txt')
re.findall(r'[^A-Za-z0-9_\-\\]',userpath)
To summarize
if userpath=os.path.normpath('(path-to-wiki)/foo/bar.txt')
then
if not os.path.normpath('(path-to-wiki)/foo/bar.txt').startswith('(path-to-wiki)')
or re.search(r'[^A-Za-z0-9_\-\\]',userpath):
... Do what ever you want with an invalid path
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With