summaryrefslogtreecommitdiff
path: root/modules/search/search.extender.inc
diff options
context:
space:
mode:
Diffstat (limited to 'modules/search/search.extender.inc')
-rw-r--r--modules/search/search.extender.inc25
1 files changed, 25 insertions, 0 deletions
diff --git a/modules/search/search.extender.inc b/modules/search/search.extender.inc
index b7af4d06a..ad4b86e89 100644
--- a/modules/search/search.extender.inc
+++ b/modules/search/search.extender.inc
@@ -123,6 +123,16 @@ class SearchQuery extends SelectQueryExtender {
protected $multiply = array();
/**
+ * Whether or not search expressions were ignored.
+ *
+ * The maximum number of AND/OR combinations exceeded can be configured to
+ * avoid Denial-of-Service attacks. Expressions beyond the limit are ignored.
+ *
+ * @var boolean
+ */
+ protected $expressionsIgnored = FALSE;
+
+ /**
* Sets up the search query expression.
*
* @param $query
@@ -183,7 +193,17 @@ class SearchQuery extends SelectQueryExtender {
// Classify tokens.
$or = FALSE;
$warning = '';
+ $limit_combinations = variable_get('search_and_or_limit', 7);
+ // The first search expression does not count as AND.
+ $and_count = -1;
+ $or_count = 0;
foreach ($keywords as $match) {
+ if ($or_count && $and_count + $or_count >= $limit_combinations) {
+ // Ignore all further search expressions to prevent Denial-of-Service
+ // attacks using a high number of AND/OR combinations.
+ $this->expressionsIgnored = TRUE;
+ break;
+ }
$phrase = FALSE;
// Strip off phrase quotes.
if ($match[2]{0} == '"') {
@@ -212,6 +232,7 @@ class SearchQuery extends SelectQueryExtender {
}
$this->keys['positive'][] = $last;
$or = TRUE;
+ $or_count++;
continue;
}
// AND operator: implied, so just ignore it.
@@ -231,6 +252,7 @@ class SearchQuery extends SelectQueryExtender {
}
else {
$this->keys['positive'] = array_merge($this->keys['positive'], $words);
+ $and_count++;
}
}
$or = FALSE;
@@ -323,6 +345,9 @@ class SearchQuery extends SelectQueryExtender {
form_set_error('keys', format_plural(variable_get('minimum_word_size', 3), 'You must include at least one positive keyword with 1 character or more.', 'You must include at least one positive keyword with @count characters or more.'));
return FALSE;
}
+ if ($this->expressionsIgnored) {
+ drupal_set_message(t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', array('@count' => variable_get('search_and_or_limit', 7))), 'warning');
+ }
$this->executedFirstPass = TRUE;
if (!empty($this->words)) {