打造安全博客之——避免WordPress暴路径

如果你的服务器的错误报告和显示默认是开启的,那么随便打开你博客的一个URL,便可查知你的博客用的是什么服务器操作系统、WP安装在哪个目录。
下面我随便找几个博客测试一下吧,哈哈,几乎百发百中了。。。 :twisted:

像这种因未在包含文件中执行而产生的调用未定义函数的错误,WP本身是无法handle的,因此,得在php.ini或在apache配置文件或.htaccess文件中禁用错误报告或错误显示,如:

1
2
Options -Indexes
php_value error_reporting 0

你完全不用担心这样设置以后WP出错了不会报告,因为在程序执行中WP自身有错误报告的相关设定。
这样设置后的好处是,可以避免让一些别有用心的人通过暴路径来获取你的WP站点信息,要知道暴路径可是web入侵时的一种重要手段。

wp-config.php最后一行是包含wp-settings.php,在wp-settings.php第57行和58行有:

1
2
// Check if we're in WP_DEBUG mode.
wp_debug_mode();

我们再看下这个函数到底干了什么吧:
我们先看一下这里:wp-includes/default-constants.php 第48-58行:

1
2
3
4
5
6
7
8
9
10
11
    // Add define('WP_DEBUG', true); to wp-config.php to enable display of notices during development.
    if ( !defined('WP_DEBUG') )
        define( 'WP_DEBUG', false );

    // Add define('WP_DEBUG_DISPLAY', false); to wp-config.php use the globally configured setting for display_errors and not force errors to be displayed.
    if ( !defined('WP_DEBUG_DISPLAY') )
        define( 'WP_DEBUG_DISPLAY', true );

    // Add define('WP_DEBUG_LOG', true); to enable error logging to wp-content/debug.log.
    if ( !defined('WP_DEBUG_LOG') )
        define('WP_DEBUG_LOG', false);

如果我们没有在wp-config.php中自己定义,那么WP默认是不开启调试模式、显示错误信息、不记录错误信息在wp-content/debug.log

在wp-includes/load.php 第262 行函数正式开始了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function wp_debug_mode() {
//如果在wp-config.php中define('WP_DEBUG',TRUE);
//那么在php5.3以后处于调试模式的WP的错误报告级别为:E_ALL & ~E_DEPRECATED & ~E_STRICT
    if ( WP_DEBUG ) {
        // E_DEPRECATED is a core PHP constant in PHP 5.3. Don't define this yourself.
        // The two statements are equivalent, just one is for 5.3+ and for less than 5.3.
        if ( defined( 'E_DEPRECATED' ) )
            error_reporting( E_ALL & ~E_DEPRECATED & ~E_STRICT );
        else
            error_reporting( E_ALL );
//配置PHP错误信息显示
        if ( WP_DEBUG_DISPLAY )
            ini_set( 'display_errors', 1 );
//错误信息记录
        if ( WP_DEBUG_LOG ) {
            ini_set( 'log_errors', 1 );
            ini_set( 'error_log', WP_CONTENT_DIR . '/debug.log' );
        }
    } else {
//这是production 环境下WP的默认错误报告级别
        error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );
    }
}

这样看来,如果主题或者插件的因为修改或其它原因造成错误,PHP还是会报告的。
且WP_DEBUG_DISPLAY 在 WP_DEBUG 为 FALSE时为不起作用的,因此我们还有必要在wp-config.php中做一下设置:

1
ini_set( 'display_errors', 0 );

以下为我的wp-config.php中的部分内容,在此帖出来仅供大家参考:

1
2
3
4
5
@ini_set( 'display_errors', 0 );
    define( 'WP_DEBUG', FALSE );
    define( 'WP_DEBUG_DISPLAY', TRUE );
    define('WP_DEBUG_LOG', TRUE);
   define('WP_ADMIN_ALERT_EMAIL','此处填写用于接收邮件的email');

再将以下代码添加到当前主题functions.php中或者新建一php文件并在functions.php中包含之:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*********START*************ALERT ERROR by 荒野无灯******************************/
add_action('shutdown', 'ihacklog_error_alert');
 
function ihacklog_error_alert()
 {
         if(is_null($e = error_get_last()) === false )
         {
             switch($e['type'])
             {
                 //@see http://www.php.net/manual/en/errorfunc.constants.php
                 case E_ERROR:
                 case E_PARSE:
                 case E_CORE_ERROR:
                 case E_USER_ERROR:
                 //case E_RECOVERABLE_ERROR :
                     if( !defined('WP_DEBUG') || (defined('WP_DEBUG') && !WP_DEBUG ) )
                {
                         $message = 'REQUEST DATE: ' . gmdate('Y-m-d H:i:s',time()+8*3600 ) . "\nREQUEST URI: " ;
                     $message .= isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'N/A';
                     $message .= "\nUSER AGENT: ";
                     $message .= isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'N/A';
                     $message .= "\nUSER IP: ";
                     $message .= isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'N/A';
                     $message .= "\nERROR INFO: \n". print_r($e, true). "\n";
                     @mail( WP_ADMIN_ALERT_EMAIL, 'Error from WP: [type]=>'. $e['type'], $message );
                     //header('Content-type: text/html;charset=UTF-8');
                     die('Oops! An error has occurred...<br />the message has been sent to the site administrator.');
                 }
                 else
                 {
                     echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
                             <html xmlns="http://www.w3.org/1999/xhtml">
                             <head>
                             <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                             
                         <style type="text/css">
                         .error-div{margin:50px auto;font-size:20px;font-family:Georgia;}
                         .info{ color:#f00;font-weight:bold;}
                         </style>
                         </head><body>'
;
                     //print_r($e);  
                    echo '<div class="error-div">Error: <span class="info">'. $e['message'] .'</span> on file: <span class="info">'. $e['file'] . '</span> line: <span class="info">'. $e['line'] .'</span>.</div>' ;
                     echo '</body></html>';
                     die();
                 }
                     break;
             }
         }
 }
 /*********END****************ALERT ERROR by 荒野无灯******************************/

在非调试情况下,如有重要错误会发邮件到指定邮箱并显示:

Oops! An error has occurred…
the message has been sent to the site administrator.

在调试开启的情况下,显示详细的错误信息:

插件和主题作者要注意
从代码级别上,可以采取以下预防措施:

1
2
// Do not delete these lines
if (!empty($_SERVER['SCRIPT_FILENAME']) &#038;&#038; '文件自身的名字' == basename($_SERVER['SCRIPT_FILENAME'])) die ('Please do not load this page directly. Thanks!');

或者一种更省事的做法:

1
2
3
4
5
if ( !defined( 'ABSPATH' ) )
{
     header( 'HTTP/1.1 403 Forbidden', true, 403 );
     die ('Please do not load this page directly. Thanks!');
}
更多
16 Responses Post a comment
  1. 清风

    解决了一个大问题,非常不错。。。

  2. 学建站

    看到这篇文章,我想起很多主题为什么会被泄露了,后台安装会有压缩包文件,如果不及时删除的话就很有可能让别人拿走了

  3. 荒野无灯

    @archy
    不用修改php.ini ,文章中已经说得很清楚了,虚拟主机修改.htaccess.
    当然,你有权限修改php.ini当然可以修改。

  4. archy

    这个必须修改php.ini吗?之前博客都被黑客搞了几次了

    按照下面的方法试了 没作用

  5. shamas

    我是早发现这个有点不好,不过也懒得折腾。反正及时备份数据什么的。

  6. 阿疯

    对于这个都懒得折腾了.
    唉..主要是我的博客也没什么东西好暴露的

  7. 荒野无灯

    @Demon
    你填寫的這個http://http://ise7en.me/ 的 URL 。。。我還以為我redirect出錯了~~

  8. Demon

    来这里都能学到点好东东。。。大湿。真好。

  9. 七小罗汉

    前天被人暴力破解登录密码,现在仍心有余悸

  10. 豬頭六

    有些複雜啊,呵呵,我博客還沒被人黑過呢。一般沒人會閑的蛋疼黑個人博客吧?

  11. 权子

    额.好危险的。你是危险人物。哈哈~~~

  12. 老谢

    想知道就算有目录了能干嘛。。。我是安全白痴

  13. 荒野无灯

    @phoetry
    主要是前面的路径,不是指后面的WP路径~~根据路径你基本可以判断出操作系统~~甚至有的可能显示apache等信息~~

  14. phoetry

    这个路径暴露问题算是很难保得周全了, 光一个主css路径便有九成九的人不会去改它.

Leave a Reply

Note: You may use basic HTML in your comments. Your email address will not be published.

Subscribe to this comment feed via RSS