PHP-平时PHP开发过程中,安全过滤的方法和需要注意的地方?经常用到的函数?
大家讨论一下,平时开发过程中,安全过滤的方法和需要注意的地方?主要是为了,防止非法用户,添加恶意的代码,或添加一些特殊代码,轻而易举就获得网站的漏洞和服务器权限。
具体的一些漏洞攻击的方式:
1、命令注入(Command Injection)
2、eval注入(Eval Injection)
3、客户端脚本攻击(Script Insertion)
4、跨网站脚本攻击(Cross Site Scripting, XSS)
5、SQL注入攻击(SQL injection)
6、跨网站请求伪造攻击(Cross Site Request Forgeries, CSRF)
7、Session 会话劫持(Session Hijacking)
8、Session 固定攻击(Session Fixation)
9、HTTP响应拆分攻击(HTTP Response Splitting)
10、文件上传漏洞(File Upload Attack)
11、目录穿越漏洞(Directory Traversal)
12、远程文件包含攻击(Remote Inclusion)
13、动态函数注入攻击(Dynamic Variable Evaluation)
14、URL攻击(URL attack)
15、表单提交欺骗攻击(Spoofed Form Submissions)
16、HTTP请求欺骗攻击(Spoofed HTTP Requests)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
还有数据库的注入,最好用pdo绑定参数,防止sql注入
页面上的post传递的数据用公共方法
/**
* 转义字符或遍历转义数组 基于addslashes()
*
* @param mixed $array
*/
function Add_S( &$array ){
if ( is_array( $array ) ){
foreach( $array as $key => $value ){
if ( !is_array( $value ) ){
$array[$key] = addslashes( $value );
}else{
Add_S( $array[$key] );
}
}
}else{
$array = addslashes( $array );
}
}
/**
* 转义字符或遍历转义数组 stripslashes()
*
* @param mixed $array
*/
function Strip_S( &$array ){
if ( is_array( $array ) ){
foreach( $array as $key => $value ){
if ( !is_array( $value ) ){
$array[$key] = stripslashes( $value );
}else{
Add_S( $array[$key] );
}
}
}else{
$array = stripslashes( $array );
}
}
首先分享一个以前用过的一个过滤:
function check_str($string, $isurl = false)
{
$string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F]/','',$string);
$string = str_replace(array("","%00","r"),'',$string);
empty($isurl) && $string = preg_replace("/&(?!(#[0-9]+|[a-z]+);)/si",'&',$string);
$string = str_replace(array("%3C",'<'),'<',$string);
$string = str_replace(array("%3E",'>'),'>',$string);
$string = str_replace(array('"',"'","t",' '),array('"',''',' ',' '),$string);
return trim($string);
}
下面截自:http://www.cnblogs.com/my37gs/archive/2011/12/07/2278697.html
1、 验证用户输入的任何数据,保证PHP代码的安全
这里有一个技巧就是使用白名单,所谓白名单就是说:我们要求用户的数据应该是这样的,例如我们要求用户的输入是一个数字,我们就只检验这个值是否是一个数字就行了,而不必检验他到底是什么——其实他有可能是个恶意脚本。
对于这个检验我们不能只在客户端的javascript进行,战地认为JS只是为了提高来访用户的体验而产生的,而不是验证的工具。因为任何一个来访的用户都可能会,也有可能无意间就禁用了客户端脚本的执行,从而跳过这层验证。所以我们必须在PHP的服务器端程序上检验这些数据。
2、 保护数据库的安全——对即将运行于数据库的Sql语句进行安全性预处理。
任何时候都要对执行前的Mysql语句,进行mysql_real_escape_string操作——该函数的用法请参考PHP手册。诸多PHP的数据库抽象层例如ADODB都提供了类似的方法。
3、 不要依赖不该依赖的PHP设置——环境有时候不可靠
不依赖,magic_quotes_gpc=On,在程序编制的过程,尽量关闭这个配置选项,任何时候判断这个选项后再对用户输入的数据进行处理。切记——PHP v6 中将会删除这个选项。尽量在合适的时候使用addcslashes 系列函数——请参考手册
4、 验证数据来源,避免远程表单提交
不要使用$_SERVER['HTTP_REFERER']这个超级变量来检查数据的来源地址,一个很小的菜鸟黑客都会利用工具来伪造这个变量的数据,尽可能利用Md5,或者rand等函数来产生一个令牌,验证来源的时候,验证这个令牌是否匹配。
5、 保护会话数据,特别是Cookies
Cookie是保存在用户的计算机上的,保存之后任何用户都有可能出于某种原因更改他,我们必须对敏感数据进行加密处理。Md5、sha1都是个的加密方法。
6、 利用htmlentities()预防XSS攻击
对用户可能输入脚本语言的地方的数据进行htmlentities()操,将多数可以产生程序错误的用户输入进行实体化。记住要遵循第一个习惯:在 Web 应用程序的名称、电子邮件地址、电话号码和帐单信息的输入中用白名单中的值验证输入数据。
我感觉主要还是在参数处理上。一定要判断是否符合你想要的,比如你想要一个数字类型的,结果参数中提供的却是个字符串。还有cookie 里的数据,这个可是能在客户端被修改掉的啊。所以凡是使用的参数,都需要进行类型和可控范围的判断和过滤。然后再使用就安全了。
当然,算法的漏洞就更不用说了。主要是在一些边界值上做处理。
过滤我就不补充了更多答案 请参考 @如何有效防止XSS攻击/AJAX跨域攻击
我说下防止非法用户的一些常用手段吧
1 前端的js验证: 我认为js验证只是一种用户体验的提升,对普通用户群体的简单限制,所以后台必须要有相应的验证。。
2 表单中的隐藏域 : 相信大家都遇到过这样的问题,如: 用户从 A 页面 点如 B 页面,B页面是个表单,这个表单中有个隐藏域,用来记录从A页面带来的数据(像id等),用户提交时 在后台修改,新增数据都是依赖这个隐藏域的值,如果这里不做好验证的话,很可能被用户修改隐藏域的值,从而导致垃圾数据。。 我见过一个商城,竟然用隐藏域记录订单信息,用firebug修改价钱后发现下订单的金额竟然是我修改的,好久没关注,不知道对这个问题修改了没有。。
对于以上问题,我一般的做法是 A 页面到 B 页面时生成一个值:
然后 在将这个生成的 key 也放入 B页面表单的 隐藏域中。
数据提交后, 用相同的加密顺序去加密在判断 如:
我现在一般用这种方式,不知道大家还有没有更好的方式。
3 ajax :一般ajax请求后台验证比较少,还有最好限制 ajax请求的地址 不能通过浏览器直接访问,不要认为 ajax 请求方式为 post 就 比较安全。
一般我限制的方法为:
当然 X_REQUESTED_WITH 也可以伪造,至少多增加了一点验证。
PHP方面:
(1)htmlspecialchars:参数一是要转换的字符串,参数二是设置是否要转换单引号,双引号之类的,参数三是字符串编码设置。
本函数将特殊字符转成 HTML 的字符串格式 ( &....; )。最常用到的场合可能就是处理客户留言的留言版了。
&
(和) 转成&
"
(双引号) 转成"
<
(小于) 转成<
>
(大于) 转成>
此函数只转换上面的特殊字符,并不会全部转换成 HTML 所定的 ASCII 转换。
(2)htmlentities:会将所有 string 的字符都转成 HTML 的特殊字集字符串。
(3)strip_tags:去掉 HTML 及 PHP 的标记。
(4)sql语句还要再加个mysql_real_escape_string();
完美的安全防护措施不仅仅是后台要进行安全过滤,而且前台也应该利用JS正则验证用户输入,便于用户体验
我一般都是把POST和GET全部转换成REQUEST形式:
$_REQUEST = array_merge($_GET, $_POST);
// 转义POST和GET数据
if (!get_magic_quotes_gpc())
{
foreach ($_REQUEST as $_key => $_value)
{
if (!is_array($_value)) $_REQUEST[$_key] = addslashes($_value);
}
}
1、GET、POST过来的值格式化。比如$id = intval($_POST['id']);//把POST过来的ID转为整数
2、入库前用addslashes()对单引号(')、双引号(")、反斜线()与 NUL(NULL 字符)用 作为转义。