使用安全的编码标准来转移安全性,变得越来越重要。请继续阅读,以获得对这个主题的精彩介绍!
在任何编码人员的职业生涯开始时,他们使用字符串在代码中构建查询。在代码而不是数据库中构建字符串时,它被称为“内联SQL”。无论您使用PHP,C#还是其他语言,您都可能使用字符串对象来基于用户输入来构建查询。采取这种方法的问题是,你打开你的应用程序到SQL注入(SQLi)。这对新开发者来说是很常见的,但是即使是最好的开发者也有时会因为糟糕的代码设计而引入漏洞。
了解基本的SQLi在您了解内联SQL引入漏洞之前,您应该首先了解攻击者如何制定策略来查找它们。许多SQLi攻击甚至不是你的定型攻击者在你的网站上寻找漏洞。相反,攻击者可以下载网络上的大量脚本,并在他最喜欢的网站上运行它们。这是SQLi成为黑客入侵网站的一种常用方法。
看看用PHP编写的一个简单的字符串。
$query = 'select username, password from User where user_id='. $_POST['user_id'];在上面的查询中,字符串 $query 是使用标记的用户的文本框输入构建的 user_id。它检索用户的用户名和密码,但是它给攻击者留下了大门。在SQLi中使用此查询,攻击者可能有权访问管理员的凭据。让我们看看如何做到这一点。
而不是在user_id 文本框中输入用户名 ,攻击者可以输入类似于以下内容的内容:
-1 or 1=1; --使用动态构建的PHP字符串将字符串放在一起,以下查询是您发送到数据库的内容:
select username, password from User where userid= -1 or 1=1; --结果是用户数据库的全部内容都被提供给攻击者。“ --'注释掉你可能在声明中的任何其他命令。这是攻击者用来避免任何语法错误的保护措施。
这是一个简单的攻击,但许多其他脚本化的SQL语句可用于测试您的输入。您必须能够使用逻辑(了解如何构建SQL语句)以及一些常用Web语言提供的内置工具来保护您的网站免受这些攻击。
从SQLi保护代码您用来抵御SQLi的方法取决于您正在编程的语言和平台。防御SQLi的一个常用方法是将内联SQL字符串语句从代码移动到数据库存储过程。存储过程将SQL语句翻译为文字,这意味着它不会将SQL语句作为可执行代码进行传输,而是将数据库将用作输入参数的文字字符串值。结果是该语句将不返回任何值。
如果您使用Microsoft .NET,则可以轻松访问ORM(对象关系映射)框架,如实体框架或NHibernate。然后,您可以使用LINQ语句来查询数据库,这些将使注入的SQL语句不可用。
在前面的例子中,PHP被用来构建字符串。使用WordPress时,由于开发人员的限制,PHP中的内联SQL很常见。WordPress经常是有针对性的,因为开发人员上传到WordPress存储库进行公共下载时,无法访问站点数据库以使用存储过程。WordPress开发人员经常使用内联SQL,这就是为什么即使是一些常见的,受欢迎的插件也被攻破的原因。
由于前面章节中以PHP为例,我们使用一个PHP示例来保护内联SQL代码免受注入攻击。PHP开发人员建议使用预准备语句 准备的语句参数化您的查询,这使得它们类似于存储过程。准备好的语句不使用构建字符串的方法,而是使用符号来指示要插入值的位置,并将这些值视为文字。
从PHP 5.x开始,可以使用PDO类来创建预准备语句。我们将使用PDO构建一个从SQLi安全的查询。首先,我们需要创建数据库连接并实例化PDO对象。
$ conn = mysqli_connect($ servername,$ username,$ password);$ pdo = new PDO('mysql:; dbname ='。$ database_name,$ username,$ password);接下来,让我们用上一节中使用的SELECT查询来设置一个准备好的语句。
$ sql = $ pdo-> prepare(“select username,password from User where userid =:id;”);请注意,准备的语句用于:id 指示这是变量所在的位置。通过PDO对象,您可以使用用户的输入为变量赋值。
$ sql - > bindParam(':id',trim($ _POST [ 'user_id' ]));我们使用“修剪”功能从输入中删除任何前导或尾随空格。
即使准备好的声明已经建立,它仍然没有执行。以下语句使用我们首先设置的连接在数据库上执行它。
$ result = $ sql - > execute();如果要将结果打印到屏幕上,可以从预准备语句中获取所有返回的行并使用循环。下面的代码是一个例子。
while($ row = $ result - > fetch_assoc()) { echo $ row [ 'username' ]; }这只是保护你的代码的一个例子。如果您必须在WordPress或任何其他PHP脚本中使用内联SQL,请使用预处理语句,而不是动态构建字符串。您保护您的应用程序和用户数据,并停止许多用于破解网站数据的脚本。