PHP安全编程

1、命令注入(Command Injection)
PHP中可以使用下列5个函数来执行外部的应用程序或函数
system、exec、passthru、shell_exec、“(单撇号,与shell_exec功能相同,如<?$results = `wc -w *.txt`; echo $results;?>)
例:
<?php //ex1.php 
$dir = $_GET["dir"]; 
if (isset($dir)){ 
 
system("ls -al ".$dir); 
}
?>
提交http://www.sectop.com/ex1.php?dir=| cat /etc/passwd
提交以后,命令变成了 system("ls -al | cat /etc/passwd");
2、eval注入(Eval Injection)
$var = "var"; 
if(isset($_GET["arg"])){ 
  $arg = $_GET["arg"]; 
  eval("\$var = $arg;"); 
  echo "\$var =".$var; 
}
http://www.test.com/index.php?arg=phpinfo()
 
动态函数:
<?php 
func A(){
dosomething(); 
func B(){ 
dosomething(); 
if (isset($_GET["func"])){ 
$myfunc = $_GET["func"]; 
echo $myfunc(); 
?> 
http://www.test.com/index.php?func=phpinfo
 
防范方法:
1、尽量不要执行外部命令
 
2、使用自定义函数或函数库来替代外部命令的功能
 
3、使用escapeshellarg函数来处理命令参数
 
4、使用safe_mode_exec_dir指定可执行文件的路径
esacpeshellarg函数会将任何引起参数或命令结束的字符转义,单引号“’”,替换成“\’”,双引号“"”,替换成“\"”,分号“;”替换成“\;”
用safe_mode_exec_dir指定可执行文件的路径,可以把会使用的命令提前放入此路径内
safe_mode = On
safe_mode_exec_dir = /usr/local/php/bin/
 
3、客户端脚本攻击(Script Insertion)
客户端脚本植入的攻击步骤
a、攻击者注册普通用户后登陆网站
b、打开留言页面,插入攻击的js代码,如插入 <script>while(1){windows.open();}</script> 无限弹框、插入<script>location.href="http://www.sectop.com";</script> 跳转钓鱼页面
c、其他用户登录网站(包括管理员),浏览此留言的内容
d、隐藏在留言内容中的js代码被执行,攻击成功
解决方案:htmlspecialchars(nl2br($row[‘question‘]), ENT_QUOTES); 转义特殊字符
 
4、跨网站脚本攻击(Cross Site Scripting, XSS)
跨站脚本主要被攻击者利用来读取网站用户的cookies或者其他个人数据,一旦攻击者得到这些数据,那么他就可以伪装成此用户来登录网站,获得此用户的权限。
一般步骤:
a、攻击者以某种方式发送xss的http链接给目标用户
b、目标用户登录此网站,在登陆期间打开了攻击者发送的xss链接
c、网站执行了此xss攻击脚本
d、目标用户页面跳转到攻击者的网站,攻击者取得了目标用户的信息
e、攻击者使用目标用户的信息登录网站,完成攻击
 
5、SQL注入攻击(SQL injection)
 
6、跨网站请求伪造攻击(Cross Site Request Forgeries, CSRF)
a、检查网页的来源
$_SERVER["HTTP_REFERER"]中的域名和$_SERVER["SERVER_NAME"]中的是否一致
b、检查内置的隐藏变量
访问页面时,在server端生成一个随机数,放置到form的隐藏域中,同时该值也保存在服务器session中,提交表单时验证提交的随机数和session中的是否一致,不一致表示来源伪造。
c、使用POST,不要使用GET
 
7、Session 会话劫持(Session Hijacking)
通过XSS或者其他手段获取到用户的session_id,然后用如下链接来冒充合法用户的身份进行操作
http://www.test.com/session.php?PHPSESSID=dce417abdb9a004673c125ccf69dcb8b
 
8、Session 固定攻击(Session Fixation)
  防范方法
a.定期更改session id
函数 bool session_regenerate_id([bool delete_old_session])
在index.php开头加上
session_start();
session_regenerate_id(TRUE);
……
这样每次从新加载都会产生一个新的session id
 
b.更改session的名称
session的默认名称是PHPSESSID,此变量会保存在cookie中,如果黑客不抓包分析,就不能猜到这个名称,阻挡部分攻击
session_start();
session_name("mysessionid");
……
 
c.关闭透明化session id
透明化session id指当浏览器中的http请求没有使用cookies来制定session id时,sessioin id使用链接来传递;打开php.ini,编辑
session.use_trans_sid = 0
代码中
int_set("session.use_trans_sid", 0);
session_start();
……
 
d.只从cookie检查session id
session.use_cookies = 1 表示使用cookies存放session id
session.use_only_cookies = 1 表示只使用cookies存放session id,这可以避免session固定攻击
代码中:
int_set("session.use_cookies", 1);
int_set("session.use_only_cookies", 1); p>
 
e.使用URL传递隐藏参数
session_start();
$seid = md5(uniqid(rand()), TRUE));
$_SESSION["seid"] = $seid;
攻击者虽然能获取session数据,但是无法得知$seid的值,只要检查seid的值是否与session中的seid一致,就可以确认当前页面是否是web程序自己调用的。
 
9、HTTP响应拆分攻击(HTTP Response Splitting)
     $fp = fsockopen(www.00aq.com, 80); // 打开Internet socket连接 
     <?php
fputs($fp, "GET / HTTP/1.1\r\n");//写入HTTP请求表头 
fputs($fp, "Host: www.00aq.com\r\n\r\n"); 
$http_response = ""; // HTTP响应的字符串
while (!feof($fp)){ 
  $http_response .= fgets($fp, );//读取256位的HTTP响应字符串
fclose($fp); // 关闭Internet socket连接
echo nl2br(htmlentities($http_response));// 显示HTTP响应信息 
     ?>
     HTTP响应拆分是由于攻击者经过精心设计利用电子邮件或者链接,让目标用户利用一个请求产生两个响应,前一个响应是服务器的响应,而后一个则是攻击者设计的响应。此攻击之所以会发生,是因为WEB程序将使用者的数据置于HTTP响应表头中,这些使用者的数据是有攻击者精心设计的
     
    可能遭受HTTP请求响应拆分的函数包括以下几个:
header(); setcookie(); session_id(); setrawcookie();
    HTTP响应拆分通常发生在:
Location表头:将使用者的数据写入重定向的URL地址内
Set-Cookie表头:将使用者的数据写入cookies内
 
    header("Location: " . $_GET[‘page‘]); 
 
   防范的方法:
    a.替换CRLF换行字符
      header("Location: " . strtr($_GET[‘page‘], array("\r"=>"",    "\n"=>"")))
    b.使用最新版本的PHP
      PHP最新版中,已经不允许在HTTP表头内出现换行字符
 
    隐藏HTTP响应表头
      apache中httpd.conf,选项ServerTokens = Prod, ServerSignature = Off
      php中php.ini,选项expose_php = Off
 
10、文件上传漏洞(File Upload Attack)
      Array{ 
[file] => Array{ 
 [name] => test.txt //文件名称 
 [type] => text/plain //MIME类型 
 [tmp_name] => /tmp/php5D.tmp //临时文件 
 [error] => 0 //错误信息 
 [size] => 536 //文件大小,单位字节 
}  
$_FILES[‘file‘][‘error‘]变量用来保存上传文件时的错误信息,它的值如下:
错误信息数值说 明
UPLOAD_ERR_OK0没有错误
UPLOAD_ERR_INI_SIZE1上传文件的大小超过php.ini的设置
UPLOAD_ERR_FROM_SIZE2上传文件的大小超过HTML表单中MAX_FILE_SIZE的值
UPLOAD_ERR_PARTIAL3只上传部分的文件
UPLOAD_ERR_NO_FILE4没有文件上传
     
  防范防范:检测文件类型,命名规则等
      
11、目录穿越漏洞(Directory Traversal)
 
12、远程文件包含攻击(Remote Inclusion)
 
13、动态函数注入攻击(Dynamic Variable Evaluation)
 
14、URL攻击(URL attack)
 
15、表单提交欺骗攻击(Spoofed Form Submissions)
 
16、HTTP请求欺骗攻击(Spoofed HTTP Requests)

PHP安全编程,布布扣,bubuko.com

PHP安全编程

上一篇:HTML和CSS的代码编写规范


下一篇:Morris.js和flot绘制折线图的比较