Commit 333e3315 by uzairr

Verify 'Full Name' field does not allow HTML.

'Full Name' field in the student account settings is allowing HTML
as an input which makes spoofing easily.To avoid it, validation is
added that ensures 'Full Name' field does not allow HTML as input.

LEARNER-3337
parent 571be1f5
......@@ -275,16 +275,9 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, AcceptanceTest):
u'Full Name',
self.full_name,
u'@',
[u'another name', self.full_name],
)
actual_events = self.wait_for_events(event_filter=self.settings_changed_event_filter, number_of_matches=2)
self.assert_events_match(
[
self.expected_settings_changed_event('name', self.full_name, 'another name'),
self.expected_settings_changed_event('name', 'another name', self.full_name),
],
actual_events
[u'<h1>another name<h1>', self.full_name],
u'Full Name cannot contain the following characters: < >',
False
)
def test_email_field(self):
......
......@@ -2,10 +2,12 @@
"""
Programmatic integration point for User API Accounts sub-application
"""
from django.utils.translation import override as override_language, ugettext as _
from django.db import transaction, IntegrityError
import re
import datetime
from pytz import UTC
from django.utils.translation import override as override_language, ugettext as _
from django.db import transaction, IntegrityError
from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings
from django.core.validators import validate_email, ValidationError
......@@ -133,8 +135,10 @@ def update_account_settings(requesting_user, update, username=None):
# If user has requested to change name, store old name because we must update associated metadata
# after the save process is complete.
changing_full_name = False
old_name = None
if "name" in update:
changing_full_name = True
old_name = existing_user_profile.name
# Check for fields that are not editable. Marking them read-only causes them to be ignored, but we wish to 400.
......@@ -169,6 +173,12 @@ def update_account_settings(requesting_user, update, username=None):
"user_message": err.message
}
if changing_full_name and contains_html(update['name']):
field_errors["name"] = {
"developer_message": u"Error thrown from validate_full_name: '{}'".format('Full Name is in-valid'),
"user_message": _(u"Full Name cannot contain the following characters: < >")
}
# If we have encountered any validation errors, return them to the user.
if field_errors:
raise errors.AccountValidationError(field_errors)
......@@ -514,6 +524,14 @@ def _get_user_and_profile(username):
return existing_user, existing_user_profile
def contains_html(value):
"""
Validator method to check whether name contains html tags
"""
regex = re.compile('(<|>)', re.UNICODE)
return bool(regex.search(value))
def _validate(validation_func, err, *args):
"""Generic validation function that returns default on
no errors, but the message associated with the err class
......
......@@ -179,22 +179,25 @@ class TestAccountApi(UserSettingsEventTestMixin, TestCase):
def test_update_multiple_validation_errors(self):
"""Test that all validation errors are built up and returned at once"""
# Send a read-only error, serializer error, and email validation error.
naughty_update = {
"username": "not_allowed",
"gender": "undecided",
"email": "not an email address"
"email": "not an email address",
"name": "<p style=\"font-size:300px; color:green;\"></br>Name<input type=\"text\"></br>Content spoof"
}
with self.assertRaises(AccountValidationError) as context_manager:
update_account_settings(self.user, naughty_update)
field_errors = context_manager.exception.field_errors
self.assertEqual(3, len(field_errors))
self.assertEqual(4, len(field_errors))
self.assertEqual("This field is not editable via this API", field_errors["username"]["developer_message"])
self.assertIn(
"Value \'undecided\' is not valid for field \'gender\'",
field_errors["gender"]["developer_message"]
)
self.assertIn("Valid e-mail address required.", field_errors["email"]["developer_message"])
self.assertIn("Full Name cannot contain the following characters: < >", field_errors["name"]["user_message"])
@patch('django.core.mail.send_mail')
@patch('student.views.render_to_string', Mock(side_effect=mock_render_to_string, autospec=True))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment