我知道一些开发人员将撇号加倍以减轻 SQLi 的影响。(这是当输入是'所以它变成'')
有没有办法打败这个?
这是在 MS SQL Server 上。
我知道一些开发人员将撇号加倍以减轻 SQLi 的影响。(这是当输入是'所以它变成'')
有没有办法打败这个?
这是在 MS SQL Server 上。
我试图展示安全范围的两面。安全性很重要,因此您不应该只知道如何克服安全性,还应该知道如何实施它。因此,我将首先列出预防措施。如果您不想阅读此内容,请向下滚动。
当涉及到安全性时,将撇号加倍并不是答案,它可能会导致不安全感。答案取决于您使用的编程语言。
请注意,这些在每种语言中都是相同的概念。他们只是有不同的名字。
即使使用准备好的/可调用的语句或参数化查询,以下内容也不正确:
// Bad code, don't use
string sqlString = "SELECT * FROM [table] WHERE [col] = '"+ something +"' AND [col2] = @Param";
您绝不能连接您的 SQL 变量。
使用 SQL Server,根据您选择的语言,您的查询应如下所示:
C#
using (SqlCommand command = new ("SELECT * FROM [tab] WHERE LName = @LName", connection))
{
// Add new SqlParameter to the command.
command.Parameters.Add(new SqlParameter("LName", txtBox.Test));
// Read in the SELECT results.
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
}
}
爪哇
Connection con = DriverManager.getConnection("database-connection-string","name","pass");
// Question marks are the bound variables which are parsed in the defined column order.
PreparedStatement findLName = con.prepareStatement("SELECT * FROM [tab] WHERE LName = ?");
// The order in which the question marks appear. You can have more than one in a prepared statement. First one is "1", second is "2", and so on.
findLName.setString(1, Lastname);
findLName.executeQuery();
Statement stmt = con.createStatement();
PHP
请注意,这仍然不能消除将脚本注入网页的可能性。您可以在可接受的范围内完全按照他们的要求插入,然后将结果输出到 HTML。
如果他们插入以下内容(简化示例):
<script> window.location.href='hxxp://www.mymalwarewebsite.com/'; </script>
...然后您将结果输出到您的页面,那么您就有大麻烦了。那么如果你从<script>
to中删除任何东西</script>
呢?如果他们插入怎么办:
<scri<script>pt> window.location.href='hxxp://www.mymalwarewebsite.com/'; </scri<script>pt>
...?如果您使用替换删除脚本标签,您仍然会被该漏洞利用。
除了上述内容之外,您真正想要的是以下内容:
HtmlEncode
Java Html Sanitizer from OWASP
HtmlEntities
.Ā
A
U+02BC
ʼ
'
U+0027
有没有办法打败这个?
也许(至少对于 MySQL)。这真的很简单(你不需要任何特殊的编码或没有引号,或任何东西):
\' [injection] -- -
例如,您有以下查询:
SELECT FROM table WHERE user = '[INPUT]';
输入是\' [injection] -- -
,但'
加倍后变成:\'' [injection] -- -
,这导致我们进入这个查询:
SELECT FROM table WHERE user = '\'' [injection] -- -';
注入的部分将作为查询执行,因为它不再在引号内。
对 SQL 注入的唯一适当防御是准备好的语句。它们也不难使用,并且通常会产生更好的代码。对于诸如双引号之类的自制防御确实没有很好的借口。
// 更新:这似乎在 MSSQL 中实际上是不可能的。所以这将留下其他答案中已经提到的两个问题:如果在 query 中没有使用引号,或者(可能)对于某些字符集,它仍然很容易受到攻击。
这也取决于加倍实际上是如何发生的。如果它是通过数据库完成的,它可能很容易受到攻击。
这只能防止通过字符串参数进行的 SQL 注入攻击。有时,参数是一个整数(想想http://www.example.org/?page=3
),那么你就不需要撇号了。例如,有时您可以检查参数是否易受攻击,如果您替换page=3
为page=1+2
。