diff --git a/Solr_Base_Query.php b/Solr_Base_Query.php
index 0e57c2f..1059944 100644
--- a/Solr_Base_Query.php
+++ b/Solr_Base_Query.php
@@ -135,6 +135,96 @@ class SolrFilterSubQuery {
   }
 
   /**
+   * Make sure our query matches the pattern name:value or name:"value"
+   * Make sure that if we are ranges we use name:[ AND ]
+   * allowed inputs :
+   * a. bundle:article
+   * b. date:[1970-12-31T23:59:59Z TO NOW]
+   * Split the text in 4 different parts
+   * 1. name, eg.: bundle or date
+   * 2. The first opening bracket (or nothing), eg.: [
+   * 3. The value of the field, eg. article or 1970-12-31T23:59:59Z TO NOW
+   * 4. The last closing bracket, eg.: ]
+   * @param string $filter
+   *   The filter to validate
+   * @return boolean
+   */
+  public static function validFilterValue($filter) {
+    $opening = 0;
+    $closing = 0;
+    $name = NULL;
+    $value = NULL;
+
+    if (preg_match('/(?P<name>[^:]+):(?P<value>.+)?$/', $filter, $matches)) {
+      foreach ($matches as $match_id => $match) {
+        switch($match_id) {
+          case 'name' :
+            $name = $match;
+            break;
+          case 'value' :
+            $value = $match;
+            break;
+        }
+      }
+      // Only allow the regular characters, numeric characters and
+      // + - / . : and spaces
+      if (!drupal_validate_utf8($name)) {
+        return FALSE;
+      }
+
+      // For the value we any character that fits between the A-Z0-9 range and
+      // any alternative for this in other languages.
+      if (preg_match('/^[a-zA-Z0-9_\x7f-\xff]+$/', $value)) {
+        return FALSE;
+      }
+      // Check our bracket count. If it does not match it is also not valid
+      $valid_brackets = TRUE;
+      $brackets['opening']['{'] = substr_count($value, '{');
+      $brackets['closing']['}'] = substr_count($value, '}');
+      $valid_brackets = ($brackets['opening']['{'] != $brackets['closing']['}']) ? FALSE : TRUE;
+      $brackets['opening']['['] = substr_count($value, '[');
+      $brackets['closing'][']'] = substr_count($value, ']');
+      $valid_brackets = ($brackets['opening']['['] != $brackets['closing'][']']) ? FALSE : TRUE;
+      $brackets['opening']['('] = substr_count($value, '(');
+      $brackets['closing'][')'] = substr_count($value, ')');
+      $valid_brackets = ($brackets['opening']['('] != $brackets['closing'][')']) ? FALSE : TRUE;
+      if(!$valid_brackets) {
+        return FALSE;
+      }
+
+      // Check the date field inputs
+      if (preg_match('/\[(.+) TO (.+)\]$/', $value, $datefields)) {
+        // Only Allow a value in the form of
+        // http://lucene.apache.org/solr/api/org/apache/solr/schema/DateField.html
+        // http://lucene.apache.org/solr/api/org/apache/solr/util/DateMathParser.html
+        // http://wiki.apache.org/solr/SolrQuerySyntax
+        // 1976-03-06T23:59:59.999Z (valid)
+        // * (valid)
+        // 1995-12-31T23:59:59.999Z (valid)
+        // 2007-03-06T00:00:00Z (valid)
+        // NOW-1YEAR/DAY (valid)
+        // NOW/DAY+1DAY (valid)
+        // 1976-03-06T23:59:59.999Z (valid)
+        // 1976-03-06T23:59:59.999Z+1YEAR (valid)
+        // 1976-03-06T23:59:59.999Z/YEAR (valid)
+        // 1976-03-06T23:59:59.999Z (valid)
+        // 1976-03-06T23::59::59.999Z (invalid)
+        if (!empty($datefields[1]) && !empty($datefields[2])) {
+          // Do not check to full value, only the splitted ones
+          unset($datefields[0]);
+          // Check if both matches are valid datefields
+          foreach ($datefields as $datefield) {
+            if (!preg_match('/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:[\d\.]{2,6}Z(\S)*)|(^([A-Z\*]+)(\A-Z0-9\+\-\/)*)/', $datefield, $datefield_match)) {
+              return FALSE;
+            }
+          }
+        }
+      }
+    }
+    return TRUE;
+  }
+
+  /**
    * Builds a set of filter queries from $this->fields and all subqueries.
    *
    * Returns an array of strings that can be combined into
@@ -314,32 +404,33 @@ class SolrBaseQuery extends SolrFilterSubQuery implements DrupalSolrQueryInterfa
   }
 
   protected function addFq($string, $index = NULL) {
-    // Gets information about the fields already in solr index.
     $string = trim($string);
     $local = '';
     $exclude = FALSE;
-    if (preg_match('/\({!([^}]+)\}(.*)/', $string, $matches)) {
+    $name = NULL;
+    $value = NULL;
+
+    // Check if we are dealing with an exclude
+    if (preg_match('/^-(.*)/', $string, $matches)) {
+      $exclude = TRUE;
+      $string = $matches[1];
+    }
+
+    // If {!something} is found as first character then this is a local value
+    if (preg_match('/\{!([^}]+)\}(.*)/', $string, $matches)) {
       $local = $matches[1];
       $string = $matches[2];
     }
-    if (preg_match('/(-|)(\(\S+\))/', $string, $matches)) {
-      // Something complicated
-      $exclude = !empty($matches[1]);
-      $this->addFilter('', $matches[2], $exclude, $local);
-    }
-    elseif (preg_match('/(-|)([^:]+):([\("\[].+[\)"\]])/', $string, $matches)) {
-      // Something with a complicated right-hand-side.
-      // Ex.: bundle:(article OR page)
-      // Ex.: title:"double words"
-      // Ex.: field_date:[1970-12-31T23:59:59Z TO NOW]
-      $exclude = !empty($matches[1]);
-      $this->addFilter($matches[2], $matches[3], $exclude, $local);
+
+    // Anything that has a name and value
+    // check if we have a : in the string
+    if (strstr($string, ':')) {
+      list($name, $value) = explode(":", $string, 2);
     }
-    elseif (preg_match('/(-|)([^:]+):(\S+)/', $string, $matches)) {
-      //$index_fields = (array) $this->solr->getFields();
-      $exclude = !empty($matches[1]);
-      $this->addFilter($matches[2], $matches[3], $exclude, $local);
+    else {
+      $value = $string;
     }
+    $this->addFilter($name, $value, $exclude, $local);
     return $this;
   }
 
diff --git a/apachesolr_search.module b/apachesolr_search.module
index 5939f7f..e4c0135 100644
--- a/apachesolr_search.module
+++ b/apachesolr_search.module
@@ -705,6 +705,16 @@ function apachesolr_search_conditions_default($search_page) {
     // Reset the array so that we have one level lower to go through
     $conditions['fq'] = $_GET['fq'];
   }
+  foreach($conditions['fq'] as $condition_id => $condition) {
+    // If the user input does not pass our validation we do not allow
+    // it to query solr
+    if (!SolrBaseQuery::validFilterValue($condition)) {
+      unset($conditions['fq'][$condition_id]);
+    }
+  }
+
+  // Add validation for user input
+  //
   // Custom filters added in search pages
   if (!empty($search_page_fq)) {
     if (!empty($path_replacer)) {
diff --git a/tests/solr_base_query.test b/tests/solr_base_query.test
index abf5eb6..3e90580 100644
--- a/tests/solr_base_query.test
+++ b/tests/solr_base_query.test
@@ -144,5 +144,85 @@ class SolrBaseQueryTests extends DrupalWebTestCase {
     $this->assertEqual(count($query->getParam('fq')), 3, count($query->getParam('fq')) . ' fq params found, expected 3 after adding subquery');
     $this->assertEqual(array('sort_label:hello', 'label:hello', '(access__all:0 OR hash:' . apachesolr_site_hash() . ')'), $query->getParam('fq'));
   }
-}
 
+  function testAddParams() {
+    $examples = array();
+    $examples['{!cache=false}inStock:true'] = array(
+      '#local' => 'cache=false',
+      '#exclude' => FALSE,
+      '#name' => 'inStock',
+      '#value' => 'true',
+    );
+    $examples['{!frange l=1 u=4 cache=false}sqrt(popularity)'] = array(
+      '#local' => 'frange l=1 u=4 cache=false',
+      '#exclude' => FALSE,
+      '#name' => NULL,
+      '#value' => 'sqrt(popularity)',
+    );
+    $examples['{!cache=false cost=5}inStock:true'] = array(
+      '#local' => 'cache=false cost=5',
+      '#exclude' => FALSE,
+      '#name' => 'inStock',
+      '#value' => 'true',
+    );
+    $examples['{!tag=impala}model:Impala'] = array(
+      '#local' => 'tag=impala',
+      '#exclude' => FALSE,
+      '#name' => 'model',
+      '#value' => 'Impala',
+    );
+    $examples['{!anything that appears to be local}'] = array(
+      '#local' => 'anything that appears to be local',
+      '#exclude' => FALSE,
+      '#name' => NULL,
+      '#value' => NULL,
+    );
+    $examples['bundle:(article OR page)'] = array(
+      '#local' => NULL,
+      '#exclude' => FALSE,
+      '#name' => 'bundle',
+      '#value' => '(article OR page)',
+    );
+    $examples['-bundle:(article OR page)'] = array(
+      '#local' => NULL,
+      '#exclude' => TRUE,
+      '#name' => 'bundle',
+      '#value' => '(article OR page)',
+    );
+    $examples['-{!anything that appears to be local}'] = array(
+      '#local' => 'anything that appears to be local',
+      '#exclude' => TRUE,
+      '#name' => NULL,
+      '#value' => NULL,
+    );
+    $examples['title:"double words"'] = array(
+      '#local' => NULL,
+      '#exclude' => FALSE,
+      '#name' => 'title',
+      '#value' => '"double words"',
+    );
+    $examples['field_date:[1970-12-31T23:59:59Z TO NOW]'] = array(
+      '#local' => NULL,
+      '#exclude' => FALSE,
+      '#name' => 'field_date',
+      '#value' => '[1970-12-31T23:59:59Z TO NOW]',
+    );
+    $query = new SolrBaseQuery("apachesolr_tests", new DummySolr());
+    foreach ($examples as $fq => $example) {
+      $query->addParam('fq', $fq);
+      // Check if filter was added
+      $message = t('hasFilter(@name, @value) is True', array('@name' => $example['#name'], '@value' => $example['#value']));
+      $this->assertTrue($query->hasFilter($example['#name'], $example['#value'], $example['#exclude']), $message);
+      $filters = $query->getFilters();
+      $filter = reset($filters);
+      $message = t('The filter "@fq" was added with all the given properties', array('@fq' => $fq));
+      $this->assertTrue(!array_diff($example, $filter), $message);
+      $query->removeFilter($example['#name']);
+      $message = t('The filter "@fq" was correctly removed', array('@fq' => $fq));
+      $this->assertFalse($query->hasFilter($example['#name'], $example['#value'], $example['#exclude']), $message);
+      // Since we cannot remove filters without names yet we have to clear the whole fq array
+      $query->removeParam('fq');
+      // Check the ones without the name also
+    }
+  }
+}
