From ade490514dd6d83adc7610f69f9c4cd68df47110 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 19 Apr 2010 18:51:04 +0200 Subject: [PATCH] Fixed a security problem caused by changed simplejson semantics. Notice: this was never in a release version of Flask. --- docs/api.rst | 2 ++ docs/patterns/jquery.rst | 3 ++- flask.py | 7 ++++++- tests/flask_tests.py | 6 ++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 247294a3..bd39d69e 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -250,6 +250,8 @@ Returning JSON doSomethingWith({{ user.username|tojson|safe }}); + Note that the ``|tojson`` filter escapes forward slashes properly. + Template Rendering ------------------ diff --git a/docs/patterns/jquery.rst b/docs/patterns/jquery.rst index d3d4a7e6..c12f4474 100644 --- a/docs/patterns/jquery.rst +++ b/docs/patterns/jquery.rst @@ -77,7 +77,8 @@ inside a `script` block here where different rules apply. will not be parsed. Everything until ```` is handled as script. This also means that there must never be any ``"|tojson|safe }`` is rendered as + ``"<\/script>"``). JSON View Functions diff --git a/flask.py b/flask.py index ba26c7f8..1dfe8a8f 100644 --- a/flask.py +++ b/flask.py @@ -259,6 +259,11 @@ def _get_package_path(name): return os.getcwd() +def _tojson_filter(string, *args, **kwargs): + """Calls dumps for the template engine, escaping Slashes properly.""" + return json.dumps(string, *args, **kwargs).replace('/', '\\/') + + class Flask(object): """The flask object implements a WSGI application and acts as the central object. It is passed the name of the module or package of the @@ -379,7 +384,7 @@ class Flask(object): get_flashed_messages=get_flashed_messages ) if json_available: - self.jinja_env.filters['tojson'] = json.dumps + self.jinja_env.filters['tojson'] = _tojson_filter def create_jinja_loader(self): """Creates the Jinja loader. By default just a package loader for diff --git a/tests/flask_tests.py b/tests/flask_tests.py index 0094f657..2d1f85f4 100644 --- a/tests/flask_tests.py +++ b/tests/flask_tests.py @@ -194,6 +194,12 @@ class JSONTestCase(unittest.TestCase): content_type='application/json') assert rv.data == '3' + def test_template_escaping(self): + app = flask.Flask(__name__) + with app.test_request_context(): + rv = flask.render_template_string('{{ ""|tojson|safe }}') + assert rv == '"<\\/script>"' + class TemplatingTestCase(unittest.TestCase):