如何避免 SQL 注入攻击?
Posted
技术标签:
【中文标题】如何避免 SQL 注入攻击?【英文标题】:How can I avoid SQL injection attacks? 【发布时间】:2011-01-13 02:28:33 【问题描述】:昨天我与一位开发人员交谈,他提到了一些关于限制数据库字段插入的内容,例如--
(减号)等字符串。
在同一类型中,我知道这是一个很好的方法来转义 html 字符,如 <
、>
等,而不是 --
。这是真的?我需要担心--
、++
吗?它更像是神话还是旧事物?
更新
非常感谢所有的答案,这样很容易理解,因为我对所有这些都是新手。 好吧,更具体地说,在这种情况下,我们的讨论是关于我们正在开发的 C# ASP.NET MVC 网站,所以那里有一个复杂的开户表单,其中包含重要信息,所以我不确定 MVC 是否使用 Linq与数据库的接口是否已经带有这种保护。因此,如果有人可以提供一些关于它的提示,那就太好了。 再次感谢
【问题讨论】:
强制:xkcd.com/327 就是说,限制可以放入数据库的内容并不是一个非常普遍甚至安全的方法。您如何从用户输入到数据库插入? 这不是您在字段中放置的内容,而是您将其放置在那里的方式(以及显示字段内容的方式) -- 在 MS SQL Server 中开始单行注释(也包括其他数据库包)。 我根据您增加的细节更新了我的答案,特别是使用 ASP。 【参考方案1】:避免 SQL 注入攻击的正确方法不是简单地禁止某些有问题的字符,而是使用参数化 SQL。简而言之,参数化 SQL 会阻止数据库将原始用户输入作为 SQL 命令的一部分执行,这会阻止像“drop table”这样的用户输入被执行。只是转义字符并不能阻止所有形式的 SQL 注入攻击,并且排除某些单词(例如“Drop”)并非在所有情况下都有效;在某些字段中,“Drop”是数据输入的完全有效部分。
您可以在这里找到一些关于参数化 SQL 主题的好文章:
https://blog.codinghorror.com/give-me-parameterized-sql-or-give-me-death/
http://www.codeproject.com/KB/database/ParameterizingAdHocSQL.aspx
既然您提到您正在使用 ASP.net,我可以为您提供一些专门处理 ASP 中的 SQL 注入的链接。
https://dzone.com/articles/aspnet-preventing-sql-injectio https://www.c-sharpcorner.com/UploadFile/75a48f/how-sql-injection-can-be-possible-in-asp-net-websites/
这里有一篇关于使您的 ASP 更安全的更一般的文章: http://www.codeproject.com/KB/web-security/Securing_ASP_NET_Apps.aspx
当然还有关于 SQL 注入的 MSDN 文章: http://msdn.microsoft.com/en-us/library/ms998271.aspx
【讨论】:
非常感谢比尔,它帮助了我很多:)【参考方案2】:对于大多数允许用户将参数注入在数据库上执行的语句中的网站来说,SQL 注入是一种高安全风险。
一个简单的例子是:
输入字段“姓名:_________
"SELECT * FROM tblCustomer WHERE Name = '" + nameInputField + "'"
所以如果我输入“Bob”,我们就有
"SELECT * FROM tblCustomer WHERE Name = 'Bob'"
但是如果我输入“'; DROP TABLE tblCustomer”,我们最终会得到更险恶的
"SELECT * FROM tblCustomer WHERE Name = ''; DROP TABLE tblCustomer"
有很多方法可以避免这些问题,而且很多方法都内置在您使用的任何语言中 - 因此,与其考虑所有不可靠的可能性“;”、“--”、“/*”等,请尝试并使用已经存在的东西。
说出您使用的语言,我相信我们可以告诉您如何避免这些攻击。
【讨论】:
【参考方案3】:他说的是SQL Injection 攻击,正如他所说的那样。
问题不在于数据库中存在此类数据,而在于将输入数据直接传递到数据库而不对其进行清理。
如果不清理它,如果有人传入一个以 ;
结尾的字符串,他们就可以随心所欲地跟随它(例如select * from sys.objects
)或更恶意的东西,比如删除一些表格。
很难完全防范,但如果您从代码中使用良好的数据库库并遵循已知做法,例如使用参数化查询,则可以限制可能的损害。
在您的数据库中存储任意数量的--
,但不要在没有经过清理过程的情况下将其传递到您的数据库(这是一个好的数据库库至关重要的地方 - 它应该清理引号和其他可能有害的输入)。
【讨论】:
【参考方案4】:在数据库中插入包含--
的字符串并没有什么“危险”。
将任何东西插入直接来自用户输入而不对其进行处理的数据库表中是很危险的,否则你会让自己打开SQL injection attacks。示例:编码员让用户在字段中输入他们的姓名,然后用户输入:
Joe '); drop table users; commit transaction; --
然后编码员将其放入他们的 mysql 数据库中,如下所示:
conn.execute("insert into users (username) values ('" + userInput + "')");
Boom 用户已经删除了 users 表(假设数据库登录有权这样做,但它不应该这样做——但这是一个不同的话题),因为编码器没有确保来自用户的字符串被正确转义,因此它被直接发送到数据库引擎,攻击者笑得很开心。 :-)
使用您的环境提供的任何工具来确保正确转义字符串。例如,JDBC 为此使用PreparedStatement
类。大多数环境都会有类似的东西。
【讨论】:
【参考方案5】:使用参数化查询。这些查询将变量表示为 SQL 中的占位符,例如 select * from person where name = ?
。创建 SQL 查询后,您可以在查询中设置参数值。参数化查询确保替换占位符的任何内容都不会被视为 SQL 语句的一部分。
请参阅Jeff Atwood's article,了解参数化查询的概览。
【讨论】:
【参考方案6】:只要在进行INSERT/UPDATE/...时正确转义数据就没有危险
转义 HTML 字符不是是一个好方法。想象一下,您编写了一个转义此类字符的函数,并且您在数据库中存储了一些转义文本。然后你注意到你的函数没有转义'NEVER 在将文本存储到数据库之前对其进行转义(当然是转义 SQL 查询)。转义应该发生在 HTML/XML/... 页面从文本中产生时,即从数据库中查询到原始文本之后!
【讨论】:
以上是关于如何避免 SQL 注入攻击?的主要内容,如果未能解决你的问题,请参考以下文章
如何在我的 ASP.NET 应用程序中避免 SQL 注入攻击?
如何实现php的安全最大化?怎样避免sql注入漏洞和xss跨站脚本攻击漏洞