PHP:如何用 strip_tags($_POST[...]) 批量替换 $_POST[...]

Posted

技术标签:

【中文标题】PHP:如何用 strip_tags($_POST[...]) 批量替换 $_POST[...]【英文标题】:PHP: How to mass replace $_POST[...] with strip_tags($_POST[...]) 【发布时间】:2011-04-03 12:51:05 【问题描述】:

我目前正从一次严重的 XSS 攻击中恢复过来,并意识到我从未对我网站上的几个表单上的输入进行清理。我使用 Notepad++ 的 Find In Files 功能在我的所有 php 文件中搜索 $_POST,并获得了近 5,000 个结果。现在,我真的不想去手动将strip_tags 添加到这些结果中的每一个,但是全部替换并不能解决问题……而且我完全是个菜鸟,比如正则表达式。

有什么办法可以让这件事变得不那么乏味吗?

【问题讨论】:

【参考方案1】:

只需使用array_map()

$Clean = array_map('strip_tags', $_POST);

或者如果你想让它回到$_POST变量:

$_POST = array_map('strip_tags', $_POST);

尽管使用不同的变量并将文件中所有出现的$_POST 更改为$Clean,这可能是一个更好的主意。

【讨论】:

【参考方案2】:

嗯,我认为array_walk_recursive 可以解决问题:

function custom_strip(&$val, $index) 
   $val = strip_tags($val);

array_walk_recursive($_POST, 'custom_strip');

【讨论】:

【参考方案3】:

你可以把它放在一个文件中(例如safe.php)

foreach ($_POST as $key => $value) 
  $_POST[$key] = is_array($key) ? $_POST[$key]: strip_tags($_POST[$key]);

然后将 require_once("safe.php"); 放入每个 php 文件(或所有 php 文件已包含的文件) 这是一个丑陋的黑客......但它可以节省你的时间。

【讨论】:

太棒了。这正是我想要的。 当表单字段名称如foo[bar]foo[] PHP 会自动转换为数组时,这将无法防止XSS。 @Tgr:是的,这绝对会像你说的那样失败,但我认为他有根据自己的需要定制的想法【参考方案4】:

非常简单。把它放在你的每个文件的顶部,或者放在一个公共的头文件中,每次都在开始时调用它:

function mystriptag(&$item)

    $item = strip_tags($item);


array_walk($_POST, mystriptag);

【讨论】:

当表单字段的名称如foo[bar]foo[] PHP 自动转换为数组时,这将无法防止XSS。【参考方案5】:

你可以只用array_mapstrip_tags$_POST,但是编写一个自定义函数来从中获取数据要好得多:

function post_data($name) 
    global $post_cache;
    if (in_array($name, $post_cache)) 
        return $post_cache[$name];
    
    $val = $_POST[$name];
    if (is_string($val)) 
        $val = strip_tags($val);
     else if (is_array($val)) 
        $val = array_map('strip_tags', $val);
    
    $post_cache[$name] = $val;
    return $val;

这将使您的代码更具可读性(其他研究它的人通常会认为$_POST['foo'] 是表单字段foo 中的数据,而不是您已经预处理过的数据),不会导致您出现插件或库问题它尝试直接访问 $_POST ,可以轻松地向$_POST 预处理添加更多逻辑(启用magic quotes 时不转义是一种常见的逻辑),而无需查找代码中使用过POST数据的所有位置,并且当您意识到有一些 POST 字段确实需要 html 标记时,可以让您免于头疼。一般来说,直接更改任何超全局变量是一个非常糟糕的主意。

此外,最好在输出上而不是输入上清理数据。不同的用途需要不同的方法,例如,如果你使用

<div class="user_photo">
   <img src="<?php echo photo_path($user_id) ?>"  />
</div>

那么$user_name 是XSS 攻击向量,strip_tags 根本无济于事;你需要htmlspecialchars。如果将用户数据用作 URL,则需要另一种方法来防御 javascript: URL 等。

【讨论】:

以上是关于PHP:如何用 strip_tags($_POST[...]) 批量替换 $_POST[...]的主要内容,如果未能解决你的问题,请参考以下文章

[PHP问题]如何用$_POST拿多个data?

bbs发帖核心代码

如何用php向服务器发送post请求

三种方法教你如何用PHP模拟post提交数据

这段表单如何用PHP 模拟post提交?

PHP如何不用表单进行POST传递