php 编写安全的代码时容易犯的错误小结


Posted in PHP onMay 20, 2010

1.不转意html entities
一个基本的常识:所有不可信任的输入(特别是用户从form中提交的数据) ,输出之前都要转意。
echo $_GET['usename'] ;
这个例子有可能输出:
<script>/*更改admin密码的脚本或设置cookie的脚本*/</script>
这是一个明显的安全隐患,除非你保证你的用户都正确的输入。
如何修复 :
我们需要将"< ",">","and" 等转换成正确的HTML表示(< , >', and "),函数htmlspecialchars 和 htmlentities()正是干这个活的。
正确的方法:
echo htmlspecialchars($_GET['username'], ENT_QUOTES);
2. 不转意SQL输入
我曾经在一篇文章中最简单的防止sql注入的方法(php+mysql中)讨论过这个问题并给出了一个简单的方法 。有人对我说,他们已经在php.ini中将magic_quotes设置为On,所以不必担心这个问题,但是不是所有的输入都是从$_GET, $_POST或 $_COOKIE中的得到的!
如何修复:
和在最简单的防止sql注入的方法(php+mysql中)中一样我还是推荐使用mysql_real_escape_string()函数
正确做法:

<?php 
$sql = "UPDATE users SET 
name='.mysql_real_escape_string($name).' 
WHERE id='.mysql_real_escape_string ($id).'"; 
mysql_query($sql); 
?>

3.错误的使用HTTP-header 相关的函数: header(), session_start(), setcookie()
遇到过这个警告吗?"warning: Cannot add header information - headers already sent [....]

每次从服务器下载一个网页的时候,服务器的输出都分成两个部分:头部和正文。
头部包含了一些非可视的数据,例如cookie。头部总是先到达。正文部分包括可视的html,图片等数据。
如果output_buffering设置为Off,所有的HTTP-header相关的函数必须在有输出之前调用。问题在于你在一个环境中开发,而在部署到另一个环境中去的时候,output_buffering的设置可能不一样。结果转向停止了,cookie和session都没有正确的设置........。

如何修复:
确保在输出之前调用http-header相关的函数,并且令output_buffering = Off

4. Require 或 include 的文件使用不安全的数据
再次强调:不要相信不是你自己显式声明的数据。不要 Include 或 require 从$_GET, $_POST 或 $_COOKIE 中得到的文件。
例如:

index.php 
<? 
//including header, config, database connection, etc 
include($_GET['filename']); 
//including footer 
?>

现在任一个黑客现在都可以用:http://www.yourdomain.com/index.php?filename=anyfile.txt
来获取你的机密信息,或执行一个PHP脚本。
如果allow_url_fopen=On,你更是死定了:
试试这个输入:
http://www.yourdomain.com/index.php?filename=http%3A%2F%2Fdomain.com%2Fphphack.php
现在你的网页中包含了http://www.youaredoomed.com/phphack.php的输出. 黑客可以发送垃圾邮件,改变密码,删除文件等等。只要你能想得到。
如何修复:
你必须自己控制哪些文件可以包含在的include或require指令中。
下面是一个快速但不全面的解决方法:
<? 
//Include only files that are allowed. 
$allowedFiles = array('file1.txt','file2.txt','file3.txt'); 
if(in_array((string)$_GET['filename'],$allowedFiles)) { 
include($_GET['filename']); 
} 
else{ 
exit('not allowed'); 
} 
?>

5. 语法错误
语法错误包括所有的词法和语法错误,太常见了,以至于我不得不在这里列出。解决办法就是认真学习PHP的语法,仔细一点不要漏掉一个括号,大括号,分号,引号。还有就是换个好的编辑器,就不要用记事本了!
6.很少使用或不用面向对象
很多的项目都没有使用PHP的面向对象技术,结果就是代码的维护变得非常耗时耗力。PHP支持的面向对象技术越来越多,越来越好,我们没有理由不使用面向对象。
7. 不使用framework
95% 的PHP项目都在做同样的四件事: Create, edit, list 和delete. 现在有很多MVC的框架来帮我们完成这四件事,我们为何不使用他们呢?
8. 不知道PHP中已经有的功能
PHP的核心包含很多功能。很多程序员重复的发明轮子。浪费了大量时间。编码之前搜索一下PHP mamual,在google上检索一下,也许会有新的发现!PHP中的exec()是一个强大的函数,可以执行cmd shell,并把执行结果的最后一行以字符串的形式返回。考虑到安全可以使用EscapeShellCmd()
9.使用旧版本的PHP
很多程序员还在使用PHP4,在PHP4上开发不能充分发挥PHP的潜能,还存在一些安全的隐患。转到PHP5上来吧,并不费很多功夫。大部分PHP4程序只要改动很少的语句甚至无需改动就可以迁移到PHP5上来。根据http://www.nexen.net的调查 只有12%的PHP服务器使用PHP5,所以有88%的PHP开发者还在使用PHP4.
10.对引号做两次转意
见过网页中出现\'或\'"吗?这通常是因为在开发者的环境中magic_quotes 设置为off,而在部署的服务器上magic_quotes =on. PHP会在 GET, POST 和 COOKIE中的数据上重复运行addslashes() 。
原始文本:
It's a string

magic quotes on :
It\'s a string
又运行一次
addslashes():
It\\'s a string

HTML输出:
It\'s a string

还有一种情况就是,用户一开始输入了错误的登录信息,服务器检测到错误输入后,输出同样的form要求用户再次输入,导致用户的输入转意两次!

PHP 相关文章推荐
PHP数组操作汇总 php数组的使用技巧
Jul 17 PHP
php抓取页面的几种方法详解
Jun 17 PHP
php全角字符转换为半角函数
Feb 07 PHP
php绘图之在图片上写中文和英文的方法
Jan 24 PHP
php文件操作之小型留言本实例
Jun 20 PHP
教你识别简单的免查杀PHP后门
Sep 13 PHP
php实现微信扫码自动登陆与注册功能
Sep 22 PHP
ThinkPHP中调用PHPExcel的实现代码
Apr 08 PHP
ThinkPHP中Widget扩展的两种写法及调用方法详解
May 04 PHP
浅谈PHP错误类型及屏蔽方法
May 27 PHP
关于ThinkPhp 框架表单验证及ajax验证问题
Jul 19 PHP
实例讲解YII2中多表关联的使用方法
Jul 21 PHP
Windows7下PHP开发环境安装配置图文方法
May 20 #PHP
Joomla下利用configuration.php存储简单数据
May 19 #PHP
php UTF-8、Unicode和BOM问题
May 18 #PHP
php生成的html meta和link标记在body标签里 顶部有个空行
May 18 #PHP
PHP 工厂模式使用方法
May 18 #PHP
在PHP中使用反射技术的架构插件使用说明
May 18 #PHP
PHP 写文本日志实现代码
May 18 #PHP
You might like
十天学会php之第八天
2006/10/09 PHP
PHP array_push 数组函数
2009/12/26 PHP
PHP获取和操作配置文件php.ini的几个函数介绍
2013/06/24 PHP
解析PHP正则提取或替换img标记属性
2013/06/26 PHP
PHP基础知识介绍
2013/09/17 PHP
Zend Framework实现将session存储在memcache中的方法
2016/03/22 PHP
cnblogs TagCloud基于jquery的实现代码
2010/06/11 Javascript
jquery mobile实现拨打电话功能的几种方法
2013/08/05 Javascript
javascript中attribute和property的区别详解
2014/06/05 Javascript
NodeJS学习笔记之FS文件模块
2015/01/13 NodeJs
JS中完美兼容各大浏览器的scrolltop方法
2015/04/17 Javascript
jQuery实现仿微软首页感应鼠标变化滑动窗口效果
2015/10/08 Javascript
使用EVAL处理jqchart jquery 折线图返回数据无效的解决办法
2015/11/26 Javascript
jQuery中cookie插件用法实例分析
2015/12/04 Javascript
实例讲解避免javascript冲突的方法
2016/01/03 Javascript
jQuery实现自动调用和触发某个事件的方法
2016/11/18 Javascript
纯原生js实现table表格的增删
2017/01/05 Javascript
Angular2.js实现表单验证详解
2017/06/23 Javascript
vue通过滚动行为实现从列表到详情,返回列表原位置的方法
2018/08/31 Javascript
JS 音频可视化插件Wavesurfer.js的使用教程
2018/10/31 Javascript
jquery实现弹窗(系统提示框)效果
2019/12/10 jQuery
Python的类实例属性访问规则探讨
2015/01/30 Python
Python函数可变参数定义及其参数传递方式实例详解
2015/05/25 Python
python开发之tkinter实现图形随鼠标移动的方法
2015/11/11 Python
Python之两种模式的生产者消费者模型详解
2018/10/26 Python
调用其他python脚本文件里面的类和方法过程解析
2019/11/15 Python
Amaze UI 文件选择域的示例代码
2020/08/26 HTML / CSS
布鲁明戴尔百货店:Bloomingdale’s
2016/12/21 全球购物
澳大利亚冒险体验:Adrenaline(跳伞、V8赛车、热气球等)
2017/09/18 全球购物
海滩咖啡馆:Beach Cafe
2018/02/02 全球购物
Mio Skincare法国官网:身体紧致及孕期身体护理
2018/04/04 全球购物
美国宠物美容和宠物用品购物网站:Cherrybrook
2018/12/07 全球购物
建筑工程自我鉴定
2013/10/18 职场文书
家具公司总经理岗位职责
2014/07/08 职场文书
医院领导班子查摆问题对照检查材料思想汇报
2014/10/08 职场文书
Java 超详细讲解十大排序算法面试无忧
2022/04/08 Java/Android