如何书写安全的PHP代码

安全 黑客攻防 后端
现在很多较新的Web开发程序员, 甚至在没有任何编程背景下学习PHP作为一种去增加一些互动元素到他们的网站的人,并没有觉察他们网站中潜在的安全风险。那我们如何来避免这些风险呢?

PHP是一个很容易学习的语言, 许多人在没有任何编程背景下学习它作为一种去增加一些互动元素到他们的网站的方法. 不幸的是,这往往意味着PHP程序员,尤其是那些较新的Web开发程序员, 并没有觉察他们网站中潜在安全风险. 这里是一些比较常见的安全问题,以及如何去避免它们。

永远,永远信任你的用户

不能说足够的次数,你应该永远,永远, 信任你的用户向你发送你期望的数据. 我听到很多人回应,大概是"哦,没有恶意的人将对我的网站感兴趣"。这就错了, 这里总是有怀有恶意的用户可以利用一个安全漏洞,问题可以很容易被发现,因为一个用户无意中做错了。

因此, 所有网页的发展的戒律,我不能再压缩了的话就是:永远,永远,相信你的用户。假定你的网站从使用者收集的每片数据含有恶意代码,始终, 你认为已经检查客户端验证的这些数据,例如在JavaScript ,如果你能够达到这个目标,你应该有了一个良好的开端。如果PHP的安全性很重要,这一点就要重要地学习,个人来说,"PHP安全"是一个重大的问题。

全局变量

在许多语言,你必须明确地设定一个变量以使用它。 在PHP中,有一个选项" , register_globals" , 你可以在php.ini中设置,让你可以使用全局变量,而不需要事先声明。

考虑下面的代码:

if ($password == "my_password") {
$authorized = 1;
}

if ($authorized == 1) {
echo "Lots of important stuff.";
}

许多人看上去觉得没什么问题,而事实上,这方面的代码在整个网站上应用. 但是,如果一个服务器开启"register_globals"。然后,只需添加"?authorized=1"的URL将让任何人都看到. 这是一个最普遍的PHP的安全问题。

所幸的是,这有两个简单的解决办法. 第一,也许最好的,就是把"register_globals"关闭. 二是你必须明确只有你使用变量. 在上面的例子中,这将意味着加入"?authorized=0"; 在脚本的开始:

$authorized = 0;
if ($password == "my_password") {
$authorized = 1;
}
if ($authorized == 1) {
echo "Lots of important stuff.";
}

错误信息

错误信息是一个非常有用的工具,无论是程序员和黑客. 开发者需要它们去改正错误. 黑客可以利用它们来找出一个网站的各种信息, 从目录结构的服务器,数据库登录信息. 如果可能的话,最好是关闭所有的错误报告. PHP可以完成这项工作. htaccess或php.ini,设置"error_reporting" 的值改为"0" . 如果你有一个开发环境,您可以设定不同的错误报告级别。

#p#

SQL注入

PHP的一个最大优点就是,它可以方便地与数据库中操作,最显着的MySQL的. 很多人使用这个数据库。不少网站,包括这一个,依赖于数据库的函数. 然而,正如你所料,有这么大的权力你就要够面对庞大的潜在安全问题. 所幸的是,有很多解决办法. 最常见面安全问题是一个数据库 SQL注入-当用户利用一个安全故障在你的数据库运行SQL语句. 让我们用一个常见的例子. 许多登录系统具有以下特点:一条线,看起来象不像是在检查从表单输入的用户名和密码, 比如去控制访问一个管理员区:

$check = mysql_query("Select Username, Password, UserLevel FROM Users Where Username 
= '".$_POST['username']."' and Password = '".$_POST['password']."'");

看上去很眼熟? 就表面看来,它好像做得不错.上述并不像可以做许多破坏. 但话又说回来,我在"username" 输入框输入这样的值并提交:

'' 或者 1=1 #

这个执行语句现在是这个样子:

elect Username, Password FROM Users Where Username = '' or 1=1 #' and Password = '';

散列符号(#)告诉MySQL的它之后一切,都会被忽略. 所以实际上只是执行的SQL到这一点. 1永远等于1 ,所以SQL将从数据库返回所有的用户名和密码. 在大多数用户登录数据库的首个户名和密码组合都是管理员用户, 他干脆输入了几个符号作为管理员已登录你的网站, 果他们其实都知道的用户名和密码,他们会有同样的权力如。

一个小创意,上述情况可以进一步发挥,让用户建立自己的登录帐号, 阅读信用卡号码,甚至删除数据库。

所幸的是,这种情况还是很容易避免. 通过检查要进入数据库的数据,并删除或取消它们, 我们可以防止任何人在这个数据库上执行他们自己的SQL语句. 函数的方法如下:

function make_safe($variable) {
$variable = addslashes(trim($variable));
return $variable;
}

现在,修改了我们的执行语句.用_POST取代上面的执行变量, 我们现在把所有的用户数据通过make_safe函数,在以下代码:

$username = make_safe($_POST['username']);
$password = make_safe($_POST['password']);
$check = mysql_query("Select Username, Password, UserLevel FROM Users Where Username
= '".$username."' and Password = '".$password."'");

现在,如果一个用户输入恶意的上述数据,查询看上去像下面这样,是完全无害. 以下查询将选择从数据库中的用户都和"\' or 1=1 #"相等的。

Select Username, Password, UserLevel FROM Users Where Username 
= '\' or 1=1 #' and Password = ''

现在,除非你曾经提供了一个非常特殊的用户名和空白密码, 你的恶意攻击者将不能做任何损害的事. 像这样检查所有的数据通过你的数据库是非常重要的,尽管你认为这是已经很安全. HTTP头可以由用户伪造. 他们参照地址可以伪造.浏览器用户字符串可以伪造. 不要信任一条用户发送的数据,虽然,你认为是安全的。

文件操作

一些现今的网站的URL,是这个样子的:

index.php?page=contactus.html

"index.php"文件包括"contactus.html"文件,而且这个网站似乎正常运行. 不过,用户可以很容易地将"contactus.html"改成他们自己喜的东西. 举例来说, 如果您正在使用Apache的mod_auth去保护文件,并储存你的密码在一个文件名为".htpasswd"(传统姓名)里 ,然后,如果用户访问以下地址, 脚本将输出你的用户名和密码:

index.php?page=.htpasswd

通过改变URL,在某些系统中, 在另一个可以运行PHP的服务器去引用文件。害怕? 你应该害怕. 再次所幸的是,这是比较容易防范. 首先,你必须确保正确设置" open_basedir"在你的php.ini文件,并已设置"allow_url_fopen "为"Off" . 这将阻止大多数这类型的攻击,以保护远程文件和文件系统. 其次,如果可以的话,请检查文件要求对有效文件. 如果你限制了某些文件可以用这个脚本, 你可以节省不少后来恶果。

使用默认

当mysql是安装,它使用了默认用户的"root"和空白的密码. SQL Server的用途"sa"作为默认的用户和提供了一个空白的密码. 如果有人发现你的数据库服务器地址,并想尝试登录, 这些都是首次组合,他们会尝试. 如果你没有设定不同的密码(最好也和用户, 那么你很可能一天一觉醒来发现你的数据库已经被删除,所有用户号码被盗. 和所有软件一样,你如果使用的软件是默认用户名和密码,改变他们。

不要让安装文件在线

很多PHP项目用安装文件来安装. 其中有不少是一旦运行就自我删除的,但许多不是这样的,直到您删除安装文件. 如果让安装文件在线请注,他们可能仍然可用, 有人可以用它来复盖你的整个网站。

预见性

试想一下,你的网站让一个坏人盯上. 这个坏的人要打破你的管理区, 改变你的所有产品的描述如"这个产品很差劲" . 我猜测,他们首先会去http://www.yoursite.com/admin/ -万一它存在. 将你的敏感文件和文件夹像预测一样,他们很容易就受到黑客攻击。

为此,要确保你的姓名你的敏感文件和文件夹,让他们很难猜测. 把你的 admin 位于http://www.yoursite.com/jsfh8sfsifuhsi8392/ 或者更难去写的,但它为你的网站添加一些额外的保障.如果你需要一个记得快的地址, 但不用"admin"或"administration" (或你的用户名和密码) . 用一些不经常用的。

这同样适用于用户名和密码. 如果你有管理区,不要使用" admin "作为用户名和" password "作为密码. 针对一些特殊的情况,最好是两个字母和数字(有的黑客利用一些所谓的"词典攻击" , 尝试每一个字,在字典里的密码,直到他们找到密码。添加一对密码,使这一类攻击无用) . 这也是明智的去定期改变你的密码 (每两个月). 最后,要确保当一个用户名输入" Wrong Password " 当错误的密码输入时你的错误讯息给没有输出.如: " Unknown Username ",恶意用户都知道,他们已经成功地猜测一个有效的用户名. 对上述两种手段,采用通用的"登录错误"的错误信息 ,如果是用户名和密码输入错误的恶意用户就没有任何办法设想正确的用户和密码。

最后,彻底和完全地设想

你假设你的网站不会受到攻击,或面要对任何问题的话,但当最终出事,你将有大量的麻烦. 如果,在另一方面, 假设你的每一个客人到你的网站是为了攻击你,你永远处于战争状态, 你就能帮助你把你的网站做得安全,并准备得没有一点闪失。

【编辑推荐】

  1. Java和PHP在Web开发方面的比较
  2. 国外主流PHP框架对比评测
  3. 精通PHP需要注意的十大要点
责任编辑:杨鹏飞 来源: shuro的博客
相关推荐

2011-07-08 10:01:05

PHP

2013-06-05 09:51:04

2020-11-06 15:00:58

PHPMySQL数据库

2020-11-09 15:49:38

PHPMemcache网络安全

2022-12-21 15:56:23

代码文档工具

2009-12-03 16:30:24

PHP代码解析损耗

2022-06-13 10:11:19

项目文档PRD

2009-12-01 16:12:37

PHP HTML截取代

2020-09-18 07:57:10

代码编码开发

2020-08-19 15:30:04

PHP网络安全代码

2010-07-13 11:47:47

2020-10-14 11:30:10

PHP网络安全加密

2021-06-25 14:13:14

态势感知

2021-04-23 11:06:14

网络数据技术

2009-11-24 10:42:06

PHP转义符

2009-12-04 09:00:05

PHP垃圾代码

2010-08-04 11:37:44

PHP NFS

2011-07-05 17:52:41

PHP

2018-10-06 05:00:53

2012-12-19 10:36:06

点赞
收藏

51CTO技术栈公众号