use prepared statements in all SQL queries that contains jids to prevent SQL injection. Fixes #7034

This commit is contained in:
Yann Leboulanger 2011-11-08 22:00:52 +01:00
parent 93683a8c54
commit 23327c834d
1 changed files with 41 additions and 37 deletions

View File

@ -569,7 +569,7 @@ class Logger:
except exceptions.PysqliteOperationalError, e: except exceptions.PysqliteOperationalError, e:
# Error trying to create a new jid_id. This means there is no log # Error trying to create a new jid_id. This means there is no log
return [] return []
where_sql = self._build_contact_where(account, jid) where_sql, jid_tuple = self._build_contact_where(account, jid)
now = int(float(time.time())) now = int(float(time.time()))
timed_out = now - (timeout * 60) # before that they are too old timed_out = now - (timeout * 60) # before that they are too old
@ -577,14 +577,13 @@ class Logger:
# 3 - 8 (we avoid the last 2 lines but we still return 5 asked) # 3 - 8 (we avoid the last 2 lines but we still return 5 asked)
try: try:
self.cur.execute(''' self.cur.execute('''
SELECT time, kind, message FROM logs SELECT time, kind, message FROM logs
WHERE (%s) AND kind IN (%d, %d, %d, %d, %d) AND time > %d WHERE (%s) AND kind IN (%d, %d, %d, %d, %d) AND time > %d
ORDER BY time DESC LIMIT %d OFFSET %d ORDER BY time DESC LIMIT %d OFFSET %d
''' % (where_sql, constants.KIND_SINGLE_MSG_RECV, ''' % (where_sql, constants.KIND_SINGLE_MSG_RECV,
constants.KIND_CHAT_MSG_RECV, constants.KIND_SINGLE_MSG_SENT, constants.KIND_CHAT_MSG_RECV, constants.KIND_SINGLE_MSG_SENT,
constants.KIND_CHAT_MSG_SENT, constants.KIND_ERROR, constants.KIND_CHAT_MSG_SENT, constants.KIND_ERROR, timed_out,
timed_out, restore_how_many_rows, pending_how_many) restore_how_many_rows, pending_how_many), jid_tuple)
)
results = self.cur.fetchall() results = self.cur.fetchall()
except sqlite.DatabaseError: except sqlite.DatabaseError:
@ -614,18 +613,18 @@ class Logger:
except exceptions.PysqliteOperationalError, e: except exceptions.PysqliteOperationalError, e:
# Error trying to create a new jid_id. This means there is no log # Error trying to create a new jid_id. This means there is no log
return [] return []
where_sql = self._build_contact_where(account, jid) where_sql, jid_tuple = self._build_contact_where(account, jid)
start_of_day = self.get_unix_time_from_date(year, month, day) start_of_day = self.get_unix_time_from_date(year, month, day)
seconds_in_a_day = 86400 # 60 * 60 * 24 seconds_in_a_day = 86400 # 60 * 60 * 24
last_second_of_day = start_of_day + seconds_in_a_day - 1 last_second_of_day = start_of_day + seconds_in_a_day - 1
self.cur.execute(''' self.cur.execute('''
SELECT contact_name, time, kind, show, message, subject FROM logs SELECT contact_name, time, kind, show, message, subject FROM logs
WHERE (%s) WHERE (%s)
AND time BETWEEN %d AND %d AND time BETWEEN %d AND %d
ORDER BY time ORDER BY time
''' % (where_sql, start_of_day, last_second_of_day)) ''' % (where_sql, start_of_day, last_second_of_day), jid_tuple)
results = self.cur.fetchall() results = self.cur.fetchall()
return results return results
@ -651,13 +650,13 @@ class Logger:
return results return results
else: # user just typed something, we search in message column else: # user just typed something, we search in message column
where_sql = self._build_contact_where(account, jid) where_sql, jid_tuple = self._build_contact_where(account, jid)
like_sql = '%' + query.replace("'", "''") + '%' like_sql = '%' + query.replace("'", "''") + '%'
self.cur.execute(''' self.cur.execute('''
SELECT contact_name, time, kind, show, message, subject FROM logs SELECT contact_name, time, kind, show, message, subject FROM logs
WHERE (%s) AND message LIKE '%s' WHERE (%s) AND message LIKE '%s'
ORDER BY time ORDER BY time
''' % (where_sql, like_sql)) ''' % (where_sql, like_sql), jid_tuple)
results = self.cur.fetchall() results = self.cur.fetchall()
return results return results
@ -672,7 +671,7 @@ class Logger:
# Error trying to create a new jid_id. This means there is no log # Error trying to create a new jid_id. This means there is no log
return [] return []
days_with_logs = [] days_with_logs = []
where_sql = self._build_contact_where(account, jid) where_sql, jid_tuple = self._build_contact_where(account, jid)
# First select all date of month whith logs we want # First select all date of month whith logs we want
start_of_month = self.get_unix_time_from_date(year, month, 1) start_of_month = self.get_unix_time_from_date(year, month, 1)
@ -684,13 +683,13 @@ class Logger:
# and take only one of the same values (distinct) # and take only one of the same values (distinct)
# Now we have timestamps of time 0:00 of every day with logs # Now we have timestamps of time 0:00 of every day with logs
self.cur.execute(''' self.cur.execute('''
SELECT DISTINCT time/(86400)*86400 FROM logs SELECT DISTINCT time/(86400)*86400 FROM logs
WHERE (%s) WHERE (%s)
AND time BETWEEN %d AND %d AND time BETWEEN %d AND %d
AND kind NOT IN (%d, %d) AND kind NOT IN (%d, %d)
ORDER BY time ORDER BY time
''' % (where_sql, start_of_month, last_second_of_month, ''' % (where_sql, start_of_month, last_second_of_month,
constants.KIND_STATUS, constants.KIND_GCSTATUS)) constants.KIND_STATUS, constants.KIND_GCSTATUS), jid_tuple)
result = self.cur.fetchall() result = self.cur.fetchall()
# convert timestamps to day of month # convert timestamps to day of month
@ -706,19 +705,21 @@ class Logger:
""" """
where_sql = '' where_sql = ''
if not is_room: if not is_room:
where_sql = self._build_contact_where(account, jid) where_sql, jid_tuple = self._build_contact_where(account, jid)
else: else:
try: try:
jid_id = self.get_jid_id(jid, 'ROOM') jid_id = self.get_jid_id(jid, 'ROOM')
except exceptions.PysqliteOperationalError, e: except exceptions.PysqliteOperationalError, e:
# Error trying to create a new jid_id. This means there is no log # Error trying to create a new jid_id. This means there is no log
return None return None
where_sql = 'jid_id = %s' % jid_id where_sql = 'jid_id = ?'
jid_tuple = (jid_id,)
self.cur.execute(''' self.cur.execute('''
SELECT MAX(time) FROM logs SELECT MAX(time) FROM logs
WHERE (%s) WHERE (%s)
AND kind NOT IN (%d, %d) AND kind NOT IN (%d, %d)
''' % (where_sql, constants.KIND_STATUS, constants.KIND_GCSTATUS)) ''' % (where_sql, constants.KIND_STATUS, constants.KIND_GCSTATUS),
jid_tuple)
results = self.cur.fetchone() results = self.cur.fetchone()
if results is not None: if results is not None:
@ -766,6 +767,7 @@ class Logger:
Build the where clause for a jid, including metacontacts jid(s) if any Build the where clause for a jid, including metacontacts jid(s) if any
""" """
where_sql = '' where_sql = ''
jid_tuple = ()
# will return empty list if jid is not associated with # will return empty list if jid is not associated with
# any metacontacts # any metacontacts
family = gajim.contacts.get_metacontacts_family(account, jid) family = gajim.contacts.get_metacontacts_family(account, jid)
@ -775,13 +777,15 @@ class Logger:
jid_id = self.get_jid_id(user['jid']) jid_id = self.get_jid_id(user['jid'])
except exceptions.PysqliteOperationalError, e: except exceptions.PysqliteOperationalError, e:
continue continue
where_sql += 'jid_id = %s' % jid_id where_sql += 'jid_id = ?'
jid_tuple += (jid_id,)
if user != family[-1]: if user != family[-1]:
where_sql += ' OR ' where_sql += ' OR '
else: # if jid was not associated with metacontacts else: # if jid was not associated with metacontacts
jid_id = self.get_jid_id(jid) jid_id = self.get_jid_id(jid)
where_sql = 'jid_id = %s' % jid_id where_sql = 'jid_id = ?'
return where_sql jid_tuple += (jid_id,)
return where_sql, jid_tuple
def save_transport_type(self, jid, type_): def save_transport_type(self, jid, type_):
""" """