Skip to content Skip to sidebar Skip to footer

Flask Url Parameters With % Are Not Properly Handled

EDIT2: I apologize for the lack of clarity. I will provide several values. The first is the URL that I call using my frontend app. The second is the value before calling urllib.unq

Solution 1:

No, Flask is usually handling percent encoding exactly right. Parameters in a URL are percent encoded, and these are decoded for you when the WSGI environment is set up. Flask then passes this on to your route when matching.

You do not need to decode the parameter value again, remove your urllib.unquote() call.

Your browser will actually encode spaces in the URL to %20 for you, even though the location bar will show a space. The location bar decodes percent-encoded components to make it possible to read international characters (so %E3%81%A9%E3%81%86%E3%82%82%E3%81%82%E3%82%8A%E3%81%8C%E3%81%A8%E3%81%86 is shown as どうもありがとう, for example).

If you are having issues with encoded slashes (/, %2F), then see issue #900, there are edge cases with Apache directives (and other WSGI servers) to consider. You would need to use a <path:param> component to match those, because the default string parameter type will not match slashes.

If I use the following test script, named routetest.py:

from flask import Flask
try:
    from urllib.parse import unquote  # PY3except ImportError:
    from urllib import unquote  # PY2

app = Flask(__name__)

@app.route('/v1/<path:param>')  # NOTE: <path:param> is required to match /deff(param=''):
    return (
        f"param: {param}\ndecoded param: {urllib.parse.unquote(param)}\n",
        200,
        {'content-type': 'text/plain'}
    )

use FLASK_APP=routetest flask run to launch this script on localhost:5000, then I can't reproduce your issues:

$ curl http://localhost:5000/v1/https%3A%2F%2Fgoogle.com
param: https://google.com
decoded param: https://google.com
$ curl http://localhost:5000/v1/foo%2520bar
param: foo%20bar
decoded param: foo bar
$ curl http://localhost:5000/v1/foo%20bar
param: foo bar
decoded param: foo bar

which can only mean that you have a WSGI server that is mishandling quoting in paths.

Solution 2:

I think the problem is you are not understanding the URL encoding :) It requires to avoid spaces, so they are translated to %20 by the browser and back automatically by flask. Read this for more information: https://www.w3schools.com/tags/ref_urlencode.asp

Answer : send an encoded foo%20bar to the server with foo%2520bar.

Post a Comment for "Flask Url Parameters With % Are Not Properly Handled"