Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent JS injection in the admin add plugin url #6885

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion cms/admin/placeholderadmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from django.utils.six.moves.urllib.parse import parse_qsl, urlparse
from django.utils.decorators import method_decorator
from django.utils.encoding import force_text
from django.utils.html import conditional_escape
from django.utils.translation import get_language_from_path, ugettext as _

from django.views.decorators.clickjacking import xframe_options_sameorigin
Expand Down Expand Up @@ -343,7 +344,7 @@ def add_plugin(self, request):
# errors is s dict mapping fields to a list of errors
# for that field.
error = list(form.errors.values())[0][0]
return HttpResponseBadRequest(force_text(error))
return HttpResponseBadRequest(conditional_escape(force_text(error)))

plugin_data = form.cleaned_data
placeholder = plugin_data['placeholder_id']
Expand Down
18 changes: 18 additions & 0 deletions cms/tests/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -1212,3 +1212,21 @@ def test_related_name(self):
'mti_pluginapp_lessmixedplugin')
# Non plugins are skipped
self.assertFalse(hasattr(NonPluginModel, 'cmsplugin_ptr'))


class UserInputValidationPluginTest(PluginsTestBaseCase):

def test_error_response_escapes(self):
language = 'en'
superuser = self.get_superuser()
page = create_page("error page", "nav_playground.html", language=language)
placeholder = page.get_placeholders(language).get(slot='body')

add_url = self.get_add_plugin_uri(
placeholder, plugin_type='TextPlugin"><script>alert("hello world")</script>', language=language)

with self.login_user_context(superuser):
response = self.client.get(add_url)

self.assertEqual(response.status_code, 400)
self.assertIn('TextPlugin&quot;&gt;&lt;script&gt;alert(&quot;hello world&quot;)&lt;/script&gt;', response.content.decode("utf-8"))