diff --git a/docs/patterns/fileuploads.rst b/docs/patterns/fileuploads.rst index 1982fe3e..339e6b53 100644 --- a/docs/patterns/fileuploads.rst +++ b/docs/patterns/fileuploads.rst @@ -33,11 +33,7 @@ bootstrapping code for our application:: So first we need a couple of imports. Most should be straightforward, the :func:`werkzeug.secure_filename` is explained a little bit later. The ``UPLOAD_FOLDER`` is where we will store the uploaded files and the -``ALLOWED_EXTENSIONS`` is the set of allowed file extensions. Then we add a -URL rule by hand to the application. Now usually we're not doing that, so -why here? The reasons is that we want the webserver (or our development -server) to serve these files for us and so we only need a rule to generate -the URL to these files. +``ALLOWED_EXTENSIONS`` is the set of allowed file extensions. Why do we limit the extensions that are allowed? You probably don't want your users to be able to upload everything there if the server is directly @@ -108,8 +104,11 @@ before storing it directly on the filesystem. >>> secure_filename('../../../../home/username/.bashrc') 'home_username_.bashrc' -Now one last thing is missing: the serving of the uploaded files. As of -Flask 0.5 we can use a function that does that for us:: +Now one last thing is missing: the serving of the uploaded files. In the +:func:`upload_file()` we redirect the user to +``url_for('uploaded_file', filename=filename)``, that is, ``/uploads/filename``. +So we write the :func:`uploaded_file` function to return the file of that name. As +of Flask 0.5 we can use a function that does that for us:: from flask import send_from_directory diff --git a/docs/patterns/fileuploads.rst~ b/docs/patterns/fileuploads.rst~ new file mode 100644 index 00000000..1982fe3e --- /dev/null +++ b/docs/patterns/fileuploads.rst~ @@ -0,0 +1,190 @@ +.. _uploading-files: + +Uploading Files +=============== + +Ah yes, the good old problem of file uploads. The basic idea of file +uploads is actually quite simple. It basically works like this: + +1. A ``
+ ''' + +So what does that :func:`~werkzeug.utils.secure_filename` function actually do? +Now the problem is that there is that principle called "never trust user +input". This is also true for the filename of an uploaded file. All +submitted form data can be forged, and filenames can be dangerous. For +the moment just remember: always use that function to secure a filename +before storing it directly on the filesystem. + +.. admonition:: Information for the Pros + + So you're interested in what that :func:`~werkzeug.utils.secure_filename` + function does and what the problem is if you're not using it? So just + imagine someone would send the following information as `filename` to + your application:: + + filename = "../../../../home/username/.bashrc" + + Assuming the number of ``../`` is correct and you would join this with + the ``UPLOAD_FOLDER`` the user might have the ability to modify a file on + the server's filesystem he or she should not modify. This does require some + knowledge about how the application looks like, but trust me, hackers + are patient :) + + Now let's look how that function works: + + >>> secure_filename('../../../../home/username/.bashrc') + 'home_username_.bashrc' + +Now one last thing is missing: the serving of the uploaded files. As of +Flask 0.5 we can use a function that does that for us:: + + from flask import send_from_directory + + @app.route('/uploads/