Forum Discussion

octavian_krody's avatar
3 years ago

How to escape user input in built liql query

Escaping id with js_string or any other escape mechanism change the semantics of what was asked from the user, while not doing it will cause invalid syntax in queries.

Given the input '123' quotes included and the following code snippet.

 

<#assign id = http.request.parameters.name.get("id", "") />
<#assign query = "/search?q=" + "SELECT * FROM messages where id='${id}'"?url />
${restd("2.0", query, "json")}

produces

{ "status" : "error", "message" : "Invalid query syntax", "data" : { "type" : "error_data", "code" : 603, "developer_message" : "line 1, column 35:\nwhitespaces, regexParser: (AND|OR) , regexParser: ORDER BY, regexParser: LIMIT, regexParser: OFFSET, regexParser: CURSOR or EOF expected, 1 encountered. in: SELECT * FROM messages where id=''123''", "more_info" : "" }, "metadata" : { } }

 

Is there any recommended way of doing such operations?

  • MattV's avatar
    MattV
    Khoros Staff

    It certainly depends on the type of input you're expecting.

    For integers, I recommend something like this

    <#assign id = http.request.parameters.name.get("id", "") />
    <#attempt>
        <#assign id = id?number />
    <#recover>
        <#assign id = 0 />
    </#attempt>

     

    And the reason I wrap that in an attempt/recover is because if id isn't a valid number, Freemarker will throw an exception. But we can catch that and set a default.

    You can then check, if id == 0, then don't run the rest of your code because something is wrong.

    For strings, if you know to expect a certain set of values, I'd verify it's from the expected set of values. If it's an arbitrary value, you can escape it with ?html which will convert most characters to it's HTML-entity equivalent, and should protect you from the most common problems.

  • The method of escaping data is dictated by how you use said data.
    If I want to dump it in html and if it is user input I need to escape html markup.
    If I want to dump the data in json fields I need to escape by json rules.

    My question what escape mechanism should I use when I dump the input in liql?

    My input can be a number, text, html it doesn't matter all it matters to me is that the liql query is formed correctly. I know that liql only shows data you can see by enforcing rules but consider the following use case.

    I query if a user can see some content so I can enhance said content's body (this is outside of the scope of server side rendering and can only be done through an ajax call, so I cannot use anything like message / user info, from the available contexts because there aren't any.

    If I then query by some custom identifier passed through an ajax parameter to see if he has permissions by dumping that into liql (check if he has something returned by the query) I might end up in having the following situation. If he adds a specific string that would change my query during the string concatenation to return something else he has rights to, then I can't tell if he should be allowed to see the fields or the target in the first place.
    Even though the query returns data he is able to see it may not be the info I am supposed to check against.