sql注入攻击只对具有表单的页面构成威胁吗?

时间:2009-11-11 17:56:57

标签: sql security web-applications sql-injection

我知道这是一个简单的问题,但在我读过的所有内容中,我从未见过这个具体的问题。

如果您在页面上进行查询,是否需要担心SQL注入攻击?或者,当您要求用户输入时,这只是一个问题吗?

谢谢!

13 个答案:

答案 0 :(得分:15)

您不必让用户输入遭受SQL注入攻击。

假设您有一个使用以下网址调用的产品页面:

product.aspx?ID=123

在您的代码中,您有一个构造如下的查询:

string sql = "SELECT * FROM Products WHERE ID = " + Request.Querystring["ID"];

有人可以使用此网址调用您的网页:

product.aspx?ID=123;DROP Table Students;

而且,你刚刚过去了。

除了可以通过用户,查询字符串,帖子,cookie,浏览器变量等传递的ANYTHING之外,我认为总是使用参数是一种好习惯,即使你的代码中有文字也是如此。例如:

if(SomeCondition)
{
    sql = "Select * from myTable where someCol = 'foo'";
}
else
{
    sql = "Select * from myTable where someCol = 'bar'";
}

这可能是注入安全的,但您的RDBMS会将它们缓存为两个不同的查询。 如果你把它告诉它:

sql = "Select * from myTable where someCol = @myParam";
if(SomeCondition)
{
   myCommand.Parameters.Add("@myParam").value = "foo";
}
else
{
   myCommand.Parameters.Add("@myParam").value = "bar";
}

您实现了相同的结果,但RDBMS只会将其作为一个查询进行缓存,并在运行时替换该参数。我使用它作为经验法则总是使用参数化查询,只是为了保持一致,更不用说略微缓存改进了。

答案 1 :(得分:4)

SQL注入是由未经过数据处理的数据引起的。您始终应始终清理进入数据库的数据。不仅适用于SQL注入,还适用于使您的应用程序正常工作。

例如,某些系统不会使用我的名字,因为它有一个'字符,并且它们的数据库没有被清理。我没有输入我的名字,我的名字来自另一个数据库。无所谓 - 数据应该被消毒。

答案 2 :(得分:3)

SQL注入代码片段也可以来自使用GET方法传递的QueryString (又名“URL参数”)

正如比利奥尼尔所暗示的那样[单引号;-)],任何不是程序固有的数据(或其非常可靠的后端)都应该“消毒”。 Sanitizing 一词似乎意味着是一个复杂的过程,但实际上它通常意味着: [可能因您的特定SQL服务器而异]

  • 删除(或转义)字符串中嵌入的单引号字符
  • 来自字符串的监视超出了基础SQL列的长度(特别是如果这样的长度很长)

认为HTTP Forms是SQL注入片段的唯一来源的一个可能原因是-valid-建议是确保从Request的表单中专门获取用户提供的提交文本。多个Web应用程序框架将HTTP请求公开为一个对象,该对象默认公开来自QueryString,Form或甚至Cookie的所有键值对,可从单个哈希中访问。虽然这对于有时从表单中有时从查询字符串获取信息的应用程序来说是实用的,但这可以促进可能成为注入器的工作,因为它比表单更容易制作URL。 (但是使用适当的工具,也可以伪造POST请求......)

答案 3 :(得分:2)

不,还有其他一些案例。例如,您可能将某些变量作为传递到php页面的查询字符串。 'user'可以修改该字符串以包含一些狡猾的脚本。

http://en.wikipedia.org/wiki/SQL_injection包含大量关于漏洞类型以及如何有效打击漏洞的内容。

答案 4 :(得分:2)

总结一下 - 在SQL查询中使用的任何类型的用户输入都是sql注入的潜在目标

答案 5 :(得分:1)

另请考虑防范cross-site-scripting ("XSS")

答案 6 :(得分:1)

如果您使用来自浏览器的任何类型的数据,则可以进行SQL注入。它可以是表单数据,查询字符串数据,cookie值,甚至是请求标头中的数据。

显而易见的方法是表单数据和查询字符串数据,但是来自浏览器的任何内容都可能被欺骗。

答案 7 :(得分:1)

代码从HTTP请求获取的任何内容都可以是SQL注入向量:

  • POST / PUT内容
  • 获取网址参数
  • 缓存

在更高级别,这些显示为$ _REQUEST或Page.Request值,会话变量,这一切都取决于一系列因素。但最终,只是POST表单。虽然最普遍的向量可能是形成POST内容和GET URL变量。

答案 8 :(得分:0)

当用户可以修改查询参数的值时,它就会成为威胁。

答案 9 :(得分:0)

如果您在页面上显示的数据来自用户提交的数据,则需要担心cross site scripting (XSS)次攻击。

ESCAPE INPUT,过滤器输出

答案 10 :(得分:0)

我担心你永远不要相信这些变量:$ _POST,$ _GET,$ _REQUEST,$ _COOKIE甚至$ _SERVER都可能包含恶意代码。因此,请始终确保插入的数据符合您的预期。 例如,作为验证电子邮件地址的额外偏执措施,您可以使用md5加密电子邮件地址,如下所示:

"SELECT username FROM users WHERE MD5(email)='" . md5($_POST['email']) . "' AND active=1"

答案 11 :(得分:0)

作为一般规则,应始终使用参数化查询。

  1. 它可以防止针对您的数据库执行恶意用户输入(SQL注入攻击)。 [您还应该进行用户输入验证,以确保不在页面上呈现恶意代码,并且可以针对您的服务器运行JavaScript。]
  2. 它使您可以重复使用查询。
  3. 您可以预先编译查询。
  4. 它组织您的输入并使其更具可读性。您可能希望在多个位置使用相同的参数。
  5. 它更好地支持不同的数据类型,如日期,字符串等。使用参数化查询时,不会遇到奇怪字符的问题。
  6. 在我的用例中,我总是生成基于参数的查询。我有一个总是会编译它们的包装器,这样如果第二个查询在同一个请求路径中执行,它将在同一个连接上运行得更快。这需要相当多的工作来设置,但值得在任何中型到企业级系统中获得性能提升。

答案 12 :(得分:0)

我同意参数化是最好的方法。

作为替代方案(可能更容易适应代码,至少最初)将字符串中的单引号加倍会阻止SQL注入。

以Neil N为例:

sql = "Select * From Products Where ID = " + Request.Querystring["ID"]; 

将变量包装在一个使引号加倍的函数中,并用单引号包装变量。

sql = "Select * From Products Where ID = " 
    + fnSQLSafeParam(Request.Querystring["ID"]);

该函数类似于(VBscript示例):

Function fnSQLSafeParam(ByVal strStr)
  If IsNull(strStr) or IsEmpty(strStr) then strStr = ""
  fnSQLSafeParam = "'" & replace(Trim(CStr(strStr)), "'", "''") & "'"
End Function