PHP开辟绝对不能违反的安全铁则[网络技术]
本文“PHP开辟绝对不能违反的安全铁则[网络技术]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
作为PHP程序员,分外是新手,关于互联网的险恶老是知道的太少,关于外部的入侵有很多时刻是素手无策的,他们根本不知道黑客是若何入侵的、提交入侵、上传漏洞、sql 注入、跨脚本攻击等等.作为最基本的防备你需求注意你的外部提交,做好第一面安全机制处理防火墙.
法则 1:毫不要信任外部数据或输入
关于Web利用程序安全性,必须熟习到的第一件事是不该该信任外部数据.外部数据(outside data) 包含不是由程序员在PHP代码中直接输入的任何数据.在采纳办法确保安全之前,来自任何其他根源(比方 GET 变量、表单 POST、数据库、配置文件、会话变量或 Cookie)的任何数据都是不可托任的.
比方,下面的数据元素可以被认为是安全的,因为它们是在PHP中设置的.
清单 1. 安全无暇的代码
$myUsername = ‘tmyer’;
$arrayarrayUsers = array(‘tmyer’, ‘tom’, ‘tommy’);
define("GREETING", ‘Hello there’ . $myUsername);
?>
但是,下面的数据元素都是有瑕疵的.
清单 2. 不安全、有瑕疵的代码
$myUsername = $_POST['username']; //tainted!
$arrayarrayUsers = array($myUsername, ‘tom’, ‘tommy’); //tainted!
define("GREETING", ‘hello there’ . $myUsername); //tainted!
?>
为什么第一个变量$myUsername 是有瑕疵的?因为它直接来自表单 POST.用户可以在这个输入域中输入任何字符串,包含用来排除文件或运行从前上传的文件的恶意号令.您大概会问,"莫非不能利用只承受字母 A-Z 的客户端(Javascrīpt)表单查验脚本来避免这种危险吗?"是的,这老是一个有好处的步骤,但是正如在背面会看到的,任何人都可以将任何表单下载到自己的机械上,改正它,然后重新提交他们需求的任何内容.
办理筹划很简单:必须对$_POST['username'] 运行清理代码.假如不这么做,那么在利用$myUsername的任何其他时刻(比方在数组或常量中),便大概污染这些对象.对用户输入举行清理的一个简单办法是,利用正则表达式来处理它.在这个示例中,只但愿承受字母.将字符串限制为特定数目的字符,大概要求全部字母都是小写的,这大概也是个好主张.
清单 3. 利用户输入变得安全
$myUsername = cleanInput($_POST['username']); //clean!
$arrayarrayUsers = array($myUsername, ‘tom’, ‘tommy’); //clean!
define("GREETING", ‘hello there’ . $myUsername); //clean!
function cleanInput($input){ $clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);return $clean;
}
?>
法则 2:禁用那些使安全性难以实施的PHP设置
已经知道了不能信任用户输入,还应当知道不该该信任机械上配置 PHP 的方法.比方,要确保禁用 register_globals.假如启用了 register_globals,便大概做一些粗心的事情,比方利用 $variable 替换同名的 GET 或 POST 字符串.通过禁用这个设置,PHP 逼迫您在精确的名称空间中引用精确的变量.要利用来自表单 POST 的变量,应当引用 $_POST['variable'].这样就不会将这个特定变量曲解成 cookie、会话或 GET 变量.
法则 3:假如不能理解它,就不能保护它
一些开辟人员利用奇特的语法,大概将语句组织得很紧凑,形成简短但是含义模糊的代码.这种方法大概效率高,但是假如您不睬解代码正在做什么,那么就无法决意若何保护它.比方,您喜好下面两段代码中的哪一段?
清单 4. 使代码简单得到保护
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:");
//unobfuscated code
$input = ";
if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = ";
}
在第二个对比清楚的代码段中,很简单看出 $input 是有瑕疵的,需求举行清理,然后才能安全地处理.
法则 4:"纵深防备" 是新的法宝
本教程将用示例来阐明若何保护在线表单,同时在处理表单的 PHP 代码中采取必要的办法.一样,即便利用 PHP regex 来确保 GET 变量美满是数字的,仍旧可以采纳办法确保 SQL 查询利用转义的用户输入.纵深防备不只是一种好思惟,它可以确保您不会陷入严重的麻烦.既然已经谈论了基本法则,目前就来研究第一种威胁:SQL 注入攻击.
◆避免SQL注入攻击
在SQL注入攻击中,用户通过操作表单或 GET 查询字符串,将信息增添到数据库查询中.比方,假定有一个简单的登录数据库.这个数据库中的每个记录都有一个用户名字段和一个密码字段.构建一个登录表单,让用户可以登录.
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="verify.php" method="post">
<p><label for=’user’>Username</label>
<input type=’text’ name=’user’ id=’user’/>
</p> <p><label for=’pw’>Password</label>
<input type=’password’ name=’pw’ id=’pw’/>
</p> <p><input type=’submit’ value=’login’/></p>
</form>
</body>
</html>
这个表单承受用户输入的用户名和密码,并将用户输入提交给名为verify.php的文件.在这个文件中,PHP处理来自登录表单的数据,以下所示:
清单 5. 不安全的 PHP 表单处理代码
<?php
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = "select count(*) as ctr from users where username=’
".$username."‘ and password=’". $pw."‘ limit 1″;
$result = MySQL_query($sql);
while ($data = mysql_fetch_object($result)){
if ($data->ctr == 1){
//they’re okay to enter The application!
$okay = 1;
}
}
if ($okay){
$_SESSION['loginokay'] = true;
header("index.php");
}else{
header("login.php");
}
?>
这段代码看起来没问题,对吗?世界各地成百(乃至成千)的 PHP/MySQL 站点都在利用这样的代码.它错在那边?好,记着 "不能信任用户输入".这里没有对来自用户的任何信息举行转义,因此使利用程序简单遭到攻击.具体来说,大概会呈现任何范例的SQL注入攻击.比方,假如用户输入 foo 作为用户名,输入 ‘ or ’1′=’1 作为密码,那么实际上会将以下字符串传送给 PHP,然后将查询传送给 MySQL:
<?php
$sql = "select count(*) as ctr from users where username=
’foo’ and password=" or ’1′=’1′ limit 1″;
?>
这个查询老是返回计数值 1,因此 PHP 会答应举行拜候.通过在密码字符串的末尾注入某些恶意 SQL,黑客就可以打扮成合理的用户.办理这个问题的办法是,将 PHP 的内置 mysql_real_escape_string() 函数用作任何用户输入的包装器.这个函数对字符串中的字符举行转义,使字符串不大概传送撇号等特别字符并让 MySQL 按照特别字符举行操作.清单7展示了带转义处理的代码.
清单7展示了带转义处理的代码
<?php
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = "select count(*) as ctr from users where username='".mysql_real_
_string($username)."' and password='". mysql_real_escape_string($pw)."'
limit 1";
$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){
if ($data->ctr == 1){ //they're okay to enter the
application!
$okay = 1;
}
}
if ($okay){
$_SESSION['loginokay'] = true;
header("index.php");
}
else{
header("login.php");
}
?>
利用 mysql_real_escape_string() 作为用户输入的包装器,便可以避免用户输入中的任何恶意 SQL 注入.假如用户尝试通过 SQL 注入传送畸形的密码,那么会将以下查询传送给数据库:
select count(*) as ctr from users where username=’foo’ and password=
’\’ or \’1\’=\’1′ limit 1″
以上是“PHP开辟绝对不能违反的安全铁则[网络技术]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |