diff options
author | Sascha Silbe <sascha-pgp@silbe.org> | 2013-08-12 15:31:07 (GMT) |
---|---|---|
committer | Sascha Silbe <sascha-pgp@silbe.org> | 2013-11-16 20:12:40 (GMT) |
commit | 75fb8e0f3d8717c60090e87274dc3c124a4ae873 (patch) | |
tree | 805247351b75f5cb837e86131886eb4ecb8c04af | |
parent | d7f76bcbf19e465e4f1bcae17e89f39153fdff3e (diff) |
check Xapian query for imbalanced parentheses
When merging the root query with a user-provided Xapian query, special
care must be taken. Asymmetric parentheses inside the user-provided
query can close outer parenthesis used for logically combining the two
queries, while still resulting in a valid query overall. Explicitly
check that the parenthesis are well-balanced inside the user-provided
query before using it.
This is a security fix, but as the search functionality isn't exposed
in journal2webdav so far there's no impact for any user.
-rw-r--r-- | fsemulation.py | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/fsemulation.py b/fsemulation.py index 7b8c088..2a73310 100644 --- a/fsemulation.py +++ b/fsemulation.py @@ -25,6 +25,7 @@ import threading import time import dbus +import xapian import sugar.mime @@ -479,6 +480,8 @@ class DataStore(object): xapian_query = query.get('query', '') query.update(self._root_query) if ('query' in self._root_query) and xapian_query: + if not check_xapian_query(xapian_query): + raise ValueError('Invalid Xapian query: %r' % xapian_query) query['query'] = '(%s) AND (%s)' % (self._root_query['query'], xapian_query) return query @@ -1107,3 +1110,23 @@ class FSEmulation(object): def safe_name(name): return name.replace(u'/', u'_') + + +def check_xapian_query(query): + """Return False if Xapian query is invalid + + Return False if the given Xapian query contains incorrectly balanced + parentheses. Return True otherwise. + """ + num_parens = 0 + inside_quote = False + for c in query: + if c == '"': + inside_quote = not inside_quote + elif c == '(' and not inside_quote: + num_parens +=1 + elif c == ')' and not inside_quote: + if num_parens < 1: + return False + num_parens -= 1 + return num_parens == 0 |