如何避免SQL注入攻击?

时间:2010-02-04 14:16:49

标签: database escaping sql-injection protection

昨天我和一位开发人员谈过,他提到了限制数据库字段插入的问题,比如--等字符串(减去负号)。

在同一类型中,我所知道的是,这是一种很好的方法来逃避像<>之类的HTML字符等。不是--。这是真的?我是否需要担心--++?它更像是神话还是旧东西?


更新

非常感谢所有的答案,这很容易理解,因为我对这一切都很陌生。 好吧,在这种情况下更具体一点,我们的讨论是关于和我们正在开发的C#ASP.NET MVC网站,因此有一个复杂的开放帐户表单中有重要信息,所以我不确定MVC是否使用Linq来与数据库的接口是否已经带有这种保护。所以如果有人能提供一些关于它的提示,那就太好了。 再次感谢

6 个答案:

答案 0 :(得分:8)

避免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 http://www.codeproject.com/KB/aspnet/SQL_Injection_.aspx?msg=3209511

这是一篇关于使您的ASP更安全的更一般的文章: http://www.codeproject.com/KB/web-security/Securing_ASP_NET_Apps.aspx

当然,关于SQL注入的MSDN文章: http://msdn.microsoft.com/en-us/library/ms998271.aspx

答案 1 :(得分:6)

对于大多数允许用户将参数喷射到在数据库上执行的语句的网站,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"

有很多方法可以避免这些问题,而且许多方法都是用你正在使用的语言构建的 - 所以不要想到所有狡猾的可能性“;”,“ - ”,“/ *”等,试试看使用已经存在的东西。

喊出你正在使用的语言,我相信我们可以告诉你如何避免这些攻击。

答案 2 :(得分:3)

他正在谈论SQL Injection攻击,正如他所说的那样。

问题不在于数据库中存在此类数据,而在于将输入数据直接传递到数据库而不对其进行清理。

如果有人传入一个以;结尾的字符串,那么他们就可以按照他们想要的任何内容(例如select * from sys.objects)或更恶意的内容(例如丢弃一些表格)进行清理

很难完全防范,但如果您使用代码中的良好数据库并遵循已知的做法,例如使用paremeterized查询,则可以限制可能的损坏。

根据需要在数据库中存储尽可能多的--,但不要将其传递到数据库而不经过清理过程(这是一个好的数据库库至关重要的地方 - 它应该清理引号和其他可能有害的输入)。

答案 3 :(得分:3)

在数据库中插入包含--的字符串没有任何“危险”。

任何插入直接来自用户输入的数据库表中而不进行处理是危险的,否则您将自己置于SQL injection attacks。示例:编码器允许用户在字段中键入其名称,用户键入:

Joe '); drop table users; commit transaction; --

然后编码器将它放在他们的MySQL数据库中,如下所示:

conn.execute("insert into users (username) values ('" + userInput + "')");

Boom 用户已经删除了users表(假设数据库登录有权这样做,它不应该 - 但这是一个不同的主题),因为编码器无法确保来自用户的字符串被正确转义,因此它被直接发送到数据库引擎,攻击者笑得很开心。 : - )

使用您的环境提供的任何工具来确保正确转义字符串。例如,JDBC为此使用PreparedStatement类。大多数环境都会有类似的东西。

答案 4 :(得分:3)

使用参数化查询。这些查询将变量表示为SQL中的占位符,例如select * from person where name = ?。创建SQL查询后,在查询中设置参数值。参数化查询确保替换占位符的内容不会被视为SQL语句的一部分。

有关参数化查询的详细概述,请参阅Jeff Atwood's article

答案 5 :(得分:1)

只要在执行INSERT / UPDATE /..时正确转义数据就没有危险。

转义HTML字符 NOT 是一种很好的方法。想象一下,你写了一个函数来逃避这些字符,你已经在数据库中存储了一些转义文本。然后你注意到你的函数没有转义'&lt;',所以你改变了函数......现在数据库中已有的记录会发生什么? - 他们的'&lt;'人物将保持未转义状态。 因此, NEVER 在将文本存储到数据库之前转义文本(当然,转义SQL查询)。当从文本中生成HTML / XML / ...页面时,即在从数据库查询原始文本之后,应该发生转义!