Improve data sanitation (Fixes Tautulli/Tautulli-Issues#161)

This commit is contained in:
JonnyWong16 2019-02-20 18:35:04 -08:00
parent 037e983350
commit 6a21d7690a
4 changed files with 39 additions and 15 deletions

View file

@ -101,10 +101,6 @@ class DataTables(object):
# Paginate results # Paginate results
result = filtered[parameters['start']:(parameters['start'] + parameters['length'])] result = filtered[parameters['start']:(parameters['start'] + parameters['length'])]
# Sanitize on the way out
result = [{k: helpers.sanitize(v) if isinstance(v, basestring) else v for k, v in row.iteritems()}
for row in result]
output = {'result': result, output = {'result': result,
'draw': draw_counter, 'draw': draw_counter,
'filteredCount': len(filtered), 'filteredCount': len(filtered),

View file

@ -522,11 +522,28 @@ def process_json_kwargs(json_kwargs):
return params return params
def sanitize(string): def sanitize_out(*dargs, **dkwargs):
if string: """ Helper decorator that sanitized the output
return unicode(string).replace('<','&lt;').replace('>','&gt;') """
def rd(function):
@wraps(function)
def wrapper(*args, **kwargs):
return sanitize(function(*args, **kwargs))
return wrapper
return rd
def sanitize(obj):
if isinstance(obj, basestring):
return unicode(obj).replace('<', '&lt;').replace('>', '&gt;')
elif isinstance(obj, list):
return [sanitize(o) for o in obj]
elif isinstance(obj, dict):
return {k: sanitize(v) for k, v in obj.iteritems()}
elif isinstance(obj, tuple):
return tuple(sanitize(list(obj)))
else: else:
return '' return obj
def is_public_ip(host): def is_public_ip(host):

View file

@ -566,13 +566,13 @@ class PlexTV(object):
settings_photo_quality = helpers.get_xml_attr(settings, 'photoQuality') settings_photo_quality = helpers.get_xml_attr(settings, 'photoQuality')
settings_photo_resolution = helpers.get_xml_attr(settings, 'photoResolution') settings_photo_resolution = helpers.get_xml_attr(settings, 'photoResolution')
sync_details = {"device_name": helpers.sanitize(device_name), sync_details = {"device_name": device_name,
"platform": helpers.sanitize(device_platform), "platform": device_platform,
"user_id": device_user_id, "user_id": device_user_id,
"user": helpers.sanitize(device_friendly_name), "user": device_friendly_name,
"username": helpers.sanitize(device_username), "username": device_username,
"root_title": helpers.sanitize(sync_root_title), "root_title": sync_root_title,
"sync_title": helpers.sanitize(sync_title), "sync_title": sync_title,
"metadata_type": sync_metadata_type, "metadata_type": sync_metadata_type,
"content_type": sync_content_type, "content_type": sync_content_type,
"rating_key": rating_key, "rating_key": rating_key,

View file

@ -55,7 +55,7 @@ import users
import versioncheck import versioncheck
import web_socket import web_socket
from plexpy.api2 import API2 from plexpy.api2 import API2
from plexpy.helpers import checked, addtoapi, get_ip, create_https_certificates, build_datatables_json from plexpy.helpers import checked, addtoapi, get_ip, create_https_certificates, build_datatables_json, sanitize_out
from plexpy.session import get_session_info, get_session_user_id, allow_session_user, allow_session_library from plexpy.session import get_session_info, get_session_user_id, allow_session_user, allow_session_library
from plexpy.webauth import AuthController, requireAuth, member_of from plexpy.webauth import AuthController, requireAuth, member_of
@ -349,6 +349,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth() @requireAuth()
@sanitize_out()
@addtoapi("get_libraries_table") @addtoapi("get_libraries_table")
def get_library_list(self, **kwargs): def get_library_list(self, **kwargs):
""" Get the data on the Tautulli libraries table. """ Get the data on the Tautulli libraries table.
@ -427,6 +428,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@sanitize_out()
@addtoapi("get_library_names") @addtoapi("get_library_names")
def get_library_sections(self, **kwargs): def get_library_sections(self, **kwargs):
""" Get a list of library sections and ids on the PMS. """ Get a list of library sections and ids on the PMS.
@ -1014,6 +1016,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth() @requireAuth()
@sanitize_out()
@addtoapi("get_users_table") @addtoapi("get_users_table")
def get_user_list(self, **kwargs): def get_user_list(self, **kwargs):
""" Get the data on Tautulli users table. """ Get the data on Tautulli users table.
@ -1228,6 +1231,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth() @requireAuth()
@sanitize_out()
@addtoapi() @addtoapi()
def get_user_ips(self, user_id=None, **kwargs): def get_user_ips(self, user_id=None, **kwargs):
""" Get the data on Tautulli users IP table. """ Get the data on Tautulli users IP table.
@ -1294,6 +1298,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth() @requireAuth()
@sanitize_out()
@addtoapi() @addtoapi()
def get_user_logins(self, user_id=None, **kwargs): def get_user_logins(self, user_id=None, **kwargs):
""" Get the data on Tautulli user login table. """ Get the data on Tautulli user login table.
@ -1575,6 +1580,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth() @requireAuth()
@sanitize_out()
@addtoapi() @addtoapi()
def get_history(self, user=None, user_id=None, grouping=None, **kwargs): def get_history(self, user=None, user_id=None, grouping=None, **kwargs):
""" Get the Tautulli history. """ Get the Tautulli history.
@ -1821,6 +1827,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth() @requireAuth()
@sanitize_out()
@addtoapi() @addtoapi()
def get_user_names(self, **kwargs): def get_user_names(self, **kwargs):
""" Get a list of all user and user ids. """ Get a list of all user and user ids.
@ -2293,6 +2300,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@sanitize_out()
@requireAuth() @requireAuth()
def get_sync(self, machine_id=None, user_id=None, **kwargs): def get_sync(self, machine_id=None, user_id=None, **kwargs):
if user_id == 'null': if user_id == 'null':
@ -2434,6 +2442,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@sanitize_out()
@addtoapi() @addtoapi()
def get_notification_log(self, **kwargs): def get_notification_log(self, **kwargs):
""" Get the data on the Tautulli notification logs table. """ Get the data on the Tautulli notification logs table.
@ -2495,6 +2504,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@sanitize_out()
@addtoapi() @addtoapi()
def get_newsletter_log(self, **kwargs): def get_newsletter_log(self, **kwargs):
""" Get the data on the Tautulli newsletter logs table. """ Get the data on the Tautulli newsletter logs table.
@ -5228,6 +5238,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@sanitize_out()
@addtoapi() @addtoapi()
def get_synced_items(self, machine_id='', user_id='', **kwargs): def get_synced_items(self, machine_id='', user_id='', **kwargs):
""" Get a list of synced items on the PMS. """ Get a list of synced items on the PMS.