Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I securely pass an arbitrarily deep path to a webapp (Flask, in this case)?

I have a form that sends a string to my Flask app when the form is posted. The string is a filepath, so I'd like to make sure it doesn't contain anything nasty, like ../../../etc/passwd. Werkzeug, which Flask uses, has a handy function called secure_filename that strips nasty stuff out of filenames. Unfortunately, when fed a full path like templates/example.html, it converts the / to _, so we end up with templates_example.html.

It seems sensible, then, to split the path up into levels, so I send templates and example.html separately and then join them together again on the server. This works great, except that the path can be arbitrarily deep. I could just string together dir1/dir2/dir3/dir4 and hope that nobody every goes deeper than dir4, but that seems dumb.

What's the right way to handle validation of paths of unknown depth? Validate differently? Send the data differently? Encode the path differently, then decode it on the server?

like image 753
pingswept Avatar asked Aug 15 '11 19:08

pingswept


People also ask

How do you protect a route in Flask?

You will need to protect the page and then access the user's data to get the name . To protect a page when using Flask-Login, add the @login_requried decorator between the route and the function.

Which two are the default addresses of a Flask website?

Flask launches its built-in developmental web server and starts the webapp. You can access the webapp from a browser via URL http://127.0.0.1:5000 (or http://localhost:5000 ).

Where can I deploy Flask app for free?

You can deploy a Flask application on Render in just a few clicks. A sample app for this quick start is deployed at https://flask.onrender.com. The code uses Gunicorn to serve your app in a production setting.


1 Answers

For situations like this Flask has safe_join which raises 404 if a user attempts to leave the path:

>>> safe_join('/foo/bar', 'test')
'/foo/bar/test'
>>> safe_join('/foo/bar', 'test/../other_test')
'/foo/bar/other_test'
>>> safe_join('/foo/bar', 'test/../../../etc/htpassw')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mitsuhiko/Development/flask/flask/helpers.py", line 432, in safe_join
    raise NotFound()
werkzeug.exceptions.NotFound: 404: Not Found
like image 165
Armin Ronacher Avatar answered Sep 21 '22 15:09

Armin Ronacher