Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent SQL Injection in Dynamic column names

I can't get away without writing some dynamic sql conditions in a part of my system (using Postgres).

My question is how best to avoid SQL Injection with the method I am currently using.

EDIT (Reasoning): There are many of columns in a number of tables (a number which grows (only) and is maintained elsewhere). I need a method of allowing the user to decide which (predefined) column they want to query (and if necessary apply string functions to). The query itself is far too complex for the user to write themselves, nor do they have access to the db. There are 1000's of users with varying requirements and I need to remain as flexible as possible - I shouldn't have to revisit the code unless the main query needs to change - Also, there is no way of knowing what conditions the user will need to use.

I have objects (received via web service) that generates a condition (the generation method is below - it isn't perfect yet) for some large sql queries.

The _FieldName is user editable (parameter name was, but it didn't need to be) and I am worried it could be an attack vector. I put double quotes (see quoted identifier) around the field name in an attempt to sanitize the string, this way it can never be a key word. I could also look up the field name against a list of fields, but it would be difficult to maintain on a timely basis.

Unfortunately the user must enter the condition criteria, I am sure there must be more I can add to the sanatize method? and does quoting the column name make it safe? (my limited testing seems to think so).

an example built condition would be "AND upper(brandloaded.make) like 'O%' and upper(brandloaded.make) not like 'OTHERBRAND'" ...

Any help or suggestions are appreciated.

Public Function GetCondition() As String
   Dim sb As New Text.StringBuilder

   'put quote around the table name in an attempt to prevent some sql injection
   'http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html
   sb.AppendFormat(" {0} ""{1}"" ", _LogicOperator.ToString, _FieldName)

   Select Case _ConditionOperator
      Case ConditionOperatorOptions.Equals
          sb.Append(" = ")

      ...

   End Select

   sb.AppendFormat(" {0} ", Me.UniqueParameterName) 'for parameter

   Return Me.Sanitize(sb)

End Function

Private Function Sanitize(ByVal sb As Text.StringBuilder) As String

   'compare against a similar blacklist mentioned here: http://forums.asp.net/t/1254125.aspx

    sb.Replace(";", "")
    sb.Replace("'", "")
    sb.Replace("\", "")
    sb.Replace(Chr(8), "")

    Return sb.ToString

End Function

Public ReadOnly Property UniqueParameterName() As String
     Get
         Return String.Concat(":" _UniqueIdentifier)
     End Get
End Property
like image 324
Mr Shoubs Avatar asked Jun 08 '12 17:06

Mr Shoubs


1 Answers

You can get the column names from the database and compare to check the user has entered a valid column name.

like image 118
Andrew Morton Avatar answered Sep 30 '22 19:09

Andrew Morton