escape display names when displaying collection contributors (bug 715601)
This commit is contained in:
Родитель
d2a685ae49
Коммит
03f7c991db
|
@ -28,16 +28,18 @@ from django.utils.translation import trans_real
|
|||
from django.utils.functional import Promise
|
||||
from django.utils.encoding import smart_str, smart_unicode
|
||||
|
||||
import bleach
|
||||
from cef import log_cef as _log_cef
|
||||
from easy_thumbnails import processors
|
||||
import html5lib
|
||||
from html5lib.serializer.htmlserializer import HTMLSerializer
|
||||
import jinja2
|
||||
import pytz
|
||||
from PIL import Image, ImageFile, PngImagePlugin
|
||||
|
||||
import amo.search
|
||||
from amo import ADDON_ICON_SIZES
|
||||
from amo.urlresolvers import reverse
|
||||
from amo.urlresolvers import get_outgoing_url, reverse
|
||||
from translations.models import Translation
|
||||
from users.models import UserNotification
|
||||
from users.utils import UnsubscribeCode
|
||||
|
@ -704,3 +706,18 @@ def no_translation():
|
|||
trans_real.deactivate()
|
||||
yield
|
||||
trans_real.activate(lang)
|
||||
|
||||
|
||||
def escape_all(v):
|
||||
"""Escape html in JSON value, including nested items."""
|
||||
if isinstance(v, basestring):
|
||||
v = jinja2.escape(v)
|
||||
v = bleach.linkify(v, nofollow=True, filter_url=get_outgoing_url)
|
||||
return v
|
||||
elif isinstance(v, list):
|
||||
for i, lv in enumerate(v):
|
||||
v[i] = escape_all(lv)
|
||||
elif isinstance(v, dict):
|
||||
for k, lv in v.iteritems():
|
||||
v[k] = escape_all(lv)
|
||||
return v
|
||||
|
|
|
@ -20,10 +20,8 @@ from django.utils.encoding import smart_unicode
|
|||
from django.views.decorators.cache import never_cache
|
||||
from django.views.decorators.csrf import csrf_view_exempt
|
||||
|
||||
import bleach
|
||||
import commonware.log
|
||||
import jingo
|
||||
import jinja2
|
||||
from PIL import Image
|
||||
from session_csrf import anonymous_csrf
|
||||
from tower import ugettext_lazy as _lazy, ugettext as _
|
||||
|
@ -33,10 +31,10 @@ from waffle.decorators import waffle_flag
|
|||
from applications.models import Application, AppVersion
|
||||
import amo
|
||||
import amo.utils
|
||||
from amo import messages, urlresolvers
|
||||
from amo import messages
|
||||
from amo.decorators import json_view, login_required, post_required, write
|
||||
from amo.helpers import loc, urlparams
|
||||
from amo.utils import HttpResponseSendFile, MenuItem
|
||||
from amo.utils import escape_all, HttpResponseSendFile, MenuItem
|
||||
from amo.urlresolvers import reverse
|
||||
from access import acl
|
||||
from addons import forms as addon_forms
|
||||
|
@ -735,20 +733,6 @@ def upload_detail_for_addon(request, addon_id, addon, uuid):
|
|||
return json_upload_detail(request, upload, addon_slug=addon.slug)
|
||||
|
||||
|
||||
def escape_all(v):
|
||||
"""Escape html in JSON value, including nested list items."""
|
||||
if isinstance(v, basestring):
|
||||
v = jinja2.escape(v)
|
||||
v = bleach.linkify(v, nofollow=True,
|
||||
filter_url=urlresolvers.get_outgoing_url)
|
||||
return v
|
||||
elif isinstance(v, list):
|
||||
for i, lv in enumerate(v):
|
||||
v[i] = escape_all(lv)
|
||||
|
||||
return v
|
||||
|
||||
|
||||
def make_validation_result(data, is_compatibility=False):
|
||||
"""Safe wrapper around JSON dict containing a validation result.
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ class UserViewBase(amo.tests.TestCase):
|
|||
class TestAjax(UserViewBase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestAjax, self).setUp()
|
||||
self.client.login(username='jbalogh@mozilla.com', password='foo')
|
||||
|
||||
def test_ajax_404(self):
|
||||
|
@ -69,6 +70,17 @@ class TestAjax(UserViewBase):
|
|||
eq_(data, {'status': 1, 'message': '', 'id': 9945,
|
||||
'name': u'Justin Scott \u0627\u0644\u062a\u0637\u0628'})
|
||||
|
||||
def test_ajax_xss(self):
|
||||
self.user_profile.display_name = '<script>alert("xss")</script>'
|
||||
self.user_profile.save()
|
||||
assert '<script>' in self.user_profile.display_name, (
|
||||
'Expected <script> to be in display name')
|
||||
r = self.client.get(reverse('users.ajax'),
|
||||
{'q': self.user_profile.email})
|
||||
data = json.loads(r.content)
|
||||
assert '<script>' not in data
|
||||
assert '<script>' not in data
|
||||
|
||||
def test_ajax_failure_incorrect_email(self):
|
||||
r = self.client.get(reverse('users.ajax'), {'q': 'incorrect'},
|
||||
follow=True)
|
||||
|
|
|
@ -35,7 +35,7 @@ from amo.decorators import (json_view, login_required, no_login_required,
|
|||
from amo.forms import AbuseForm
|
||||
from amo.urlresolvers import reverse
|
||||
from amo.helpers import absolutify, loc
|
||||
from amo.utils import log_cef, send_mail, urlparams
|
||||
from amo.utils import escape_all, log_cef, send_mail, urlparams
|
||||
from abuse.models import send_abuse_report
|
||||
from addons.models import Addon
|
||||
from addons.views import BaseFilter
|
||||
|
@ -82,9 +82,9 @@ def ajax(request):
|
|||
if u:
|
||||
data.update(status=1, id=u[0].id, name=u[0].name)
|
||||
else:
|
||||
data.update(message=_('A user with that email address does not exist.'))
|
||||
data['message'] = _('A user with that email address does not exist.')
|
||||
|
||||
return data
|
||||
return escape_all(data)
|
||||
|
||||
|
||||
@no_login_required
|
||||
|
|
Загрузка…
Ссылка в новой задаче