Browse Source

Fixed XSS problem by escaping all slashes in JSON.

This also probes simplejson first to figure out if it escapes slashes
which it did in earlier versions.
pull/1638/head
Armin Ronacher 15 years ago
parent
commit
9f6bc93e4d
  1. 12
      flask.py
  2. 2
      tests/flask_tests.py

12
flask.py

@ -10,6 +10,7 @@
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
""" """
from __future__ import with_statement from __future__ import with_statement
import re
import os import os
import sys import sys
@ -47,6 +48,12 @@ except (ImportError, AttributeError):
pkg_resources = None pkg_resources = None
# figure out if simplejson escapes slashes. This behaviour was changed
# from one version to another without reason.
if json_available:
_json_escapes_slashes = '\\/' in json.dumps('/')
class Request(RequestBase): class Request(RequestBase):
"""The request object used by default in flask. Remembers the """The request object used by default in flask. Remembers the
matched endpoint and view arguments. matched endpoint and view arguments.
@ -271,7 +278,10 @@ def _tojson_filter(string, *args, **kwargs):
"""Calls dumps for the template engine, escaping Slashes properly.""" """Calls dumps for the template engine, escaping Slashes properly."""
if __debug__: if __debug__:
_assert_have_json() _assert_have_json()
return json.dumps(string, *args, **kwargs).replace('</', '<\\/') rv = json.dumps(string, *args, **kwargs)
if not _json_escapes_slashes:
rv = rv.replace('/', '\\/')
return rv
class Flask(object): class Flask(object):

2
tests/flask_tests.py

@ -245,6 +245,8 @@ class JSONTestCase(unittest.TestCase):
with app.test_request_context(): with app.test_request_context():
rv = flask.render_template_string('{{ "</script>"|tojson|safe }}') rv = flask.render_template_string('{{ "</script>"|tojson|safe }}')
assert rv == '"<\\/script>"' assert rv == '"<\\/script>"'
rv = flask.render_template_string('{{ "<\0/script>"|tojson|safe }}')
assert rv == '"<\\u0000\\/script>"'
class TemplatingTestCase(unittest.TestCase): class TemplatingTestCase(unittest.TestCase):

Loading…
Cancel
Save