使用.htaccess文件禁用目录中的PHP(包括所有子目录)

76

我正在制作一个网站,允许人们上传文件、html页面等。现在我遇到了一个问题。我的目录结构如下:

-/USERS
    -/DEMO1
    -/DEMO2
    -/DEMO3
    -/etc... (every user has his own direcory here)
-index.php
-control_panel.php
-.htaccess

现在我想禁用PHP,但是在/USERS目录及其子目录中启用服务器端包含。这可以实现吗(如果可以,如何实现)?

我使用WAMP服务器。

11个回答

130

尝试在您的.htaccess文件中禁用engine选项:

php_flag engine off

11
文件内容将被发送给客户端。但是为什么不自己尝试一下,看看会发生什么呢? - Gumbo
22
请注意,如果未安装 mod_php 作为 PHP,则会返回 500 错误。请将其包含在 <IfModule mod_php5.c> ... </IfModule> 中。 - Halil Özgür
4
可以使用 php_admin_flag,但不能在 .htaccess 文件中使用。任何使用 php_admin_value 设置的指令类型都不能被 .htaccess 或 ini_set() 覆盖。要清除先前设置的值,请将值设为 none。 - pylover
9
有人可以创建一个子目录,在新的.htaccess文件中添加"php_flag engine on",然后从这个子目录运行PHP代码吗? - user5858
3
我不建议使用这个。正如一些人所指出的那样,这会允许用户下载你的PHP文件内容。我认为这非常不安全,不应该这样做。 - Pierre-Olivier Benoit
显示剩余10条评论

52

要禁用所有子目录的访问(最安全),请使用:

<Directory full-path-to/USERS>
     Order Deny,Allow
     Deny from All
 </Directory>

如果你只想阻止PHP文件被直接访问,可以这样做:

1 - 确保你知道服务器将哪些文件扩展名识别为PHP,并且不允许在htaccess中覆盖设置。我的一个服务器设置如下:

# Example of existing recognized extenstions:
AddType application/x-httpd-php .php .phtml .php3

2- 根据扩展名在FilesMatch(或LocationMatch)中添加正则表达式。

 <Directory full-path-to/USERS>
     <FilesMatch "(?i)\.(php|php3?|phtml)$">
            Order Deny,Allow
            Deny from All
    </FilesMatch>
 </Directory>

或者使用 Location 来匹配 PHP 文件(我更喜欢上述文件的方法)

<LocationMatch "/USERS/.*(?i)\.(php3?|phtml)$">
     Order Deny,Allow
     Deny from All
</LocationMatch>

3
“不要允许人们在htaccess中覆盖”,是的,这是一个非常好的建议。如果人们可以使用本地htaccess文件轻松覆盖您的htaccess,则所有在htaccess中的工作都将被浪费。您的演示环境可能没有php文件的用途,因此最好不要允许它们被创建或提供(甚至包括源代码视图),直接完全阻止它们(包括htaccess文件)。 - Timo Tijhof
很好的评论,我忽视了人们可以上传“.htaccess”文件的想法。 - bart
1
这在 .htaccess 文件中不起作用(出现错误 500)。应该将其添加到 Apache 配置文件的虚拟主机中。 - NicolasBernier
我能建议一个更短的正则表达式来覆盖所有的php1-php5和phtml文件: "(?i)\.(ph.+)$" - Aleksey Napolskih
如前所述,这对于 .htaccess 文件无效,需要放置在 Apache 的 vhost 配置中。要使第一个示例在 .htaccess 文件中起作用,只需使用以下内容: Order Deny,Allow Deny from All - Pierre-Olivier Benoit

13

如果你正在使用mod_php,你可以将以下内容放置在/USERS目录下的.htaccess文件中或者在httpd.conf文件中针对USERS目录进行配置。

RemoveHandler .php
或者
RemoveType .php

(根据是否使用AddHandler或AddType启用了PHP)

从另一个目录运行的PHP文件仍然可以包含/USERS中的文件(假设没有open_basedir限制), 因为这不经过Apache。如果使用Apache访问php文件,将以纯文本形式提供。

编辑

Lance Rushing的解决方案只是拒绝访问文件可能更好。


10
<Directory /your/directorypath/>
     php_admin_value engine Off
</Directory>

12
请考虑添加一些额外的评论。 - Stewie Griffin
这将把PHP源代码以纯文本形式输出给客户端,请不要使用这个指令 - undefined

9
这将显示源代码而不是执行它:
<VirtualHost *>
    ServerName sourcecode.testserver.me
    DocumentRoot /var/www/example
    AddType text/plain php
</VirtualHost>

我曾经使用它来使其他同事能够从本地网络读取源代码(只是一个快速而不完美的替代方案)。 警告! 正如Dan之前指出的那样,这种方法永远不应该在生产环境中使用。请遵循接受的答案,因为它会阻止任何尝试执行或显示php文件。
如果您希望用户共享php文件(并让其他人显示源代码),有更好的方法可以实现,例如git、wiki等。
应该避免使用这种方法!(你已经被警告了。将其保留在此处仅供教育目的)

2
严重的安全漏洞!不要在生产环境中使用! - Dan Garland
@DanGarland,请告诉我们如何做到? - Airy
1
@AbdulJabbarWebBestow 的原因是因为任何人都可以查看源代码而不是执行它。如果这些代码包含敏感信息(如连接密码),那么这些信息可能会被泄露。 - lepe
@DanGarland,我刚看到他的代码中提到了text/plain的根目录。你是完全正确的。我可以看到Lepe已经编辑了他的答案并接受了你的观点。 - Airy
2
“安全漏洞”是一个使用问题:在存储用户上传内容的目录中放置“AddType text/plain php”可能是一个有趣的安全防护措施:如果用户设法上传PHP文件,则服务器不会执行它,当然他们会看到PHP源代码,但是这是从他们上传的文件中。 - Xenos

9

对于我而言,所有这些答案都无法解决我的问题(要么生成500错误,要么什么都不做)。这可能是因为我正在使用托管服务器,在那里我无法访问Apache配置。

但是下面这行代码对我有效:

RewriteRule ^.*\.php$ - [F,L]

这行代码将在以.php结尾且位于此子目录中的任何URL上生成403 Forbidden错误。

@Oussama引导了我到正确的方向(这里),感谢他。


2
如果您使用 php-fpmphp_admin_value不起作用,并会导致内部服务器错误。

请在您的.htaccess中使用以下代码。它将禁用该文件夹及其所有子文件夹中的解析器:

<FilesMatch ".+\.*$">
    SetHandler !
</FilesMatch>

1
在生产环境中,我更喜欢将请求重定向到禁用 PHP 处理的目录下的 .php 文件,以显示主页或 404 页面。这样不会暴露任何源代码(为什么搜索引擎应该索引上传的恶意代码?),并且对于访问者甚至试图利用该内容的邪恶黑客来说都更友好。此外,它可以在大多数情况下实现 - vhost 或 .htaccess。类似这样:
<DirectoryMatch "^${docroot}/(image|cache|upload)/">
    <FilesMatch "\.php$">
        # use one of the redirections
        #RedirectMatch temp "(.*)" "http://${servername}/404/"
        RedirectMatch temp "(.*)" "http://${servername}"
    </FilesMatch>
</DirectoryMatch>

根据您的需要调整指令。


1
这可能有点过度了 - 但是小心进行任何依赖于 PHP 文件扩展名为 .php 的操作 - 如果以后有人添加了对 .php4 或甚至 .html 的处理程序,使它们由 PHP 处理,那该怎么办呢?你最好从不同的 Apache 实例或其他仅提供静态内容的服务中提供这些目录中的文件。

5
@Nevermind - 我不是在谈论你的用户,我在谈论你自己,或者两年后的其他系统管理员。 - Dominic Rodger

1

我在Centos 6.10中使用虚拟主机的.conf定义文件来处理多个文件夹:

<DirectoryMatch ^/var/www/mysite/htdocs/(nophpexecutefolder1|nophpexecutefolder2)>
       php_admin_value engine Off
</DirectoryMatch>

然而,即使它不像通常解析php代码那样,当执行echo时,它仍会从.php文件输出诸如变量声明和文本等内容。
<?php

echo "<strong>PHP CODE EXECUTED!!";

$a=1;
$b=2;

echo $a+$b;

以上在网页浏览器中产生了什么?

PHP CODE EXECUTED!!"; $a=1; $b=2; echo $a+$b;

这可能会向用户公开一些代码,这并不理想。

因此,在 .htaccess 中最好与以下内容结合使用:

<FilesMatch ".*.(php|php3|php4|php5|php6|php7|php8|phps|pl|py|pyc|pyo|jsp|asp|htm|html|shtml|phtml|sh|cgi)$">
 Order Deny,Allow
 Deny from all
  #IPs to allow access to the above extensions in current folder
  # Allow from XXX.XXX.XXX.XXX/32 XXX.XXX.XXX.XXX/32
</FilesMatch>

以上代码将阻止访问任何上述文件扩展名,但允许其他扩展名(如图像、CSS等)以通常的方式被访问。当访问.php文件时会出现错误:
Forbidden

You don't have permission to access /nophpexecutefolder1/somefile.php on this server.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接