2

I have a prepare and a query function in go and when I place the ? in the search it works fine. When I try and do a contains search with the % I get sql: statement expects 0 inputs; got 1

How can I do this type of query without having the variables directly in the SQL? I want to prevent SQL injection . Thank You for your help.

I am using go version go1.8.1 darwin/amd64 and using MySQL

My Go Code:

stmt, err := dBusers.Prepare("SELECT id, name, email, username FROM users WHERE name LIKE '%?%';")
    if err != nil {
        logging.LogError("Could Not Query All Users: "+err.Error())
        return nil, errors.New("Could Not Query Users")
    }
    rows, err := stmt.Query(name)
Trevor V
  • 1,958
  • 13
  • 33
  • 2
    http://stackoverflow.com/questions/19730941/how-to-use-wildcards-in-sql-query-with-parameters suggests making your parameter argument (in this case, `name`) include the wildcards instead of the query. So `stmt.Query("%" + name + "%")`. This still prevents injection, because it's still being sent as a parameter instead of inline with the query. – Kaedys May 09 '17 at 19:55

2 Answers2

3

Reposting my comment as an answer so this question actually has one:

This answer suggests making your parameter argument (in this case, name) include the wildcards instead of the query. So stmt.Query("%" + name + "%"). This still prevents injection, because it's still being sent as a parameter instead of inline with the query.

Community
  • 1
  • 1
Kaedys
  • 9,600
  • 1
  • 33
  • 40
0

You could either make the whole %searchValue% a parameter value itself, or use string concatenation for it inside the query itself.

Approach 1 (recommended):

stmt, err := dBusers.Prepare("SELECT id, name, email, username FROM users WHERE name LIKE ?;")
    if err != nil {
        logging.LogError("Could Not Query All Users: "+err.Error())
        return nil, errors.New("Could Not Query Users")
    }
    rows, err := stmt.Query("%" + name + "%")

Approach 2:

stmt, err := dBusers.Prepare("SELECT id, name, email, username FROM users WHERE name LIKE '%' + ? + '%';")
    if err != nil {
        logging.LogError("Could Not Query All Users: "+err.Error())
        return nil, errors.New("Could Not Query Users")
    }
    rows, err := stmt.Query(name) 

I would recommend the first approach because it wouldn't force you to always use a "contains' search. You could selectively use the same statement to do exact (just name), begins with (name+"%"), ends with ("%"+name) or contains ("%"+name+"%") searches.

PS: Thinking about it, the second approach might lead to injection, not sure, need to think about it more.

Cetin Basoz
  • 22,495
  • 3
  • 31
  • 39