PHP环境安全性能检查脚本

PHP在Linux环境下安全配置是一个复杂的过程,其中涉及到很多的细节设置,在这里发出来一个脚本,通过这个脚本来检测你的PHP环境是否存在安全隐患,从而针对这些对你的PHP环境进行加固。
功能:
1.检测PHP环境安全配置
2.应禁用的功能。
3.危险的设置,可能会导致本地或远程文件包含。
4.错误处理。
5.在编译时定义的常量。
安装PHP环境后,将此三个文件脚本放在网站web目录下(audit.php php.xml style.css )进行浏览器查看,他将在你配置的基础中通过XML文件中匹配规则检测出可能存在的配置错误,存在问题的选项它会用红色突出的颜色显示。当然还有一些东西可以根据你的要求更改。

源码如下:
(1)audit.php

<?php
/**
 *audit.php
 *PHP Security Auditor
 */
class Audit {
    static private $rules;
    static private $constants;
    static private $phpVer;
    static public $report;
 
    /**
      * Converts settings such as 1M 1G 1K to their byte equivilent values
      * @param string $n
      * @return string
     **/
    static private function convertToBytes($n) {
        // If n is -1 then there is no limit
        if ($n == -1) return PHP_INT_MAX;
        switch (substr($n, -1)) {
            case "B": return substr($n,0,-1);
            case "K": return substr($n,0,-1) * 1024;
            case "M": return substr($n,0,-1) * 1024 * 1024;
            case "G": return substr($n,0,-1) * 1024 * 1024 * 1024;
        }
        return $n;
    }
 
    static private function MakeReport($type, $title) {
        ksort(self::$report[$type]);
        $html = '<h1>' . $title . '</h1><table><tr class="h"><th>Setting</th><th>Current</th>
                <th>Recomended</th><th>Description</th></tr>';
        foreach(self::$report[$type] as $key => $values) {
            if ($values['p'] == 1) $class="r";
            else $class="v";
 
            $html .= '<tr><td class="e">' . htmlentities($key) . '</td>' . '<td class="'. 
                    $class.'">' . htmlentities($values['c']) . '</td>' . '<td class="'. 
                    $class .'">' . htmlentities($values['r']) . '</td>' . '<td class="'. 
                    $class .'">' . htmlentities($values['d']) . '</td></tr>';
        }
        $html .= '</table>';
        return $html;
    }
 
    static public function HTMLReport() {
        $class = "";
        $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
                    "DTD/xhtml1-transitional.dtd">' . '<html><head>' . '<link rel="stylesheet" 
                    type="text/css" media="all" href="style.css"/>' . '</head><body>';
        $html .= self::MakeReport("ini", "PHP INI");
        $html .= self::MakeReport("disabled", "PHP Disabled Functions");
        $html .= self::MakeReport("const", "PHP CONST");
        $html .= '</html>';
        echo($html . "\n");
    }
 
    /**
      * Adds an item to the reporting array.
      * @param string $type - the type (ini or const)
      * @param string $key - the name of the variable
      * @param string $currentValue - the current ini or const value
      * @param string $recomended - the recomended value
      * @param string $desc - a description of the issue
      * @param boolean $problem - true if not complaint, false if compliant
      */
    static private function Report($type, $key, $currentValue, $recomended, $desc, $problem) {
        if (isset(self::$report[$type][$key]))
            if ((self::$report[$type][$key]['r'] < $recomended) && 
                (self::$report[$type][$key['p']] == 1)) return;
            self::$report[$type][$key] = array(
                                            "c" => $currentValue,
                                            "r" => $recomended,
                                            "d" => $desc,
                                            "p" => $problem);
    }
 
    /**
      * Loads the rules from an XML file
      * @param string $file
      */
    static public function LoadRules($file = "php.xml") {
        if (!defined('PHP_VERSION_ID')) {
                $version = explode(".", PHP_VERSION);
                self::$phpVer =  ($version[0] * 10000 + $version[1] * 100 + $version[2]);
        } else {
            self::$phpVer = PHP_VERSION_ID;
        }
 
        self::$constants = get_defined_constants();
        self::$rules = simplexml_load_file($file);
    }
 
    /**
      * Processes the XML ruleset against const and ini values found in PHP
      */
    static public function ProcessXML() {
        foreach(self::$rules as $null => $entry) {
            $ruleID = $entry->attributes()->id;
            // Check the version of PHP the rule applies to
            $version = (string)$entry->version;
            if ($version != "") {
                $op = (string)$entry->version->attributes()->op;
                switch ($op) {
                    case 'before':
                        if ($version < self::$phpVer) continue 2;
                        break;
                }
            }
 
            // Evaluate the rule as we are sure it applys to the version of PHP running
            switch((string)$entry->type) {
                // Look at CONST values in PHP
                case "const":
                    $key 	= (string)$entry->key;	// e.g LIBXML_NOENT
                    $cValue = self::$constants[$key];	// The current value
                    $rValue = (string)$entry->value;	// The recomended value
                    $desc	= (string)$entry->description;	// Description
                    switch((string)$entry->value->attributes()->op) {
                        case "eq":
                            self::Report("const", $key, $cValue, $rValue, $desc, 
                                            ($cValue == $rValue) ? 0 : 1);
                            break;
                    }
                    break;
                // Check the list of functions that should be restricted
                case "disable_functions":
                    $disabled = ini_get("disable_functions");
                    $list = explode(",", $disabled);
                    $xmlList = (array)($entry->list);
                    $xmlList = $xmlList['function'];
                    foreach($xmlList as $null => $function) {
                        $de = array_search($function, $list);
                        self::Report("disabled", $function, (($de == 0) ? "enabled" : 
                                        "disabled"), "disabled", "", (($de == 0) ? 1 : 0));
                    }
                    break;
 
                // Look at values defined within the INI files
                case "ini":
                    $key 	= (string)$entry->key; // e.g. display_errors
                    $cValue = trim(self::convertToBytes(ini_get($key))); // Current value
                    $rValue = (string)$entry->value;	// Recomended value
                    $desc	= (string)$entry->description; // Description
                    if (is_numeric($rValue) && $cValue == "") $cValue = "0";
 
                    // Deals with where one value should be compared to another
                    if ((string)$entry->value->attributes()->type == "key")
                        $rValue = self::convertToBytes(ini_get((string)$entry->value));
                        switch((string)$entry->value->attributes()->op) {
                            // Equal to
                            case "eq":
                                self::Report("ini", $key, $cValue, $rValue, $desc, 
                                                ($cValue == $rValue) ? 0 : 1);
                                break;
 
                            // Less than or equal to
                            case "lt":
                                self::Report("ini", $key, $cValue, "< $rValue", $desc, 
                                                ($cValue <= $rValue) ? 0 : 1);
                                break;
 
                            // Greater than or equal to
                            case "gt":
                                self::Report("ini", $key, $cValue, "> $rValue", $desc, 
                                                ($cValue >= $rValue) ? 0 : 1);
                                break;
 
                            // Not equal to
                            case "ne":
                                $neValue  = (string)$entry->value->attributes()->net;
                                $notBlank = (string)$entry->value->attributes()->notblank;
                                if ($notBlank == "true") {
                                    self::Report("ini", $key, $cValue, $rValue, $desc, 
                                                    ($cValue != "") ? 0 : 1);
                                    break;
                                }
                                self::Report("ini", $key, $cValue, $rValue, $desc, 
                                                ($cValue != $neValue) ? 0 : 1);
                                break;
                        }
                        break;
                }
            }
        }
    }
 
Audit::LoadRules();
Audit::ProcessXML();
Audit::HTMLReport();
?>
(2)php.xml
<?xml version="1.0" encoding="UTF-8"?>
<rules>
    <entry id="1">
	<type>ini</type>
	<key>upload_max_filesize</key>
	<value op="lt">4194304</value>
	<description>Sets the maximum size of an uploaded file. Reduce this to mitigate the risk of DOS attacks.</description>
    </entry>
    <entry id="29">
	<type>ini</type>
	<key>upload_max_filesize</key>
	<value op="lt" type="key">memory_limit</value>
	<description>The maximum size of an uploaded file should be able to fit within the avaliable memory limit.</description>
    </entry>
    <entry id="30">
	<type>ini</type>
	<key>post_max_size</key>
	<value op="lt" type="key">memory_limit</value>
	<description>The maximum post size of data posted to the server should be within the avaliable memory limit.</description>
    </entry>
    <entry id="32">
	<type>ini</type>
	<key>always_populate_raw_post_data</key>	
	<value op="eq">0</value>
	<description>This does not need to be used. The preferred method for accessing the raw POST data is php://input.</description>
    </entry>
    <entry id="33">
	<type>ini</type>
	<key>magic_quotes_gpc</key>	
	<value op="eq">0</value>
	<description>Sets magic_quotes state for GPC (GET PUT COOKIE) data.  Relying on this feature is highly discouraged.</description>
	<version op="before">50300</version>
	<url>http://www.php.net/manual/en/info.configuration.php#ini.magic-quotes-gpc</url>
    </entry>
    <entry id="34">
	<type>ini</type>
	<key>magic_quotes_runtime</key>	
	<value op="eq">0</value>
	<description>Sets magic_quotes state for data from external sources.  Relying on this feature is highly discouraged.</description>
	<version op="before">50300</version>
	<url>http://www.php.net/manual/en/info.configuration.php#ini.magic-quotes-runtime</url>
    </entry>
    <entry id="35">
	<type>ini</type>
	<key>safe_mode</key>	
	<value op="eq">0</value>
	<description>This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged.</description>
	<version op="before">50300</version>
    </entry>
    <entry id="36">
	<type>ini</type>
	<key>memory_limit</key>
	<value op="lt">16777216</value>
	<description>The maximum memory limit for each script should be 16M or less.</description>
    </entry>
    <entry id="5">
	<type>ini</type>
	<key>upload_max_filesize</key>	
	<value op="lt" type="key">post_max_size</value>
	<description>The maximum upload file size should be less than or equal to the maximum post size.</description>
    </entry>
    <entry id="2">
	<type>ini</type>
	<key>max_file_uploads</key>
	<value op="lt">10</value>
	<description>The maximum mumber of files that can be uploaded in 1 go.</description>
    </entry>
    <entry id="3">
	<type>ini</type>
	<key>file_uploads</key>
	<value op="eq">0</value>
	<description>This may be impractical but if not needed file uploading should be disabled.</description>
    </entry>
    <entry id="4">
	<type>ini</type>
	<key>post_max_size</key>	
	<value op="lt">4194304</value>
	<description>The maximum post size should as small as reasonably possible to mitigate the risk of DOS attacks.</description>
    </entry>
    <entry id="6">
	<type>ini</type>
	<key>register_long_arrays</key>	
	<value op="eq">0</value>
	<description>Populates HTTP_*_VARS which should no longer be used.</description>
	<version op="before">50300</version>
    </entry>
    <entry id="7">
	<type>ini</type>
	<key>register_globals</key>	
	<value op="eq">0</value>
	<description>Highly dangerous feature enabling variables to be defined in scripts from the GPC paramaters. This should be always be turned off.</description>	
	<version op="before">50300</version>
    </entry>
    <entry id="8">
	<type>ini</type>
	<key>session.hash_function</key>	
	<value op="eq">1</value>
	<description>MD5 should be replaced with SHA-160 as it is a more complex and secure hashing algorithm.</description>
	<version op="after">50000</version>
    </entry>
    <entry id="9">
	<type>ini</type>
	<key>session.hash_bits_per_character</key>	
	<value op="gt">5</value>
	<description>The number of bits encoded per character of the session key.</description>
	<version op="after">50000</version>
    </entry>
    <entry id="10">
	<type>ini</type>
	<key>session.entropy_file</key>	
	<value op="ne" net="">/dev/random</value>
	<description>Provides a random seed for generating the session.</description>
    </entry>
    <entry id="11">
	<type>ini</type>
	<key>session.entropy_length</key>	
	<value op="gt">32</value>
	<description>The number of bytes to read for gathering entropy for session generation.</description>
    </entry>
    <entry id="12">
	<type>ini</type>
	<key>session.name</key>	
	<value op="ne" net="PHPSESSID">Custom String</value>
	<description>The name given to the PHP Session. It is recomended this be changed from the default.</description>
    </entry>
    <entry id="14">
	<type>ini</type>
	<key>session.save_path</key>	
	<value op="ne" net="/tmp" notblank="true">/custom/location</value>
	<description>The save path for the session should be changed from the default /tmp.</description>
    </entry>
    <entry id="15">
	<type>ini</type>
	<key>session.use_trans_sid</key>	
	<value op="eq">0</value>
	<description>Sessions should not be allowed in GET paramaters.</description>
    </entry>
    <entry id="18">
	<type>ini</type>
	<key>display_errors</key>	
	<value op="eq">0</value>
	<description>Error messages should be suppressed</description>
    </entry>
    <entry id="19">
	<type>ini</type>
	<key>allow_url_fopen</key>	
	<value op="eq">0</value>
	<description>Remote files should not be accessable using fopen.</description>
    </entry>
    <entry id="20">
	<type>ini</type>
	<key>allow_url_include</key>	
	<value op="eq">0</value>
	<description>You should not be able to include remote scripts using include.</description>
    </entry>
    <entry id="31">
	<type>ini</type>
	<key>session.cookie_httponly</key>	
	<value op="eq">1</value>
	<description>Cookies must be httponly by default</description>
	<version op="after">50200</version>
    </entry>
    <entry id="20">
	<type>ini</type>
	<key>open_basedir</key>	
	<value op="ne" net="/" notblank="true">/the/webroot</value>
	<description>Limit the files that can be opened by PHP to the webroot.</description>
    </entry>
    <entry id="32">
	<type>ini</type>
	<key>upload_tmp_dir</key>	
	<value op="ne" net="/tmp" notblank="true">/custom/location</value>
	<description>Change the location of where files are initally uploaded to</description>
    </entry>
    <entry id="21">
	<type>ini</type>
	<key>max_execution_time</key>	
	<value op="lt">20</value>
	<description>Execution time should be limited to 20 seconds or less.</description>
    </entry>
    <entry id="22">
	<type>ini</type>
	<key>max_input_nesting_level</key>	
	<value op="lt">32</value>
	<description>Maximum level of nesting of objects 32 is sufficent.</description>
    </entry>
    <entry id="23">
	<type>ini</type>
	<key>enable_dl</key>	
	<value op="eq">0</value>
	<description>Disable loading of dynamic extensions.</description>
    </entry>
    <entry id="24">
    	<type>ini</type>
	<key>display_startup_errors</key>	
	<value op="eq">0</value>
	<description>Startup errors should be suppressed.</description>
    </entry>
    <entry id="25">
	<type>ini</type>
	<key>log_errors</key>	
	<value op="eq">1</value>
	<description>All errors generated by PHP should be logged to a file.</description>
    </entry>
    <entry id="26">
	<type>ini</type>
	<key>log_errors_max_len</key>	
	<value op="gt">2048</value>
	<description>At least 2048 characters of the error message should be stored in the error log.</description>
    </entry>
    <entry id="27">
	<type>ini</type>
	<key>error_log</key>	
	<value op="ne" net="">/custom/location</value>
	<description>Should be set to the location of the php error log.</description>
    </entry>
    <entry id="28">
	<type>const</type>
	<key>LIBXML_NOENT</key>	
	<value op="eq">0</value>
	<description>External entities should be disabled for XML parsing</description>
    </entry>
    <entry id="37">
	<type>ini</type>
	<key>session.use_only_cookies</key>	
	<value op="eq">1</value>
	<description>Session variables should only be passed in cookies.</description>
    </entry>
    <entry id="29">
	<type>const</type>
	<key>LIBXML_NONET</key>	
	<value op="eq">0</value>
	<description>Network access for XML parsers should be disabled.</description>
    </entry>
    <entry id="38">
	<type>disable_functions</type>
	<list>
		<function>fsocket_open</function>
		<function>pack</function>
		<function>escapeshellarg</function>
		<function>escapeshellcmd</function>
		<function>exec</function>
		<function>passthru</function>
		<function>proc_close</function>
		<function>php_uname</function>
		<function>getmyuid</function>
		<function>getmypid</function>
		<function>passthru</function>
		<function>leak</function>
		<function>listen</function>
		<function>diskfreespace</function>
		<function>tmpfile</function>
		<function>link</function>
		<function>ignore_user_abort</function>
		<function>set_time_limit</function>
		<function>limit</function>
		<function>exec</function>
		<function>highlight_file</function>
		<function>show_source</function>
		<function>fpaththru</function>
		<function>virtual</function>
		<function>posix_ctermid</function>
		<function>posix_getcwd</function>
		<function>posix_getegid</function>
		<function>posix_geteuid</function>
		<function>posix_getgid</function>
		<function>posix_getgrgid</function>
		<function>posix_getgrnam</function>
		<function>posix_getgroups</function>
		<function>posix_getlogin</function>
		<function>posix_getpgid</function>
		<function>posix_getpgrp</function>
		<function>posix_getpid</function>
		<function>posix</function>
		<function>posix_getpwnam</function>
		<function>posix_getpwuid</function>
		<function>posix_getrlimit</function>
		<function>posix_getsid</function>
		<function>posix_getuid</function>
		<function>posix_isatty</function>
		<function>posix_kill</function>
		<function>posix_mkfifo</function>
		<function>posix_setegid</function>
		<function>posix_seteuid</function>
		<function>posix_setgid</function>
		<function>posix_setpgid</function>
		<function>posix_setsid</function>
		<function>posix_setuid</function>
		<function>posix_times</function>
		<function>posix_ttyname</function>
		<function>posix_uname</function>
		<function>proc_open</function>
		<function>proc_close</function>
		<function>proc_get_status</function>
		<function>proc_nice</function>
		<function>proc_terminate</function>
		<function>phpinfo</function>
		<function>proc_open</function>
		<function>shell_exec</function>
		<function>system</function>
		<function>set_time_limit</function>
		<function>ini_alter</function>
		<function>dl</function>
		<function>popen</function>
		<function>parse_ini_file</function>
	</list>
    </entry>
</rules>
(3)style.css
@CHARSET "UTF-8";
 
body {background-color: #ffffff; color: #000000;}
body, td, th, h1, h2 {font-family: sans-serif;}
pre {margin: 0px; font-family: monospace;}
table {border-collapse: collapse;}
td, th { border: 1px solid #000000; font-size: 75%; vertical-align: baseline;  padding-left:5px; padding-right:5px;}
h1 {font-size: 150%;}
h2 {font-size: 125%;}
.p {text-align: left;}
.e {background-color: #ccccff; font-weight: bold; color: #000000;}
.h {background-color: #9999cc; font-weight: bold; color: #000000;}
.v {background-color: #cccccc; color: #000000; padding-left:5px;}
.r {background-color: #c50000; color: #000000;  padding-left:5px;}

转载于:https://my.oschina.net/wzwitblog/blog/112913

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值