PHP安全 [安全编码]

Posted 王小帥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP安全 [安全编码]相关的知识,希望对你有一定的参考价值。

目录

数据库安全(SQL注入)

命令执行 

XSS 

资源泄露 

本地文件包含

任意文件上传 


文件系统安全

源码

<?php 
//从用户目录中删除指定的文件
$username = $_POST['user_submitted_name'];
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$userfille";
unlink ("$homedir/$userfile");
echo "The file has been deleted!";
?>

如果攻击者恶意构造如下:

user_submitted_name="../etc"
user_submitted_filename="passwd"

因为源码是直接拼接的,所以上述执行会直接把/etc/passwd文件执行删除操作。(属于越权行为)

安全编码

  1. 不允许用户有拼接权限。
  2. 对用户输入进行完整的校验。

校验源码(白名单):

<?php 
$username = $_SERVER('REMOTE_USER'); //使用认证机制
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$username";

$filepath = "$homedir/$userfile";
if(!ctype_alnum($username) || !preg_match('/^(?:[a-z0-9_-]|\\.(?!\\.))+$/iD',userfile)){
    die("Bad username/filename");
}
...
?>

ctype_alnum():做字母和数字字符检测

( : ?         非捕获分组,仅仅匹配

( ?  ! \\. )   匹配非.的内容

分析:

  1. ../etc 在上述正则会导致die,即 ..开头的文件不允许
  2. /符号会导致die
  3. 根据操作系统的不同,存在着各种各样需要注意的文件,包括联系到系统的设备( /dev/或者COM1)、配置文件(/ect/文件和.ini文件)、常用的存储区域(/home/ 或者My Documents )等等。由于此原因,建立一个策略禁止所有权限而只开放明确允许的通常更容易些

数据库安全(SQL注入)

恶意输入:

尽量避免直接的数据库查询语句的拼接,无论数据库种类。

<?php 
$query = "SELECT * FROM products WHERE id LIKE '%$prod%'";
$result = mssql_query($query);
?>

a%' exec master..xp_cmdshell 'net user test testpass /ADD'

<?php
$query = "SELECT * FROM products WHERE id LIKE '%a%' exec master..xp_cmdshell 'net user test testpass /ADD'--";
$result = mssql_query($query);
?>

 错误输出:

尽量避免直接输出原本的数据库错误信息,而自行构造。

<?php
$sql = "SELECT * FROM movies WHERE title LIKE '%" . sqli($title) . "%'";
    $recordset = mysql_query($sql,$link);
    if(!$recordset)
    {
        die("ERROR!");
    }
}

在使用数据库时候,对于敏感信息加密存储:

  • md5($pass)
  • md5($salt.md5($pass))
  • SHA-1
  • SHA-2(SHA-224,SHA-256,SHA-384和SHA-512)
  • 推荐使用:
  • md5($salt.md5($pass))与SHA-256

命令执行 

源码:

$targetUrl = $_POST["target"];
switch ($targetUrl) {
    case "www.target.com": echo "" . shell_exec("nslookup www.target.com");
        break;
    case "web.target.com": echo "" . shell_exec("nslookup web.target.com");
        break;
    ...
    default:echo "" . shell_exec("nslookup www.target.com");
    }
}

如果命令执行不可缺少,使用白名单的形式,并且硬编码禁止拼接。

XSS 

<?php 

    //用户可控数据不需存储直接响应的,应编码输出。
echo $this->securityUtil->encodeForhtml($data);
echo $this->securityUtil->encodeForjavascript($data);

    //用户可控数据需存储响应,应过滤字符。
$this->securityUtil->purifier($_GET["data"]);

}

注释 

资源泄露 

<?php 

$file = fopen("temp.txt","w") or die ("Unable to open file!");
fclose($file);

本地文件包含

<?php 

$filename = $_GET["filename"];
switch ($filename){
    case "file.txt":include("./file.txt");
        break;
    default:include("./readme.txt");
}

当必须要接受外部文件名的时候,同样是白名单。

任意文件上传 

<?php 

$config = array('limit'=>5 * 1024 *1024,  //允许上传的文件最大大小
                'type'=>array(            //允许的上传文件后缀及MIME
                        "gif"=>"image/gif",
                        "jpg"=>"image/jpeg",
                        "png"=>"image/png")
);

$title = $_FILES["file"];
$data = $this->securityUtil->verifyUploadFile($file,$config);
if($data['flag']!=true){
    returun; //上传失败
}

对文件的大小,后缀名以及MIME进行验证。对上传的路径,文件名以及它的权限进行限制,甚至对文件内容进行验证。 

安全编码细则

  1. 所有输入的数据都是有害的(直接或者间接由用户输入的)
  2. 不依赖运行环境的安全配置
  3. 安全控制措施落实在最后执行阶段
  4. 最小化
  5. 失败终止

总则

绝对安全的系统是不存在的。最好的安全机制应该能在不防碍用户,并且不过多地增加开发难度的情况下做到能满足需求。

 

 

 

 

以上是关于PHP安全 [安全编码]的主要内容,如果未能解决你的问题,请参考以下文章

PHP安全 [安全编码]

DjangoPython安全编码与代码审计

PHP 安全性:如何滥用编码?

关于PHP二进制安全的解释

PHP Cookie 安全问题

codeigniter 中的安全性