|
1 Patch taken from https://review.openstack.org/329997 (Liberty) and |
|
2 slightly modified to adjust for gpatch fuzz for application to Kilo. |
|
3 |
|
4 From d585e5eb9acf92d10d39b6c2038917a7e8ac71bb Mon Sep 17 00:00:00 2001 |
|
5 From: Richard Jones <[email protected]> |
|
6 Date: Tue, 3 May 2016 15:51:49 +1000 |
|
7 Subject: [PATCH] Escape angularjs templating in unsafe HTML |
|
8 |
|
9 This code extends the unsafe (typically user-supplied) HTML escape |
|
10 built into Django to also escape angularjs templating markers. Safe |
|
11 HTML will be unaffected. |
|
12 |
|
13 Closes-bug: 1567673 |
|
14 Change-Id: I0cbebfd0f814bdf1bf8c06833abf33cc2d4748e7 |
|
15 (cherry picked from commit 4bc01cedf39cdeff2553d01cdace707a1ecf6620) |
|
16 --- |
|
17 horizon/utils/escape.py | 31 +++++++++++++++++++++++++++++++ |
|
18 openstack_dashboard/settings.py | 3 +++ |
|
19 openstack_dashboard/test/settings.py | 6 ++++++ |
|
20 3 files changed, 40 insertions(+) |
|
21 create mode 100644 horizon/utils/escape.py |
|
22 |
|
23 diff --git a/horizon/utils/escape.py b/horizon/utils/escape.py |
|
24 new file mode 100644 |
|
25 index 0000000..471a90f |
|
26 --- /dev/null |
|
27 +++ b/horizon/utils/escape.py |
|
28 @@ -0,0 +1,31 @@ |
|
29 +# Copyright 2016, Rackspace, US, Inc. |
|
30 +# |
|
31 +# Licensed under the Apache License, Version 2.0 (the "License"); |
|
32 +# you may not use this file except in compliance with the License. |
|
33 +# You may obtain a copy of the License at |
|
34 +# |
|
35 +# http://www.apache.org/licenses/LICENSE-2.0 |
|
36 +# |
|
37 +# Unless required by applicable law or agreed to in writing, software |
|
38 +# distributed under the License is distributed on an "AS IS" BASIS, |
|
39 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
40 +# See the License for the specific language governing permissions and |
|
41 +# limitations under the License. |
|
42 + |
|
43 +import django.utils.html |
|
44 + |
|
45 + |
|
46 +def escape(text, existing=django.utils.html.escape): |
|
47 + # Replace our angular markup string with a different string |
|
48 + # (which just happens to be the Django comment string) |
|
49 + # this prevents user-supplied data from being intepreted in |
|
50 + # our pages by angularjs, thus preventing it from being used |
|
51 + # for XSS attacks. Note that we use {$ $} instead of the |
|
52 + # standard {{ }} - this is configured in horizon.framework |
|
53 + # angularjs module through $interpolateProvider |
|
54 + return existing(text).replace('{$', '{%').replace('$}', '%}') |
|
55 + |
|
56 + |
|
57 +# this will be invoked as early as possible in settings.py |
|
58 +def monkeypatch_escape(): |
|
59 + django.utils.html.escape = escape |
|
60 diff --git a/openstack_dashboard/settings.py b/openstack_dashboard/settings.py |
|
61 index 5761a91..803b079 100644 |
|
62 --- a/openstack_dashboard/settings.py |
|
63 +++ b/openstack_dashboard/settings.py |
|
64 @@ -27,6 +27,9 @@ from openstack_dashboard import exceptions |
|
65 from openstack_dashboard import exceptions |
|
66 from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa |
|
67 |
|
68 +from horizon.utils.escape import monkeypatch_escape |
|
69 + |
|
70 +monkeypatch_escape() |
|
71 |
|
72 warnings.formatwarning = lambda message, category, *args, **kwargs: \ |
|
73 '%s: %s' % (category.__name__, message) |
|
74 diff --git a/openstack_dashboard/test/settings.py b/openstack_dashboard/test/settings.py |
|
75 index 1926644..45f1d06 100644 |
|
76 --- a/openstack_dashboard/test/settings.py |
|
77 +++ b/openstack_dashboard/test/settings.py |
|
78 @@ -17,6 +17,12 @@ from openstack_dashboard import exceptions |
|
79 from openstack_dashboard import exceptions |
|
80 from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa |
|
81 |
|
82 +from horizon.utils.escape import monkeypatch_escape |
|
83 + |
|
84 +# this is used to protect from client XSS attacks, but it's worth |
|
85 +# enabling in our test setup to find any issues it might cause |
|
86 +monkeypatch_escape() |
|
87 + |
|
88 STATICFILES_DIRS = get_staticfiles_dirs() |
|
89 |
|
90 TEST_DIR = os.path.dirname(os.path.abspath(__file__)) |
|
91 -- |
|
92 1.9.1 |
|
93 |
|
94 |