一些需要禁用的PHP危险函数(disable_functions)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一些需要禁用的PHP危险函数(disable_functions)相关的知识,希望对你有一定的参考价值。

参考技术A phpinfo()
功能描述:输出
PHP
环境信息以及相关的模块、WEB
环境等信息。
危险等级:中
passthru()
功能描述:允许执行一个外部程序并回显输出,类似于
exec()。
危险等级:高
exec()
功能描述:允许执行一个外部程序(如
UNIX
Shell

CMD
命令等)。
危险等级:高
system()
功能描述:允许执行一个外部程序并回显输出,类似于
passthru()。
危险等级:高
chroot()
功能描述:可改变当前
PHP
进程的工作根目录,仅当系统支持
CLI
模式
PHP
时才能工作,且该函数不适用于
Windows
系统。
危险等级:高
scandir()
功能描述:列出指定路径中的文件和目录。
危险等级:中
chgrp()
功能描述:改变文件或目录所属的用户组。
危险等级:高
chown()
功能描述:改变文件或目录的所有者。
危险等级:高
shell_exec()
功能描述:通过
Shell
执行命令,并将执行结果作为字符串返回。
危险等级:高
proc_open()
功能描述:执行一个命令并打开文件指针用于读取以及写入。
危险等级:高
proc_get_status()
功能描述:获取使用
proc_open()
所打开进程的信息。
危险等级:高
error_log()
功能描述:将错误信息发送到指定位置(文件)。
安全备注:在某些版本的
PHP
中,可使用
error_log()
绕过
PHP
safe
mode,
执行任意命令。
危险等级:低
ini_alter()
功能描述:是
ini_set()
函数的一个别名函数,功能与
ini_set()
相同。
具体参见
ini_set()。
危险等级:高
ini_set()
功能描述:可用于修改、设置
PHP
环境配置参数。
危险等级:高
ini_restore()
功能描述:可用于恢复
PHP
环境配置参数到其初始值。
危险等级:高
dl()
功能描述:在
PHP
进行运行过程当中(而非启动时)加载一个
PHP
外部模块。
危险等级:高
pfsockopen()
功能描述:建立一个
Internet

UNIX
域的
socket
持久连接。
危险等级:高
syslog()
功能描述:可调用
UNIX
系统的系统层
syslog()
函数。
危险等级:中
readlink()
功能描述:返回符号连接指向的目标文件内容。
危险等级:中
symlink()
功能描述:在
UNIX
系统中建立一个符号链接。
危险等级:高
popen()
功能描述:可通过
popen()
的参数传递一条命令,并对
popen()
所打开的文件进行执行。
危险等级:高
stream_socket_server()
功能描述:建立一个
Internet

UNIX
服务器连接。
危险等级:中
putenv()
功能描述:用于在
PHP
运行时改变系统字符集环境。在低于
5.2.6
版本的
PHP
中,可利用该函数
修改系统字符集环境后,利用
sendmail
指令发送特殊参数执行系统
SHELL
命令。
危险等级:高
禁用方法如下:
打开/etc/php.ini文件,
查找到
disable_functions
,添加需禁用的函数名,如下:
phpinfo,eval,passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,fsockopen

从客户端检测到潜在危险的 Request.Path 值 (&)

【中文标题】从客户端检测到潜在危险的 Request.Path 值 (&)【英文标题】:A potentially dangerous Request.Path value was detected from the client (&) 【发布时间】:2011-08-06 15:10:24 【问题描述】:

我明白为什么会发生这种情况,但我需要解决方法。我在 *** 上查看了其他一些问题,但没有一个有帮助。我不想禁用整个网站的输入验证,因为这绝对是危险的。我只有一个(至少现在)需要禁用输入验证的地方。

我使用 [ValidateInput(false)] 属性修饰了 Action Method,并且使用 Html.Encode 对字符串进行了编码。但是,我仍然遇到同样的错误。这是我的看法:

<div id="sharwe-categories">
    <ul class="menu menu-vertical menu-accordion">
        @foreach(var topLevel in Model)
        
            var topLevelName = Html.Encode(topLevel.Name);
             <li class="topLevel">
                <h3>  
                    @Html.ActionLink(topLevel.Name, "Index", "Item", new  category = topLevelName , new @class = "main" )
                    <a href="#" class="drop-down"></a>
                </h3>
                <ul>
                    @foreach (var childCategory in topLevel.Children)
                    
                        var childcategoryName = Html.Encode(childCategory.Name);
                        <li>@Html.ActionLink(childCategory.Name, "Index", "Item", new RouteValueDictionary   "category", topLevelName ,  "subcategory", childcategoryName  , null)</li>
                    
                </ul>
            </li>
        

    </ul>

</div>

如您所见,没有用户输入。但是有些类别名称中有一些“危险”字符...有什么解决办法吗?

【问题讨论】:

你能提供导致问题的值吗? @Robert Koritnik:包含“&”或“,”或任何危险字符的值... 【参考方案1】:

您可能会发现following blog post 对于在 url 中使用特殊字符很有用。但一般来说,最好的做法是 replace those titles with slugs 与 *** 一样,在 url 中使用问题标题以获得更好的 SEO 并使用 id 来识别它们。

【讨论】:

但是使用 requestValidationMode v2 并使用 [ValidateInput(false)] 装饰 Action 方法是否安全?在我的应用程序中,安全性是重中之重,所以我不能冒任何风险...... @Kassem,ValidateInput(false) 属性用于将 HTML 发布到控制器操作。在 ASP.NET MVC 3 中,您可以使用 [AllowHtml] 属性来装饰视图模型属性,该属性将仅对更安全的该属性禁用请求验证。如果您使用AllowHtml 属性,则无需设置requestValidationMode="2.0"。如果您想将特殊字符作为 url 的一部分和您没有选择的路由参数发布,则需要遵循我链接到的博客文章中的建议。 除非他以某种方式更改类别命名...通常或仅在 URL 中使用时... @Robert Koritnik,是的,这正是我建议的两种解决方案之一:使用蛞蝓。 是的,你做到了。我同意。但是添加了 ID,我认为这在他的情况下是不可行的,因为它有多个类别。但是,是的。你做到了。【参考方案2】:

尽管 Darin 的答案完全可行,但我不建议使用 Scott Hanselman 逐步关闭所有这些验证的技术。你迟早会陷入深渊……

使用 ID 和虚拟字符串(这对 SEO 和人们非常有用)的第二个建议是一种可行的方法,但有时它们也不可行。想象一下这个请求 URL:

/111/Electronics/222/Computers/333/Apple

虽然我们有这些我们可以依赖的 ID 和人类/SEO 友好的类别名称,但这绝对不是我们想要的。当我们需要表示单个项目时,ID + Dummy string 是可行的。在其他情况下不是。而且由于您必须显示类别和子类别,这是一个问题。

那你能做什么?

两种可能的解决方案:

    将类别名称清理为仅包含有效字符 - 可以这样做,但如果这些不是静态的并且特权用户无法编辑,那么您在这里就不走运了,因为即使您现在已经清理了它们,稍后有人会输入无效的内容

    随时随地清理您的字符串 - 当您使用类别名称时,将其清理并在读取和使用它(以获取实际的类别 ID)时,您可以将提供的(先前清理的)类别名称与您在 DB 中的值进行比较随时清理:

      现在在过滤类别时 在生成类别名称之前

我建议您采用 2.2 方法。扩展您的数据库表以包含两列:

类别显示名称 类别 URL 友好名称

您还可以在第二列上设置唯一约束,这样就不会发生您的两个类别(即使它们具有不同的显示名称)具有相同的 URL 友好名称。

如何清洁

首先想到的是去除无效字符,但这非常繁琐,而且您很可能会遗漏一些内容。从您的类别显示名称中获取有效字符更加容易和明智。我在生成 dummy URL 类别名称时也做了同样的事情。只需取出有效的并将其余的放入垃圾箱。它通常工作得很好。此类正则表达式的两个示例:

    (\w2,) - 只使用字母、数字和下划线,并且至少使用其中两个(因此我们省略了 a 或单个数字和类似的东西,它们不会增加任何意义,并且会不必要地延长我们的 URL ([a-zA-Z0-9]2,) - 只有字母和数字(也是 2+)

获取您的类别显示名称中的所有匹配项,并用空格/破折号将它们连接起来,并与原始显示名称一起保存。一个不同的question of mine 正是与此有关。

为什么要增加一列?因为您无法在 SQL Server 中运行正则表达式。如果您使用的是 MySql,您可以使用一列并在 DB 上使用正则表达式。

【讨论】:

效果非常好!感谢您的建议,不胜感激:)【参考方案3】:

即使您不应该这样做……有时也没有一种简单的方法可以绕过它。 web.Config 中 httpRuntime 标记上的 requestPathInvalidCharacters 是您所寻求的。只需在 部分输入以下内容:

&lt;httpRuntime requestPathInvalidCharacters="&amp;lt;,&amp;gt;,*,%,:,\" /&gt;

我强烈建议使用以下方法锁定它:

<location path="the/path/you/need/to/lock/down">
    <system.web>
        <httpRuntime requestPathInvalidCharacters="&lt;,&gt;,*,%,:,\"/>
    </system.web>
</location>

只需将其放入根 标记中即可。这样...您不会打开整个站点以允许路径中出现 & 符号...并可能使整个站点遭受无法预料的攻击。

【讨论】:

以上是关于一些需要禁用的PHP危险函数(disable_functions)的主要内容,如果未能解决你的问题,请参考以下文章

Apache降权和禁用PHP危险函数

工作笔记04----------禁用PHP危险函数

宝塔面板 – NGINXPHP版本号隐藏/危险函数的禁用

PHP 危险函数(转载)

PHP操作用户提交内容时需要注意的危险函数

PHP安全配置之禁用参数