phpsphinxsphinxql

Sphinx - How to escape user input for SphinxQL?


I have website where users can search posts by entering keywords, I am using Sphinx search for full text search, everyhting is working as expected.

But when i enter/input some special charaters in search query the search dosnt complete and throws error.

e.g. keyword i search for :

hello)

my query for sphinxql :

SELECT id FROM index1 WHERE MATCH('hello)') 

error i get :

index index1: syntax error, unexpected ')' near ')'

my php code looks like this

<?php
$sphinxql = mysqli_connect($sphinxql_host.':'.$sphinxql_port,'','') or die('ERROR'); 
$q = urldecode($_GET['q']);
$sphinxql_query = "SELECT id FROM $sphinx_index WHERE MATCH('".$q."') ";
?>

How can i escape user input and make sure the query wont brake and return the result set ?


Solution

  • You should use SQL escaping, to avoid SQL injection.

    http://php.net/manual/en/mysqli.real-escape-string.php

    $sphinxql_query = ".... MATCH('".mysqli_real_escape_string($sphinxql,$q)."') ";
    

    ... BUT you may want to ALSO, escape extended syntax.

    See the FIRST THREE POSTS (after that it delves into misunderstanding) in this thread in the sphinx forum http://sphinxsearch.com/forum/view.html?id=13619

    For a simple solution.

    The function in that thread, can be used to make your query work. It will escape the ) and stop it being taken as a operator.


    BUT, it also means you WONT be able to use any search operators - because it blindly escapes them ALL. (which is the confusion later in the thread)

    If you want to be able to use some or all operators, need to use more advanced escaping. (which I dont have a good solution for)


    Edit: actully lets go the whole hog...

    <?php
    
    //Escapes all the Extended syntax, so can accept anything the user throws at us. 
    function EscapeString ( $string ) {
       $from = array ( '\\', '(',')','|','-','!','@','~','"','&', '/', '^', '$', '=' );
       $to = array ( '\\\\', '\(','\)','\|','\-','\!','\@','\~','\"', '\&', '\/', '\^', '\$', '\=' );
       return str_replace ( $from, $to, $string );
    }
    
    if ($allow_full_extended_syntax) {
       $q = $_GET['q']; 
       // the user is responsible for providing valid query.
    } elseif ($allow_partical_extended_syntax) {
       $q = InteligentEscape($_GET['q']); 
       //I don't have this function, it would need to be created. 
    } else {
       $q = EscapeString($_GET['q']); 
       // escapes ALL extended syntax. NO operators allowed 
    }
    
     $sphinxql_query = ".... MATCH('".mysqli_real_escape_string($sphinxql,$q)."') ";
    

    Then it sounds like you want both $allow_full_extended_syntax and $allow_partical_extended_syntax set to false. Which means no operators will work, because they will be fully escaped.