SQL注入即使在转义引用时也是如此

时间:2015-08-28 05:26:01

标签: security asp-classic sql-injection

我正试图想办法解决以下问题,因为它看起来像某人,我想解决它。但是,我真的想了解攻击是如何工作的,然后用OWASP Recommendation

修复它
    Set conn = Server.CreateObject("ADODB.Connection")
    conn.open xDb_Conn_Str
    sSql = "SELECT * FROM [User]"
    sSql = sSql & " WHERE [Username] = '" & CleanSql(sUserId) & "'"
    Set rs = conn.Execute(sSql)

CleanSql -

Function CleanSql(str)

    Dim sWrk

    sWrk = Trim(str&"")
    sWrk = Replace(sWrk, "'", "''") ' Adjust for Single Quote

    sWrk = Replace(sWrk, "[", "[[]") ' Adjust for Open Square Bracket

    CleanSql = sWrk

End Function

单引号显然在此被转义。

在此之后,它会检查用户是否通过以下方式验证密码:

If UCase(rs("Password")) = UCase(sPassWd) Then
    DoStuff()

感谢任何帮助。

4 个答案:

答案 0 :(得分:4)

由于听起来你已经意识到准备/参数化陈述的好处,我不会宣讲。您似乎只是好奇您现有的应用程序是如何被破坏的。

一个简单的\' ; drop table users --可以击败你的报价加倍。您的CleanSql()功能会将其转换为:

\'' ; drop table users --

您的SQL语句将变为:

... WHERE [Username] = '\'' ; drop table users --'

由于'\''是有效值(转义单引号),因此where子句有效结束。 ;启动一个新命令,--有效地注释结束语。 drop table可以是任何内容...... update users set password=...insert into users values ()或攻击者想要运行的任何内容。

答案 1 :(得分:2)

你应该始终使用Prepared statement,因为在大多数情况下逃避不足,因为总会有特殊情况你会忘记。

Dim cmdPrep1 As New ADODB.Command
Set cmdPrep1.ActiveConnection = conn

cmdPrep1.CommandText = "SELECT * FROM [User]  WHERE [Username] = ?"
cmdPrep1.CommandType = adCmdText
cmdPrep1.Prepared = True

Set prm1 = cmdPrep1.CreateParameter("Username", adChar, adParamInput, Len(sUserId), sUserId)
cmdPrep1.Parameters.Append prm1

Set rs = cmdPrep1.Execute()

如果准备好的语句不适用于您的语言或数据库,请强烈考虑切换 请参阅此wikipedia article以查看为什么预准备语句更安全,但其要点是参数与查询分开传递,因此避免在查询中嵌入utrusted string

答案 2 :(得分:1)

只是因为这不适用于the ESCAPE keyword is used

此外,您的CleanSql函数不适用于未加引号的值(例如数值)。

这就是建议使用参数化查询的原因 - 这些查询将值视为数据而不是查询的一部分。

有时您无法使用参数化,例如,如果您动态更改ORDER BY,或者您想动态更改从中读取数据的表。在这些情况下,您应该使用白名单来确保应用程序允许动态数据。您无法使用参数化的另一种情况是有IN子句时。这是您的CleanSql函数有用的地方 - 请注意,您不需要括号转义 - 这仅适用于未指定转义字符的LIKE个查询。

答案 3 :(得分:0)

一种简单的方法:System.out.println