first round of input sanitization

This commit is contained in:
j 2012-02-21 21:56:06 +05:30
parent b62b58a967
commit 67bc4475e9
7 changed files with 44 additions and 28 deletions

View file

@ -1,18 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# ci:si:et:sw=4:sts=4:ts=4 # ci:si:et:sw=4:sts=4:ts=4
import re
import ox import ox
import html5lib
def cleanup_value(value, layer_type): def cleanup_value(value, layer_type):
#FIXME: what about other types? location etc #FIXME: what about other types? location etc
if layer_type == 'text': if layer_type == 'text':
value = sanitize_fragment(value) value = ox.parse_html(value)
else: else:
value = ox.stripTags(value) value = ox.escape_html(value)
return value return value
def sanitize_fragment(html):
return html5lib.parseFragment(html).toxml().decode('utf-8')

View file

@ -139,7 +139,7 @@ def editPage(request):
page, created = models.Page.objects.get_or_create(name=data['name']) page, created = models.Page.objects.get_or_create(name=data['name'])
if not created: if not created:
page.log() page.log()
page.text = data['text'] page.text = ox.parse_html(data['text'])
page.save() page.save()
response = json_response({'name': page.name, 'text': page.text}) response = json_response({'name': page.name, 'text': page.text})
else: else:

View file

@ -31,22 +31,27 @@ def addEvent(request):
exists = False exists = False
names = [data['name']] + data.get('alternativeNames', []) names = [data['name']] + data.get('alternativeNames', [])
for name in names: for name in names:
name = ox.decodeHtml(name)
if models.Event.objects.filter(defined=True, if models.Event.objects.filter(defined=True,
name_find__icontains=u'|%s|'%name).count() != 0: name_find__icontains=u'|%s|'%name).count() != 0:
exists = True exists = True
existing_names.append(name) existing_names.append(name)
if not exists: if not exists:
models.Event.objects.filter(defined=False, name__in=names).delete() models.Event.objects.filter(defined=False, name__in=names).delete()
data['name'] = ox.escape_html(data['name'])
event = models.Event(name=data['name']) event = models.Event(name=data['name'])
for key in ('start', 'startTime', 'end', 'endTime', 'duration', 'durationTime', for key in ('start', 'startTime', 'end', 'endTime', 'duration', 'durationTime',
'type', 'alternativeNames'): 'type', 'alternativeNames'):
if key in data and data[key]: if key in data and data[key]:
value = data[key] value = data[key]
if isinstance(value, basestring):
value = ox.escape_html(value)
if key == 'alternativeNames': if key == 'alternativeNames':
value = tuple(value) value = tuple([ox.escape_html(v) for v in value])
setattr(event, key, value) setattr(event, key, value)
if 'nameSort' in data: if 'nameSort' in data:
event.set_name_sort(data['nameSort']) value = ox.escape_html(data['nameSort'])
event.set_name_sort(value)
event.matches = 0 event.matches = 0
event.save() event.save()
event.update_matches() event.update_matches()
@ -83,17 +88,19 @@ def editEvent(request):
conflict_names.append(name) conflict_names.append(name)
if not conflict: if not conflict:
models.Event.objects.filter(defined=False, name__in=names).delete() models.Event.objects.filter(defined=False, name__in=names).delete()
if 'name' in data:
event.set_name_sort(data['name'])
for key in ('name', 'start', 'startTime', 'end', 'endTime', 'duration', 'durationTime', for key in ('name', 'start', 'startTime', 'end', 'endTime', 'duration', 'durationTime',
'type', 'alternativeNames'): 'type', 'alternativeNames'):
if key in data: if key in data:
value = data[key] value = data[key]
if isinstance(value, basestring):
value = ox.escape_html(value)
if key == 'alternativeNames': if key == 'alternativeNames':
value = tuple(value) value = tuple([ox.escape_html(v) for v in value])
setattr(event, key, value) setattr(event, key, value)
if 'name' in data:
event.set_name_sort(ox.escape_html(data['name']))
if 'nameSort' in data: if 'nameSort' in data:
event.set_name_sort(data['nameSort']) event.set_name_sort(ox.escape_html(data['nameSort']))
event.save() event.save()
if 'name' in data or 'alternativeNames' in data: if 'name' in data or 'alternativeNames' in data:
event.update_matches() event.update_matches()

View file

@ -226,14 +226,20 @@ class Item(models.Model):
if not description: if not description:
description = '' description = ''
d, created = Description.objects.get_or_create(key=k, value=value) d, created = Description.objects.get_or_create(key=k, value=value)
d.description = description d.description = ox.parse_html(description)
d.save() d.save()
for key in data: for key in data:
if data[key] == None: if data[key] == None:
if key in self.data: if key in self.data:
del self.data[key] del self.data[key]
else: else:
self.data[key] = data[key] k = filter(lambda i: i['id'] == key, settings.CONFIG['itemKeys'])
if k and k.get('type') == 'text':
self.data[key] = ox.parse_html(data[key])
elif isinstance(data[key], basestring):
self.data[key] = ox.escape_html(data[key])
else:
self.data[key] = ox.escape_html(data[key])
return self.save() return self.save()
def log(self): def log(self):

View file

@ -433,10 +433,10 @@ def edit(request):
response = json_response(status=200, text='ok') response = json_response(status=200, text='ok')
if 'notes' in data: if 'notes' in data:
if request.user.get_profile().capability('canEditMetadata'): if request.user.get_profile().capability('canEditMetadata'):
item.notes = data['notes'] item.notes = ox.parse_html(data['notes'])
del data['notes'] del data['notes']
if 'rightslevel' in data: if 'rightslevel' in data:
item.level = data['rightslevel'] item.level = int(data['rightslevel'])
del data['rightslevel'] del data['rightslevel']
if 'user' in data: if 'user' in data:
if request.user.get_profile().get_level() in ('admin', 'staff') and \ if request.user.get_profile().get_level() in ('admin', 'staff') and \

View file

@ -3,6 +3,8 @@
from __future__ import division from __future__ import division
import os import os
import ox
from django.db.models import Max, Sum from django.db.models import Max, Sum
from django.db import transaction from django.db import transaction
from django.http import HttpResponseForbidden, Http404 from django.http import HttpResponseForbidden, Http404
@ -238,7 +240,7 @@ def addList(request):
value = list.status value = list.status
list.status = value list.status = value
if 'description' in data: if 'description' in data:
list.description = data['description'] list.description = ox.parse_html(data['description'])
if 'view' in data: if 'view' in data:
list.view = data['view'] list.view = data['view']
if 'sort' in data: if 'sort' in data:
@ -356,7 +358,7 @@ def editList(request):
name = data['name'] + ' (%d)' % num name = data['name'] + ' (%d)' % num
list.name = name list.name = name
elif key == 'description': elif key == 'description':
list.description = data['description'] list.description = ox.parse_html(data['description'])
if 'position' in data: if 'position' in data:
pos, created = models.Position.objects.get_or_create(list=list, user=request.user) pos, created = models.Position.objects.get_or_create(list=list, user=request.user)

View file

@ -50,13 +50,16 @@ def addPlace(request):
if _exists: if _exists:
name = 'Untitled [%s]' %n name = 'Untitled [%s]' %n
n += 1 n += 1
names = [name] + data.get('alternativeNames', []) names = [name] + data.get('alternativeNames', [])
for name in names: data['alternativveNames'] = [ox.escape_html(n)
for n in data.get('alternativeNames', [])]
name = ox.escape_html(name)
for n in names:
n = ox.decodeHtml(name)
if models.Place.objects.filter(defined=True, if models.Place.objects.filter(defined=True,
name_find__icontains=u'|%s|'%name).count() != 0: name_find__icontains=u'|%s|'%n).count() != 0:
exists = True exists = True
existing_names.append(name) existing_names.append(n)
''' '''
if 'geoname' in data: if 'geoname' in data:
if models.Place.objects.filter(defined=True, if models.Place.objects.filter(defined=True,
@ -104,15 +107,17 @@ def editPlace(request):
names = data.get('name', []) names = data.get('name', [])
if isinstance(names, basestring): if isinstance(names, basestring):
names = [names] names = [names]
names = [ox.escape_html(n) for n in names]
alternative_names = [ox.escape_html(n) for n in data.get('alternativeNames', [])]
alternative_names = filter(lambda n: n.strip(), alternative_names)
if place.editable(request.user): if place.editable(request.user):
conflict = False conflict = False
conflict_names = [] conflict_names = []
conflict_geoname = '' conflict_geoname = ''
alternative_names = data.get('alternativeNames', [])
if alternative_names: if alternative_names:
alternative_names = filter(lambda n: n.strip(), alternative_names)
data['alternativeNames'] = alternative_names data['alternativeNames'] = alternative_names
for name in names + alternative_names: for name in names + alternative_names:
name = ox.decodeHtml(name)
if models.Place.objects.filter(defined=True, if models.Place.objects.filter(defined=True,
name_find__icontains=u'|%s|'%name).exclude(id=place.id).count() != 0: name_find__icontains=u'|%s|'%name).exclude(id=place.id).count() != 0:
conflict = True conflict = True
@ -129,6 +134,8 @@ def editPlace(request):
for key in data: for key in data:
if key != 'id': if key != 'id':
value = data[key] value = data[key]
if isinstance(value, basestring):
value = ox.escape_html(value)
if isinstance(value, list): if isinstance(value, list):
value = tuple(value) value = tuple(value)
setattr(place, key, value) setattr(place, key, value)