相对于其他几种语言来说, PHP 在 web 建站方面有更大的优势,即使是新手,也能很容易搭建一个网站出来。但这种优势也容易带来一些负面影响,因为很多的 PHP 教程没有涉及到安全方面的知识。
本文分为几部分,每部分会涵盖不同的安全威胁和应对策略。但是,这并不是说你做到这几点以后,就一定能避免你的网站出现任何问题。如果你想提高你的网站安全性的话,你应该继续通过阅读书籍或者文章,来研究如何提高你的网站安全性
出于演示需要,代码可能不是很完美。日常开发过程中,很多代码都包含在了框架跟各种库里面。作为一个后台开发,你不仅要熟练基本的 CURD,更要知道如何保护你的数据。
1. SQL 注入
我赌一包辣条,你肯定会看到这里。 SQL 注入是对您网站最大的威胁之一,如果您的数据库受到别人的 SQL 注入的攻击的话,别人可以转出你的数据库,也许还会产生更严重的后果。
网站要从数据库中获取动态数据,就必须执行 SQL 语句,举例如下:
<?php $username = $_GET['username']; $query = "SELECT * FROM users WHERE username = '$username'";
攻击者控制通过 GET 和 POST 发送的查询(或者例如 UA 的一些其他查询)。一般情况下,你希望查询户名为「 peter 」的用户产生的 SQL 语句如下:
SELECT * FROM users WHERE username = 'peter'
但是,攻击者发送了特定的用户名参数,例如:' OR '1'='1
这就会导致 SQL 语句变成这样:
SELECT * FROM users WHERE username = 'peter' OR '1' = '1'
这样,他就能在不需要密码的情况下导出你的整个用户表的数据了。
那么,我们如何防止这类事故的发生呢?主流的解决方法有两种。转义用户输入的数据或者使用封装好的语句。转义的方法是封装好一个函数,用来对用户提交的数据进行过滤,去掉有害的标签。但是,我不太推荐使用这个方法,因为比较容易忘记在每个地方都做此处理。
下面,我来介绍如何使用 PDO 执行封装好的语句( mysqi 也一样):
$username = $_GET['username']; $query = $pdo->prepare('SELECT * FROM users WHERE username = :username'); $query->execute(['username' => $username]); $data = $query->fetch();
动态数据的每个部分都以:做前缀。然后将所有参数作为数组传递给执行函数,看起来就像 PDO 为你转义了有害数据一样。
几乎所有的数据库驱动程序都支持封装好的语句,没有理由不使用它们!养成使用他们的习惯,以后就不会忘记了。