提问人:Reza 提问时间:10/21/2020 最后编辑:Reza 更新时间:10/21/2020 访问量:485
如何在不使用参数的情况下使 sql 字符串在 vb.net 中安全
How to make sql string safe in vb.net without using parameters
问:
我正在做一个有问题的项目,我几乎通过使用修复了所有注入,有一种情况是构建sql字符串,然后加密并传递给,然后它将从中检索和解密以运行,显然不能在这种情况下使用参数,也无法重构为不传递sql, 唯一的选择是在构建 SQL 语句时尽可能避免注入,或者使用参数,然后获取生成的 SQL 语句并将其传递给视图状态。vb.net
sql innjection
parameters
viewState
viewState
viewState
参数值由字符串和数字混合而成。
例如
sSQL = sSQL & " WHERE Name LIKE '" & lstBrowse.SelectedItem.Value & "%'"
sSQL = sSQL & " WHERE State ='" & lstBrowse.SelectedItem.Value & "'"
sSQL = sSQL & " WHERE OrganizationID=" & lstBrowse.SelectedItem.Value
如何在不使用参数的情况下做到这一点?我应该考虑和避免什么?
答:
好的,我认为问题在于人们假设你不能有“可选”参数,或者你必须提前设置它们。(你没有)。
你可以列出这个:
dim strWhere as string
strWhere = "(State = @State)
cmdSQL.Parmaters.Add("@State",SqlDbType.NVarchar).Value = lstBrowse.SelectedItem.Value
现在,我可以“即时”向 strWhere 添加更多条件,并且随着时间的推移,还可以将 parmaters 添加到 cmdSQL.Parmaters 集合中。
现在,让我们假设你在一些复杂的网格页面上,用户选择了一些东西,现在你需要把这个说法传递给另一个表单?
Well, it gets a wee bit messy to have:
Keep track of some field names
Keep track of some conditions (=, like, etc.)
Keep track of the parameters
但是你肯定可以把一个参数列表“串”在一起,以及一些也与该参数匹配的 sql。因此,没有必要使用 EXISTING 参数对 sql 进行硬编码。
现在,另一个问题是你建议不仅要构建一些动态 sql,而且你需要在会话中传递它(或者你想要这种能力)。
好吧,我只是构建一个非常短的代码的“团块”,将上述所有内容放入一个非常简短和简单的类中。然后将该类推入会话。
因此,将这部分代码放入项目中的一个标准代码模块中。
公共类 SqlParms
Public cmdSQL As New SqlCommand("", GetCon)
Public Where As String
Private m_SQL As String
Public Sub Add(FieldName As String, Cond As String, FieldValue As Object, Datatype As SqlDbType)
Dim mycond As String
Dim prex As String = "", sufx As String = ""
If Left(Cond, 1) = "%" Then prex = "'%' + "
If Right(Cond, 1) = "%" Then sufx = " + '%'"
mycond = Replace(Cond, "%", "")
If Where <> "" Then Where += " AND "
Where += "(" & FieldName & " " & mycond & " " & prex & "@" & FieldName & sufx & ")"
cmdSQL.Parameters.Add("@" & FieldName, Datatype).Value = FieldValue
End Sub
Public Property SQL As String
Get
Return m_SQL
End Get
Set(value As String)
m_SQL = value & " WHERE " & Where
cmdSQL.CommandText = m_SQL
End Set
End Property
End Class
那么,以上都是吗?允许您添加“字段”、“条件”,然后添加更多内容。 这很简单。
所以,现在在代码中,我可以去:
Dim MyParms As New SqlParms
Session("MyParms") = MyParms
现在,请注意,一旦我们将会话指向该类?然后我可以添加/修改当前代码位,而不必将 MyParms 汇集/保存/推回 - 它是一个对象,现在在会话中。
因此,让我们添加您的条件。
MyParms.Add("State", "=", lstBrowse.SelectedItem.Value, SqlDbType.NVarChar)
好的,所以上面的内容不仅被添加,而且在我们的会话中也被添加!!
好的,让我们假设我们有两个条件,第二个条件是 ContactID(数据库中的 PK 值 - 因此是整数数据类型)。 好的,我们现在开始:
MyParms.Add("OrganziationID", "=", lstBrowse.SelectedItem.Value, SqlDbType.Int)
或者也许
MyParms.Add("OrganziationID", "=", droplist1.SelectedValue, SqlDbType.Int)
MyParms.SQL = "SELECT * from tblHotels"
再次:注意运行以上 1 个,还是 2 个条件后?它在 session() 中。
好的,假设我们跳到了一个新的不同页面。现在我们需要填充一个网格。
代码将是:
请注意,下面非常非常小心,我们如何不使用新关键字!
Dim MyParms As SqlParms = Session("MyParms")
Dim rst As New DataTable
Using MyParms.cmdSQL
MyParms.cmdSQL.Connection.Open()
rst.Load(MyParms.cmdSQL.ExecuteReader)
End Using
GridView1.DataSource = rst
GridView1.DataBind()
因此,这个小小的“帮助程序”例程可以让你构建 where 子句。 它在 session() 中,现在您可以将所有这些东西传递/跳转到另一个页面。
人们经常没有意识到的另一件非常有趣的事情? 您始终可以向 sql 命令对象添加参数,并且尚未设置 sql 集。而且您甚至不需要连接集。
因此,您实际上可以转储上述“帮助程序”例程,然后创建一个 sql 命令对象,并将其推送到会话中。
不管以上什么?您不必对 sql 进行预硬编码。这些值可以而且将会成为参数安全(sql注入安全),如果您要添加“可选”参数,这甚至适用。唯一的诀窍是确保你也使用这些可选参数构建 sql。
所以,如果我这样说:
dim MyParms as new SqlParms
MyParms.Add("City", "Like%", "E", SqlDbType.NVarChar)
MyParms.SQL = "SELECT * from tblHotels"
Dim rst As New DataTable
Using MyParms.cmdSQL
MyParms.cmdSQL.Connection.Open()
rst.Load(MyParms.cmdSQL.ExecuteReader)
End Using
GridView1.DataSource = rst
GridView1.DataBind()
因此,上面的内容将用结果表填充我们的数据网格。
上面的 sql 现在是这样的:
SELECT * from tblHotels WHERE (City Like @City + '%')
现在因为我想要“喜欢”的支持?好吧,我无法在参数名称中添加/包含/包含百分比(我使用与前面带有@的字段名称相同的字段名称。
所以,我使用 %like(用于前缀通配符) 和 Like%(后缀)。然后,代码去除 % 并将其正确添加到 where 子句中,如上所述。
因此,您可以在“添加”更多条件时对字符串进行编码。但在所有情况下,使用参数不仅是一个好主意,而且也不是那么难做到。
我在该类中还使用了一个名为 GetCon 的公共函数,该函数仅返回一个连接对象,但您可以将该类中的“GetCon”替换为您自己的例程,该例程返回一个连接字符串,然后用于创建 sqlconneciton 对象。
此外,相当小,但我确实假设 sql 属性设置为 LAST,因为 sql 字符串随后与 where 子句组合在一起。如果添加更多参数,则需要再次设置 sql 属性。
综上所述: 您可以并且应该添加附加值作为参数。我看不出有很多理由不这样做。
如果您需要在一个页面中设置所有这些内容,然后跳转到另一个页面,则可以将这个可爱的助手例程推入会话。(甚至让当前页面允许一些额外的过滤。
评论
Stored Procedure
Parameterized Query