将wp-config移到Web根之外真的有好处吗?


135

如今,最常见的安全性最佳实践之一似乎是wp-config.php目录移到高于vhost文档根目录的位置。我从来没有真正找到过一个好的解释,但是我假设这是为了最大程度地减少读取数据库密码在webroot中恶意或感染脚本的风险。

但是,您仍然必须让WordPress访问它,因此您需要扩展open_basedir以包括文档根目录上方的目录。这不仅破坏了整个目的,而且还可能将服务器日志,备份等暴露给攻击者?

还是该技术只是试图防止出现这样的情况,即在这种情况下wp-config.php任何请求的人都将其显示为纯文本http://example.com/wp-config.php,而不是被PHP引擎解析?这似乎是非常罕见的情况,并且不会超过将日志/备份/等暴露给HTTP请求的不利影响。

也许可以在某些托管设置中将其移到文档根目录之外,而无需暴露其他文件,但在其他设置中则不能?


结论: 在这个问题上经过反复的反复讨论之后,出现了两个答案,我认为应该将其视为权威的答案。亚伦·亚当斯(Aaron Adams)很好地支持移动 wp-config,而克里斯吉塔吉(Chrisguitarguy)很好地反对了。如果您不是该线程的新手,并且不想阅读整个内容,那么这是您应该阅读的两个答案。其他答案要么是多余的,要么是不正确的。


确实没有必要在问题中插入您选择的答案并拒绝所有其他答案。正如您在下面看到的那样,这就是stackexchange投票系统的作用,用于投票表决对人们有意义的答案,而提问者应该使用“接受的答案”机制和您自己的上下投票。
Kzqai 2014年

6
对于我所问的99%的问题,我都不会这样做,但是我认为在这种情况下是合适的。这个问题有8个答案,其中一些相当冗长/复杂,尽管其中包含的信息不正确或没有在对话中添加任何内容,但其中一些还是有很多反对意见。我认为提供半权威性的结论有助于人们第一次阅读该主题。与往常一样,读者可以自由决定。我只是作为OP提供我的意见。
伊恩·邓恩2014年

1
@Kzqai:“ stackexchange投票系统”是一个民主过程,与会人员通常是1)不清楚OP实际要求或试图解决的内容,以及2)对任何特定答案的有效性不理解。之后,反应在已惠及和投票选举了,这是不是有帮助更多有OP澄清,提供援助的响应。毕竟,OP是唯一知道的人,我希望有更多OP这样做。是的,人们“投票给别人有意义的答案”,但让OP让他对他有意义的事情有最后的决定权。
Mac

Answers:


127

简短答案:是

这个问题的答案是明确的,否则完全不负责任


长答案:一个真实的例子

请允许我提供一个非常真实的示例,该示例来自我的真实服务器,其中,移出wp-config.phpWeb根目录明确阻止了其内容的捕获

错误:

请看一下对Plesk中的错误的描述(已在11.0.9 MU#27中修复):

将订阅与托管计划同步后,Plesk重置子域转发(117199)

听起来无害,对吧?

好吧,这是我触发此错误的方法:

  1. 设置子重定向到另一个网址(例如site.staging.server.comsite-staging.ssl.server.com)。
  2. 更改了订阅的服务计划(例如,其PHP配置)。

当我这样做时,Plesk将子域重置为默认值:提供的内容~/httpdocs/,而没有任何解释器(例如PHP)处于活动状态。

而且我没有注意到。数周。

结果:

  • 随着wp-config.php在网站根目录,请求/wp-config.php将已下载WordPress的配置文件。
  • 随着wp-config.phpWeb根目录外,请求/wp-config.php下载一个完全无害的文件。实际wp-config.php文件无法下载。

因此,很明显,移出wp-config.php网络根目录在现实世界中具有真正的安全优势


如何移动wp-config.php到服务器上的任何位置

WordPress会在您的WordPress安装上方自动为您的wp-config.php文件查找一个目录,因此,如果已将其移动到该目录,就可以完成!

但是,如果您将其移到其他地方怎么办?简单。wp-config.php使用以下代码在WordPress目录中创建一个新文件:

<?php

/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
    define('ABSPATH', dirname(__FILE__) . '/');

/** Location of your WordPress configuration. */
require_once(ABSPATH . '../phpdocs/wp-config.php');

(请确保将以上路径更改为重定位wp-config.php文件的实际路径。)

如果您遇到的问题open_basedir,只需open_basedir在PHP配置中将新路径添加到指令中:

open_basedir = "/var/www/vhosts/example.com/httpdocs/;/var/www/vhosts/example.com/phpdocs/;/tmp/"

而已!


分开相反的论点

任何反对搬离wp-config.php网络根源的争论都基于错误的假设。

论据1:如果禁用了PHP,则它们已经在

有人看到[ wp-config.php] 的唯一方法就是绕过服务器的PHP解释器……如果发生这种情况,您就已经麻烦了:他们可以直接访问您的服务器。

:我上面描述的情况是配置错误的结果,而不是入侵。

论点2:偶然禁用PHP的情况很少见,因此可忽略不计

如果攻击者有足够的权限来更改PHP处理程序,那么您已经搞砸了。根据我的经验,偶然的更改非常罕见,在这种情况下,更改密码很容易。

:我上面描述的情况是常见服务器软件中的一个错误导致了常见服务器配置的错误。这几乎是“罕见的”(此外,安全性意味着担心这种罕见情况)。

WTF:如果在入侵过程中获取了敏感信息,则在入侵后更改密码几乎没有帮助。真的,我们是否仍然认为WordPress仅用于休闲博客,并且攻击者仅对污损感兴趣?让我们担心保护我们的服务器,而不仅仅是在有人进入后恢复它。

论据3:拒绝访问就wp-config.php足够了

您可以通过虚拟主机配置来限制对文件的访问,或者 .htaccess–与移出文档根目录一样,有效地限制对文件的外部访问。

FALSE:假设您的虚拟主机服务器默认值为:no PHP,no .htaccessallow from all(在生产环境中很少见)。如果您在例行操作(例如面板更新)期间以某种方式重置了配置,则所有内容都将恢复为默认状态,您将处于暴露状态。

如果在将设置意外重置为默认值时安全模型失败,则需要更高的安全性。

WTF:为什么有人会特别建议减少安全层?昂贵的汽车不仅有锁,而且还有锁。他们也有警报器,防盗器和GPS追踪器。如果有什么值得保护的地方,那就做对。

论点4:未经授权的访问wp-config.php没什么大不了的

数据库信息实际上是[ wp-config.php]中唯一敏感的内容。

:身份验证密钥和盐可以用于多种潜在的劫持攻击。

WTF:即使数据库凭据是唯一的内容wp-config.php,您也应该对攻击者获得帮助感到恐惧

参数5:移动wp-config.phpWeb根目录以外实际上使服务器更少安全

您仍然必须让WordPress访问[ wp-config.php],因此您需要扩展open_basedir以包括文档根目录上方的目录。

:假设wp-config.php存在httpdocs/,只需将其移至../phpdocs/,并设置open_basedir为仅包含httpdocs/phpdocs/。例如:

open_basedir = "/var/www/vhosts/example.com/httpdocs/;/var/www/vhosts/example.com/phpdocs/;/tmp/"

(请记住,始终包含/tmp/或您的用户tmp/目录(如果有的话)。)


结论:配置文件以后都应该始终被定位在网站根目录外

如果您关心安全性,那么您将移出wp-config.phpWeb根目录。


1
如果您在apache,linux或admin的头脑中有错误,那么无论如何您都是敬酒的。在您的方案中,您无法解释为什么在网站的根目录比在服务器的任何其他位置更容易发生配置错误。配置错误的apache可能访问/../config.php就像/config.php一样容易
Mark Kaplun

1
您不是“无论如何都敬酒”。这是非常可能的,甚至是显而易见的,一个错误会导致Web根被重置为默认值,在这种情况下你是不是“面包” -你wp-config.php仍然安全。这是极不可能的,以至于基本上使它几乎是不可能的,一个错误会导致Web根被任意地重置为您放置了wp-config.php。的确切目录。
亚伦·亚当斯

1
@IanDunn实际上,移动wp-config.php到任意位置很容易。我在回答中增加了指示;它只涉及wp-config.php在WordPress目录中创建一个虚拟对象,引用真实对象的位置。
亚伦·亚当斯

3
这种反应是现场的。我的网络托管公司发生了驱动器阵列故障。一切都说完了之后,他们部分恢复了系统。事实证明,他们使用了一系列cPanel / WHM脚本来重建httpd.conf文件,但这样做不正确。幸运的是,我已经在doc根目录之外拥有了wp-config.php,但是如果我没有内容,可以拿走。是的,很罕见,但是如上所述,罕见的情况是您需要担心的。同样,声明“头脑简单的人会迷路”是拥有LESS安全性的不好借口。
兰斯·克利夫兰

1
很好,亚伦。由于我在本评论及其他评论主题中提到的原因,我仍然有些怀疑,但是您已经使我确信它的优点比我最初想象的要多。至少,如果做得正确,我认为这不会伤害任何事情。我仍然有一个问题,就是大多数推广它的人似乎都不了解它的原因,而且他们教它的方式通常会导致httpdocs之上的目录暴露出来,但是您已经帮助解决了这些问题。你的答案。
伊恩·邓恩

40

最大的事情是wp-config.php包含一些敏感信息:您的数据库用户名/密码等。

因此,您可以将其移动到文档根目录之外,而不必担心任何事情。攻击者将永远无法从外部来源访问该文件。

但是,这就是麻烦所在:wp-config.php永远不要在屏幕上实际打印任何内容。它仅定义在WP安装过程中使用的各种常量。因此,某人看到该文件内容的唯一方法是绕过服务器PHP解释器-他们将.php文件呈现为纯文本格式。如果发生这种情况,那么您就已经麻烦了:他们可以直接访问您的服务器(可能还有root权限),并且可以做任何他们想做的事情。

我将继续说wp-config从安全角度出发,移出文档根目录没有任何好处 -出于上述原因,这些原因如下:

  1. 您可以通过虚拟主机配置或.htaccess限制对文件的访问-以与移出文档根目录相同的方式有效地限制对文件的外部访问
  2. 您可以确保严格限制文件权限,wp-config以防止没有足够特权的任何用户读取文件,即使他们通过SSH获得(受限)服务器访问权限也是如此。
  3. 您的敏感信息(数据库设置)仅在单个站点上使用。因此,即使攻击者获得了该信息的访问权,它也会影响的唯一站点将是该wp-config.php文件所属的WordPress安装。更重要的是,该数据库用户仅具有读取和写入该WP安装数据库的权限,而没有其他权限-无权授予其他用户权限。换句话说,如果攻击者获得了对数据库的访问权限,则只需从备份中还原(请参阅第4点)并更改数据库用户即可。
  4. 您经常备份。通常是一个相对术语:如果您每天发布20篇文章,则最好每天或每隔几天备份一次。如果您每周发布一次,则每周备份一次就足够了。
  5. 您的网站受版本控制(例如),这意味着即使攻击者获得了访问权限,您也可以轻松地检测到代码更改并将其回滚。如果攻击者可以访问wp-config,那么他们可能已经搞砸了其他东西。
  6. 数据库信息确实是中唯一敏感的内容wp-config,并且因为您对此非常小心(请参阅第3点和第4点),所以这并不是什么大问题。盐等可以随时更改。唯一发生的是它使登录用户的Cookie无效。

对我来说,wp-config由于含糊不清,使文档脱离了安全性的根基-这是一个稻草人。


2
是的,那几乎就是我一直在想的。我很高兴知道我不是唯一的一个人:)我想再待一两天,以防万一有人有令人信服的反对意见,但到目前为止,这似乎是对的正确答案我。
伊恩·邓恩

3
较小的更正:将wp-config.php文件移出文档根目录没有安全性好处。还有其他好处,与安全性无关,仅适用于不寻常的设置。
奥托(Otto)

4
只是为了揭穿可能的神话-这是不可能的,服务器端可能出了一些问题-在这种情况下,php代码会显示在屏幕上?
史蒂芬·哈里斯

3
@IanDunn但最好的答案是将其完全移出该层次结构,这确实解决了您对日志等问题的担忧。此回答并未回答您的问题标题“正在……真正有益”,它只是说其他安全措施是有好处的,它们可以使您不必担心安全性。每个人都认为自己的房子是安全的,直到他们被盗。之后,他们会做得更好。即使某些人的安全性很低,他们也从未遭到盗窃,但这并不意味着降低安全性是一个好建议。
AndrewC

4
这些是很好的观点,但是我最大的问题是它们是补救性论据,而不是预防性论据。其中大多数谈论这不是什么大不了的事情,因为A)您假设某人正确地处理了db用户,B)您有备份。当您使用woocommerce之类的东西或在数据库中存储敏感信息时会发生什么?然后你就被搞砸了。
Goldentoa11年11

25

我认为马克斯(Max's)是一个知识渊博的答案,那是故事的一方面。该WordPress的食品有更多的提醒

另外,请确保只有您(和Web服务器)可以读取此文件(通常意味着400或440权限)。

如果您将服务器与.htaccess一起使用,则可以将此文件放在该文件中(位于最顶部),以拒绝访问它的任何人的访问:

<files wp-config.php>
order allow,deny
deny from all
</files>

请注意,在wp-config.php上设置400或440权限可能会阻止插件写入或修改它。例如,一个真正的案例就是缓存插件(W3 Total Cache,WP Super Cache等)。在这种情况下,我将使用600(/home/user目录中文件的默认权限)。


5
麦克斯就是答案。对他+1。我只是想扩展它。
its_me 2012年

1
Aahan Krish,您已经靶心了。感谢您的添加。
Max Yudin 2012年

因此,如果您使用htaccess拒绝对wp-config.php的HTTP请求,那么与将其移到文档根目录之外却没有暴露日志/备份/等一样,这是否会达到相同的结果呢?
伊恩·邓恩

4
@IanDunn取决于文档的根目录是什么- (1)如果wordpress托管在中的目录中public_html,则移至wp-config.php该目录之外意味着该文件将位于public_html目录中。在这种情况下,您将必须使用htaccess规则拒绝对wp-config.php的HTTP请求。(2)如果将WordPress直接安装在public_html目录下,请向上一层=>,将其移至/home/user目录中。在这种情况下,由于文件位于文档根目录之外,因此非常安全。您仍然可以将文件的权限设置为600(或更严格的440或400)。
its_me 2012年

@IanDunn就像我说的那样,这是我的基本理解,而且我不是安全专家。:)
its_me 2012年

17

有人要求我们发光,我将在这里回复。

是的,将wp-config.php与站点的根目录隔离会带来安全方面的好处。

1-如果您的PHP处理程序被破坏或以某种方式被修改,您的数据库信息将不会被公开。是的,在服务器更新期间,我在共享主机上看到了几次这种情况。是的,在此期间该站点将被破坏,但您的密码将保持不变。

2-最佳做法始终建议将配置文件与数据文件隔离。是的,使用WordPress(或任何网络应用程序)很难做到这一点,但是将其向上移动确实有点孤立。

3-记住PHP-CGI漏洞,任何人都可以将?-传递到文件并查看源。http://www.kb.cert.org/vuls/id/520827

最后,这些都是很小的细节,但它们确实有助于最大程度地降低风险。特别是在共享环境中,任何人都可以访问您的数据库(他们所需要的只是一个用户/密码)。

但是,不要让小干扰(过早的优化)摆在使站点正确安全的真正必要条件的前面:

1-始终保持更新

2-使用强密码

3-限制访问(通过权限)。我们在这里有一篇关于它的文章:

http://blog.sucuri.net/2012/08/wordpress-security-cutting-through-the-bs.html

谢谢,


大家好,感谢您的补充。我认为我们已经在其他答案及其评论中提到了大多数问题。1)是的,这是可能的,但很少见;2)是的,这是有好处的,但是它们很小。3)是的,这是可能的,但是这种类型的漏洞不太可能再次发生,并且防范该漏洞就像打打wh鼠,或者使人们在机场脱鞋,因为有些公驴将炸弹藏在了他的炸弹中一次穿鞋。这是反动的,不可能带来未来的收益。
伊恩·邓恩2012年

在各种讨论中,问题从“有没有好处?”中提炼出来。“好吧,虽然有一些好处,但是超过了风险吗?” 我要指的主要风险是必须扩展openbase_dir范围,以便让PHP访问Web根目录之外的脚本。许多托管设置-包括大量使用Plesk的设置-将日志,备份,应该与Web根隔离的私有FTP区域等存储在Web根上方的目录中。因此,授予PHP访问该目录的权限可能是一个严重的漏洞。
伊恩·邓恩

15

绝对可以。

当您将wp-config.php移到公共目录外时,当php处理程序被恶意(或意外!)更改时,可以防止使用浏览器读取它。

当由于la脚的管理员的故障而几乎没有感染服务器时,可以读取数据库的登录名/密码。向管理员收取罚款,并获得趋向更好和更可靠的服务器主机。虽然那可能更昂贵。


4
如果攻击者有足够的权限来更改PHP处理程序,那么您已经搞砸了。根据我的经验,偶然的更改非常罕见,在这种情况下,更改密码很容易。鉴于上述情况,由于open_basedir范围扩大,您是否仍然值得冒暴露日志/备份/等风险?
伊恩·邓恩

1
我从未-rwx访问过比以前更高的目录,public_html所以我从未熟悉过open_basedir。我的日志位于单独的目录中,因此备份也是如此。我认为这就是所有共享主机所拥有的。
Max Yudin

寄主千差万别;没有标准的目录结构。Plesk(共享主机最受欢迎的控制面板之一)将日志放入/var/www/vhosts/example.com/statistics/logs,文档根目录为/var/www/vhosts/example.com/httpdocs。将wp-config.php移至/var/www/vhosts/example.com/wp-config.php将需要授予脚本访问整个example.com目录的权限。
伊恩·邓恩

出于好奇,您的日志和备份存储在哪里(如果不在域目录中)?是否通过控制面板或其他工具访问它们?
伊恩·邓恩

1
是的,通过控制面板。
Max Yudin

8

为了便于讨论,我只想澄清一下,移动wp_config.php文件并不一定意味着您只需要将其移动到父目录即可。假设您有一个类似/ root / html的结构,其中html包含WP安装和所有HTML内容。除了将wp_config.php移至/ root之外,您还可以将其移至/ root / secure ...之类,它既位于html目录之外,也不位于服务器根目录中。当然,您需要确保php也可以在此安全文件夹中运行。

由于无法将WP配置为在/ root / secure之类的同级文件夹中寻找wp_config.php,因此您必须采取其他步骤。我将wp_config.php留在/ root / html中,并剪掉敏感部分(数据库登录名,salt,表前缀)并将其移至名为config.php的单独文件中。然后,将PHP include命令添加到wp_config.php中,如下所示:include('/home/content/path/to/root/secure/config.php');

这基本上就是我在设置中所做的。现在,基于以上讨论,我仍在评估是否有必要甚至是一个好主意。但我只是想补充一点,上面的配置是可能的。它不会公开您的备份和其他根文件,并且只要安全文件夹未使用其自己的公共URL进行设置,便无法浏览。

此外,可以通过在其中创建.htaccess文件来限制对安全文件夹的访问:

order deny,allow
deny from all
allow from 127.0.0.1

嗨,迈克尔,感谢您的分享。但是,您是否在真实环境中尝试过以验证其正常工作?我认为该open_basedir指令需要一棵完整的,因此/root/secure要从中进行访问/root/html,您必须设置open_basedir/root
伊恩·邓恩

为了使您的想法可行,我认为您需要设置目录结构,如/root/httpdocs/config/accessible,其中httpdocs保存日志,备份等;config拥有wp-config.php,并accessible拥有WordPress和所有内容。您必须修改vhost配置等,才能将文档根目录重新映射到accessible。但是,在默认设置中,仅拒绝HTTP请求到wp-config不会带来任何好处。
伊恩·邓恩

1
根据php.net/manual/en/ini.core.php#ini.open-basedir的说法:“在Windows下,用分号分隔目录。在所有其他系统上,用冒号分隔目录。作为Apache模块,来自父目录的open_basedir路径现在将自动继承。” 因此,您可以设置多个目录,而无需将它们放在单个树中。
迈克尔

我刚刚测试了一下,看来您是对的。不过,我仍然不确定与仅通过Apache拒绝访问文件相比,这具有什么安全优势。
伊恩·邓恩

@IanDunn在亚伦·亚当斯(Aaron Adams)的回答中得到了很好的回答
AndrewC

4

有很多不良的书面主题和插件,可以让atatcker注入代码(记住Timthumb的安全性问题)。如果我会成为攻击者,为什么还要搜索wp-config.php?只需注入以下代码:

var_dump( DB_NAME, DB_USER, DB_PASSWORD );

您可以尝试隐藏您的wp-config.php。只要WordPress使所有敏感信息都可以全局访问,隐藏wp-config.php就没有任何好处。

wp-config.php中的坏处不是它保存敏感数据。不好的部分是将敏感数据定义为全局可访问常量。

更新资料

我想弄清楚问题define()以及为什么将敏感数据定义为全局常量是个坏主意。

有许多攻击网站的方法。脚本注入只是攻击网站的一种方法。

假设服务器存在一个漏洞,攻击者可以利用该漏洞访问内存转储。攻击者将在内存转储中找到所有变量的所有值。如果定义了全局可访问常量,则它必须保留在内存中,直到脚本结束。创建一个变量而不是一个常量,垃圾回收器很有可能在不再需要该变量之后覆盖(或释放)内存。

保护敏感数据的更好方法是在使用敏感数据后立即将其删除:

$db_con = new stdClass();
$db_con->db_user = 'username';
$db_con->password = 'password';
$db_con->host = 'localhost';

$db_handler = new Database_Handler( $db_con );

$db_con = null;

使用敏感数据后,分配给null将覆盖内存中的数据。攻击者必须在$db_con包含敏感数据时立即获取内存转储。在上面的示例中,这是很短的时间(如果类Database_Handler不保存其副本)。


此答复未直接解决问题。如果任何插件作者说服您安装他们的代码并且有恶意,他们都可以在WordPress上度过美好的一天。这与在系统上自愿安装病毒没有什么不同。这个不移动wp-config.php的参数是没有意义的。这就像在汽车中故意安装汽车炸弹,使设置汽车防盗器毫无用处。从技术上讲是真实的,但是WTF?!?
Lance Cleveland

2
不,这不是没有意义的。问题是:我可以通过隐藏wp-config.php保护数据库帐户。答案很明显:不会。就好像您问“我可以用汽车警报器保护我的汽车免受汽车炸弹袭击吗?” 通过隐藏wp-config来保护数据库访问或ftp访问没有其他好处。两者都在全球范围内。我敢肯定,攻击者还有更多方法无需注入代码即可访问全局变量。
Ralf912

我没有在原始问题中看到“可以通过隐藏wp-config.php来保护数据库帐户吗”。最初的问题是“移动wp-config.php是否有意义”。答案是肯定的,IMO。这就像在问外出时是否应该锁上前门。说“任何人都可以轻易打破窗户进入,所以为什么要打扰”并不能回答问题的基本要点。IMO提出的问题是:“移动wp-config.php是否值得付出额外的努力?这样做有什么好处吗?”。是。至少,它可以阻止懒惰的黑客。
兰斯·克利夫兰

2
最常见的安全最佳实践之一...您错过了非常非常重要的一点:攻击者对什么感兴趣?这不是您如何设置wp-config.php的样式。攻击者对您在wp-config中定义的值感兴趣。用前门抓取您的示例:隐藏wp-config就像您将前门锁起来一样,但是将所有未受保护的黄金存储在花园中。wp-config中定义的所有值都是全局定义的。因此,他们是所有 WP-Config的外部访问。即使您隐藏了wp-config,这些值仍然存在。
拉尔夫912

1
我认为那些主张移动它的人正在尝试保护wp-config.php可以通过HTTP请求以纯文本显示的情况,而不是可以将其暴露给主机上运行的其他PHP代码的情况。
伊恩·邓恩

-1

除了安全性优点外,它还允许您将WordPress实例保持在版本控制下,同时将核心WordPress文件保留为子模块/外部。这就是Mark Jaquith设置其WordPress-Skeleton项目的方式。有关详细信息,请参见https://github.com/markjaquith/WordPress-Skeleton#assumptions


8
他将其设置在文档根目录中,而不是在其外部,因此与该问题无关。该问题询问的技术指定您将wp-config.php目录移至vhost文档根目录上方,而不只是将目录移至WordPress安装文件夹上方。重点是将其放在HTTP请求可以读取的文件夹之外。
伊恩·邓恩
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.