diff options
author | Sascha Silbe <sascha-pgp@silbe.org> | 2013-08-12 15:31:07 (GMT) |
---|---|---|
committer | Sascha Silbe <sascha-pgp@silbe.org> | 2013-08-12 15:36:27 (GMT) |
commit | d376573d35e336aa5d05deb95cd209304357c092 (patch) | |
tree | 87a80498fa6f295b115284953cc4cf217f9f6c2c | |
parent | 97d361c4963fe56bfdc53ffe110825dc08e525c6 (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 0eeca9b..fb6ba39 100644 --- a/fsemulation.py +++ b/fsemulation.py @@ -20,6 +20,7 @@ import stat import time import dbus +import xapian import sugar.mime @@ -446,6 +447,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 @@ -1074,3 +1077,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 |