文章来源:PHP开发学习门户
地址:http://www.phpthinking.com/archives/575
php给了开发人员极大的灵活性,可是这也为安全问题带来了潜在的隐患,最近须要总结一下以往的问题。在这里借翻译一篇文章同一时候加上自己开发的一些感触总结一下。
简单介绍
当开发一个互联网服务的时候,必须时刻牢记安全观念,并在开发的代码中体现。
PHP脚本语言对安全问题并不关心。特别是对大多数没有经验的开发人员来说。
每当你讲不论什么涉及到钱財事务等交易问题时。须要特别注意安全问题的考虑。比如开发一个论坛或者是一个购物车等。
安全保护一般性要点
对于一般的Javascript前台验证,因为无法得知用户的行为。比如关闭了浏览器的javascript引擎。这样通过POST恶意数据到server。须要在server端进行验证,对每一个php脚本验证传递到的数据。防止XSS攻击和SQL注入
要如果你的站点接收的每一条数据都是存在恶意代码的。存在隐藏的威胁,要对每一条数据都进行清理
在php.ini文件里进行下面配置:
假设这个配置选项打开之后。会出现非常大的安全隐患。比如有一个process.php的脚本文件。会将接收到的数据插入到数据库,接收用户输入数据的表单可能例如以下:
1 |
<input
name= "username" type= "text" size= "15" maxlength= "64" > |
这样,当提交数据到process.php之后,php会注冊一个$username变量。将这个变量数据提交到process.php。同一时候对于不论什么POST或GET请求參数,都会设置这种变量。假设不是显示进行初始化那么就会出现以下的问题:
2 |
//
Define $authorized = true only if user is authenticated |
3 |
if (authenticated_user())
{ |
此处。如果authenticated_user函数就是推断$authorized变量的值,如果开启了register_globals配置。那么不论什么用户都能够发送一个请求。来设置$authorized变量的值为随意值从而就能绕过这个验证。
全部的这些提交数据都应该通过PHP提前定义内置的全局数组来获取,包含$_POST、$_GET、$_FILES、$_SERVER、$_REQUEST等。当中$_REQUEST是一个$_GET/$_POST/$_COOKIE三个数组的联合变量。默认的顺序是$_COOKIE、$_POST、$_GET。
推荐的安全配置选项
error_reporting设置为Off:不要暴露错误信息给用户,开发的时候能够设置为ON
safe_mode设置为Off
register_globals设置为Off
将下面函数禁用:system、exec、passthru、shell_exec、proc_open、popen
open_basedir设置为 /tmp ,这样能够让session信息有存储权限,同一时候设置单独的站点根文件夹
expose_php设置为Off
allow_url_fopen设置为Off
allow_url_include设置为Off
SQL注入攻击
对于操作数据库的SQL语句,须要特别注意安全性。由于用户可能输入特定语句使得原有的SQL语句改变了功能。类似以下的样例:
1 |
$sql = "select
* from pinfo where product = '$product'" ; |
此时假设用户输入的$product參数为:
39′; DROP pinfo; SELECT ‘FOO
那么终于SQL语句就变成了例如以下的样子:
1 |
select
product from pinfo where product = '39' ;
DROP pinfo; SELECT 'FOO' |
这样就会变成三条SQL语句,会造成pinfo表被删除,这样会造成严重的后果。
这个问题能够简单的使用PHP的内置函数解决:
1 |
$sql = 'Select
* from pinfo where product = ' "' |
2 |
mysql_real_escape_string( $product )
. '"' ; |
防止SQL注入攻击须要做好两件事:
对输入的參数总是进行类型验证
对单引號、双引號、反引號等特殊字符总是使用mysql_real_escape_string函数进行转义
可是,这里依据开发经验,不要开启php的Magic Quotes。这个特性在php6中已经废除。总是自己在须要的时候进行转义。
防止主要的XSS攻击
XSS攻击不像其它攻击,这样的攻击在client进行。最主要的XSS工具就是防止一段javascript脚本在用户待提交的表单页面。将用户提交的数据和cookie偷取过来。
XSS工具比SQL注入更加难以防护,各大公司站点都被XSS攻击过,尽管这样的攻击与php语言无关。但能够使用php来筛选用户数据达到保护用户数据的目的,这里主要使用的是对用户的数据进行过滤,一般过滤掉HTML标签,特别是a标签。
以下是一个普通的过滤方法:
01 |
function transform_HTML( $string , $length =
null) { |
02 |
//
Helps prevent XSS attacks |
04 |
$string =
trim( $string ); |
05 |
//
Prevent potential Unicode codec problems. |
06 |
$string =
utf8_decode( $string ); |
07 |
//
HTMLize HTML-specific characters. |
08 |
$string =
htmlentities( $string ,
ENT_NOQUOTES); |
09 |
$string = str_replace ( "#" , "#" , $string ); |
10 |
$string = str_replace ( "%" , "%" , $string ); |
11 |
$length = intval ( $length ); |
13 |
$string = substr ( $string ,
0, $length ); |
这个函数将HTML的特殊字符转换为了HTML实体,浏览器在渲染这段文本的时候以纯文本形式显示。如<strong>bold</strong>会被显示为:
<STRONG>BoldText</STRONG>
上述函数的核心就是htmlentities函数,这个函数将html特殊标签转换为html实体字符,这样能够过滤大部分的XSS攻击。
可是对于有经验的XSS攻击者。有更加巧妙的办法进行攻击:将他们的恶意代码使用十六进制或者utf-8编码。而不是普通的ASCII文本。比如能够使用以下的方式进行:
1 |
<a
href= "http://host/a.php?
variable=%22%3e
%3c%53%43%52%49%50%54%3e%44%6f%73%6f%6d%65%74%68%69%6e%67%6d%61%6c%69%63%69%6f%75%73%3c%2f%53%43%52%49%50%54%3e" > |
这样浏览器渲染的结果事实上是:
1 |
<a
href= "http://host/a.php?variable=" >
<SCRIPT>Dosomethingmalicious</SCRIPT> |
这样就达到了攻击的目的。为了防止这样的情况,须要在transform_HTML函数的基础上再将#和%转换为他们相应的实体符号,同一时候加上了$length參数来限制提交的数据的最大长度。
使用SafeHTML防止XSS攻击
上述关于XSS攻击的防护很easy。可是不包括用户的全部标记,同一时候有上百种绕过过滤函数提交javascript代码的方法,也没有办法能全然阻止这个情况。
眼下。没有一个单一的脚本能保证不被攻击突破,可是总有相对来说防护程度更好的。一共同拥有两个安全防护的方式:白名单和黑名单。当中白名单更加简单和有效。
一种白名单解决方式就是SafeHTML。它足够智能可以识别有效的HTML,然后就行去除不论什么危急的标签。
这个须要基于HTMLSax包来进行解析。
安装使用SafeHTML的方法:
1、前往http://pixel-apes.com/safehtml/?
page=safehtml 下载最新的SafeHTML
2、将文件放入server的classes 文件夹,这个文件夹包括全部的SafeHTML和HTMLSax库
3、在自己的脚本中包括SafeHTML类文件
4、建立一个SafeHTML对象
5、使用parse方法进行过滤
02 |
/*
If you're storing the HTMLSax3.php in the /classes directory, along |
03 |
with
the safehtml.php script, define XML_HTMLSAX3 as a null string. */ |
04 |
define(XML_HTMLSAX3, '' ); |
05 |
//
Include the class file. |
06 |
require_once ( 'classes/safehtml.php' ); |
07 |
//
Define some sample bad code. |
08 |
$data = "This
data would raise an alert <script>alert('XSS Attack')</script>" ; |
09 |
//
Create a safehtml object. |
10 |
$safehtml = new safehtml(); |
11 |
//
Parse and sanitize the data. |
12 |
$safe_data = $safehtml ->parse( $data ); |
14 |
echo 'The
sanitized data is <br />' . $safe_data ; |
SafeHTML并不能全然防止XSS攻击。仅仅是一个相对复杂的脚本来检验的方式。
使用单向HASH加密方式来保护数据
单向hash加密保证对每一个用户的password都是唯一的,并且不能被破译的,仅仅有终于用户知道password。系统也是不知道原始password的。
这种一个优点是在系统被攻击后攻击者也无法知道原始password数据。
加密和Hash是不同的两个过程。与加密不同。Hash是无法被解密的,是单向的;同一时候两个不同的字符串可能会得到同一个hash值,并不能保证hash值的唯一性。
MD5函数处理过的hash值基本不能被破解,可是总是有可能性的,并且网上也有MD5的hash字典。
使用mcrypt加密数据
MD5 hash函数能够在可读的表单中显示数据,可是对于存储用户的信用卡信息的时候。须要进行加密处理后存储,而且须要之后进行解密。
最好的方法是使用mcrypt模块。这个模块包括了超过30中加密方式来保证仅仅有加密者才干解密数据。
02 |
$data = "Stuff
you want encrypted" ; |
03 |
$key = "Secret
passphrase used to encrypt your data" ; |
04 |
$cipher = "MCRYPT_SERPENT_256" ; |
05 |
$mode = "MCRYPT_MODE_CBC" ; |
06 |
function encrypt( $data , $key , $cipher , $mode )
{ |
14 |
substr (md5( $key ),0,mcrypt_get_key_size( $cipher , $mode )), |
17 |
substr (md5( $key ),0,mcrypt_get_block_size( $cipher , $mode )) |
21 |
function decrypt( $data , $key , $cipher , $mode )
{ |
27 |
substr (md5( $key ),0,mcrypt_get_key_size( $cipher , $mode )), |
30 |
substr (md5( $key ),0,mcrypt_get_block_size( $cipher , $mode )) |
mcrypt函数须要下面信息:
1、待加密数据
2、用来加密和解密数据的key
3、用户选择的加密数据的特定算法(cipher:如 MCRYPT_TWOFISH192,MCRYPT_SERPENT_256。 MCRYPT_RC2, MCRYPT_DES, and MCRYPT_LOKI97)
4、用来加密的模式
5、加密的种子,用来起始加密过程的数据,是一个额外的二进制数据用来初始化加密算法
6、加密key和种子的长度,使用mcrypt_get_key_size函数和mcrypt_get_block_size函数能够获取
假设数据和key都被盗取,那么攻击者能够遍历ciphers寻找开行的方式就可以,因此我们须要将加密的key进行MD5一次后保证安全性。同一时候因为mcrypt函数返回的加密数据是一个二进制数据。这样保存到数据库字段中会引起其它错误,使用了base64encode将这些数据转换为了十六进制数方便保存。
- Web 开发常见安全问题
不是所有 Web 开发者都有安全的概念,甚至可能某些安全漏洞从来都没听说过.这就是这篇科普文章的存在意义,希望 Web 开发者在开发时能依此逐条检查代码中的安全问题. 注:服务器运维相关的安全注意事项 ...
- Web开发常见安全问题
转载自: http://blog.csdn.net/fengyinchao/article/details/50775121 不是所有 Web 开发者都有安全的概念,甚至可能某些安全漏洞从来都没听说过 ...
- Web开发常规调试方法与常见问题分析
一.Web项目基本原理 现在的web项目大都已经前后端独立开发与部署. 前后端独立开发,一般是前端与后端通过web接口(常见的有RESTful与websocket)文档进行交流.前端开发人员先更具业务 ...
- 移动WEBAPP开发常规CSS样式总结
我所使用到的HTML页面标签: Section,div,artical,p,ol,ul,li,header,footer,span,form,input,label,h1,h2,h3 :详细说明我就不 ...
- iOS开发线程安全问题
先来看一下代码: - (void)viewDidLoad { [super viewDidLoad]; self.testStr = @"String initial complete&qu ...
- 跟我一起学WCF(3)——利用Web Services开发分布式应用
一.引言 在前面文章中分别介绍了MSMQ和.NET Remoting技术,今天继续分享.NET 平台下另一种分布式技术——Web Services 二.Web Services 详细介绍 2.1 We ...
- 软件快速开发平台 WebBuilder 6.8
WebBuilder是一款开源的跨平台.数据库和浏览器的可视化Web应用快速开发平台.WebBuilder使用了多项最新的技术,使Web应用的开发更快捷和简单. 作为一款高效的Web开发工具,WebB ...
- 不使用Visual Studio开发ASP.NET MVC应用(下篇)
书接上回! 前文“纯手工”.彻底抛弃Visual Studio,制作了一个ASP.NET MVC应用,运行起来还不错,项目目录.源代码.web.config等所有东西都已经做到“最简”,除去了Visu ...
- 利用Web Services开发分布式应用
一.引言 在前面文章中分别介绍了MSMQ和.NET Remoting技术,今天继续分享.NET 平台下另一种分布式技术——Web Services 二.Web Services 详细介绍 2.1 We ...
- hdoj--2138--How many prime numbers(暴力模拟)
How many prime numbers Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- laravel中的数据迁移和数据填充
laravel中的数据迁移和数据填充 标签(空格分隔): php 生成迁移文件两种方式: 1 新建一个表的迁移文件 php artisan make:migration create_students ...
- pyton写购物车
pyton写购物车 基本要求: 用户输入工资,然后打印购物菜单用户可以不断的购买商品,直到余额不够为止退出时打印用户已购买的商品和剩余金额.. 1.这个程序功能不完整,bug很多,练手之作. good ...
- <Sicily>Fibonacci
一.题目描述 In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn-1 + Fn-2 for n ≥ 2. For exampl ...
- 写给自己的Java程序员学习路线图_转载
如下是我做开发这三年经常使用一些技术和工具,当然这些技术也都是需要加强的(有些是我一直使用的,不过不深入,有些内部的原理等等不是很清楚) 前端部分: 1)HTML:网页的核心语言,构成网页的基础 2) ...
- Linux cp 复制命令
Linux 的cp命令 功能: 复制文件或目录说明: cp指令用于复制文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则它会把前面指定的所有文件或目录复制到此目录中.若 ...
- Mac配置PHP环境
本文章来自:http://blog.csdn.net/wj_november/article/details/51417491 本人使用的是:MacOs 10.12.3,根据如上操作已经安装成功,感谢 ...
- [POI2008]POD-Subdivision of Kingdom(搜索+状压)
题意 给定一个n个点的无向图,要求将点集分成大小相等的两个子集,使两个子集之间的边数最少 (n<=26) 题解 一开始想了半天DP发现不会,去看题解全是搜索. 所以发现C(1326)可以过我就写 ...
- [USACO5.4]奶牛的电信Telecowmunication(网络流)
P1345 [USACO5.4]奶牛的电信Telecowmunication 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮 ...
- Unity C# 设计模式(一)单例模式
动机(Motivation): 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性.以及良好的效率 意图: 保证一个类仅有一个实例,并提供一 ...