如果不在我的系统的一部分(使用 Postgres)中编写一些动态 sql 条件,我就无法逃脱。
我的问题是如何最好地避免使用我目前使用的方法进行 SQL 注入。
编辑(推理):许多表中有许多列(一个(仅)增长并在其他地方维护的数字)。我需要一种方法来允许用户决定他们想要查询哪个(预定义)列(并在必要时应用字符串函数)。查询本身对于用户来说太复杂了,无法自己编写,他们也无权访问数据库。有 1000 名用户有不同的要求,我需要尽可能保持灵活性——除非主查询需要更改,否则我不应该重新访问代码——此外,无法知道用户需要什么条件采用。
我有对象(通过 Web 服务接收)为一些大型 sql 查询生成条件(生成方法如下 - 它还不完美)。
这_FieldName
是用户可编辑的(参数名称是,但它不需要),我担心它可能是一个攻击媒介。我在字段名称周围加上双引号(请参阅带引号的标识符)以尝试清理字符串,这样它就永远不会成为关键字。我还可以根据字段列表查找字段名称,但很难及时维护。
不幸的是,用户必须输入条件标准,我确定必须有更多我可以添加到 sanatize 方法?并引用列名使其安全吗?(我有限的测试似乎是这样认为的)。
一个示例构建条件是“AND upper(brandloaded.make) like 'O%' and upper(brandloaded.make) not like 'OTHERBRAND'”...
任何帮助或建议表示赞赏。
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