解码mysql_real_escape_string()以输出HTML

时间:2010-04-04 02:17:34

标签: php sql-injection html-encode mysql-real-escape-string

我正在尝试保护自己免受sql注入并使用:

mysql_real_escape_string($string);

发布HTML时,它看起来像这样:

<span class="\&quot;className\&quot;">
<p class="\&quot;pClass\&quot;" id="\&quot;pId\&quot;"></p>
</span>

我不确定real_escape_string添加了多少其他变体,所以不想只替换一些并错过其他变种...如何将此“解码”回到格式正确的HTML中,例如:

html_entity_decode(stripslashes($string));

9 个答案:

答案 0 :(得分:13)

mysql_real_escape_string()手册页会告诉您转义了哪些字符:

  

mysql_real_escape_string()调用   MySQL的库函数   mysql_real_escape_string,其中   在下面添加反斜杠   字符:\ x00,\ n,\ r,\,',“和   \ X1A。

您可以通过使用未转义的表单替换这些转义字符来成功撤消转义。

不应该使用

mysql_real_escape_string()来清理HTML ...在输出网页数据之前没有理由使用它。它应该只用于您要放入数据库的数据。您的清理过程应如下所示:

<强>输入

  1. 接受来自表单或HTTP请求的用户输入
  2. 使用mysql_real_escape_string()
  3. 创建数据库查询

    <强>输出

    1. 从数据库中提取数据
    2. 在打印前通过htmlspecialchars()运行任何用户定义的数据
    3. 使用其他数据库驱动程序(例如MySQLiPDO)将允许您使用预准备语句,这些语句负责为您转义大多数输入。但是,如果你无法切换或利用它们,那么一定要使用mysql_real_escape_string() ...只在插入数据之前使用它。

答案 1 :(得分:9)

你搞得一切都搞砸了。

mysql_real_escape_string不需要任何解码。

如果您使用斜杠获取数据,则表示已经转义两次。而不是剥离额外的斜杠,你应该不添加它们。

更不用说无论什么逃避已经过时,你应该

使用预备陈述

而不是任何转义字符串。

所以,永远不要逃避,永远不要解码 问题解决了。

答案 2 :(得分:8)

mysql_real_escape_string用于在将用户提供的数据存储到数据库时阻止SQL注入,但更好的方法是使用PDO(例如)使用数据绑定。我总是建议使用它而不是弄乱逃脱。

话虽如此,关于如何在之后显示它的问题 - 在存储数据之后,当您检索数据时,数据是完整且有效的,而不需要“未转义”。除非您添加了自己的转义序列,否则请不要这样做。

答案 3 :(得分:0)

不知道格式化是怎么回事,因为我可以看到它,但你的html表单

<span class="\&quot;className\&quot;">
<p class="\&quot;pClass\&quot;" id="\&quot;pId\&quot;"></p>
</span>

应该简单;

<span class="className">
<p class="pClass" id="pId"></p>
</span>

当你把它拿回来之后,在你把它放入数据库之前你使用mysql_real_escape_string()来逃避它,以确保你不会遭受SQL注入攻击。

因此,您正在逃避准备放置文本下一步的值。

当你从数据库中取出它(或者以html的形式向用户显示任何内容)时,你再次将它转义为下一个(html)与htmlentities()等的地方,以保护你的用户免受XSS攻击攻击。

这构成了口头禅FIEO,过滤器输入,逃生输出的EO部分,你应该在你的眼睑内侧纹身。

答案 4 :(得分:0)

好吧,我采用旧时尚的方式刺了一下,到目前为止,我无法看到我的方法有什么问题。显然它有点粗糙,但它完成了工作:

function mysql_unreal_escape_string($string) {
    $characters = array('x00', 'n', 'r', '\\', '\'', '"','x1a');
    $o_chars = array("\x00", "\n", "\r", "\\", "'", "\"", "\x1a");
    for ($i = 0; $i < strlen($string); $i++) {
        if (substr($string, $i, 1) == '\\') {
            foreach ($characters as $index => $char) {
                if ($i <= strlen($string) - strlen($char) && substr($string, $i + 1, strlen($char)) == $char) {
                    $string = substr_replace($string, $o_chars[$index], $i, strlen($char) + 1);
                    break;
                }
            }
        }
    }
    return $string;
}

这应该涵盖大多数情况。

答案 5 :(得分:-1)

我想知道为什么这个例程没有附带的解码器例程。它可能由MySQL解释,就像它没有被转义一样。当您执行$row=mysql_fetch_array($res, MYSQL_ASSOC)';

时,您会获得未转义的结果

答案 6 :(得分:-1)

即使这是一个老问题...... 我和彼得克雷格有同样的问题。 事实上,我要处理一个旧的CMS。为了防止SQL注入,所有$ _POST和$ _GET值都是“sql-escaped”。不幸的是,这是在一个中心点完成的,所以你所有的模块都在接收所有sql-escape的数据!在某些情况下,您希望直接显示这些数据,以便您遇到问题:如何显示sql-escaped字符串而不从DB中获取它? 答案是: 使用stripcslashes(不是stripslashes !!)

http://php.net/manual/en/function.stripcslashes.php

答案 7 :(得分:-1)

使用以下函数在HTML页面上显示时删除斜杠:

stripslashes()函数;

例如。 $ HTML =的stripslashes($ HTML); 要么 $ HTML =的stripslashes($行[&#34;字段名&#34;]);

答案 8 :(得分:-2)

我认为其他一些答案错过了明显的问题......

您在输入的内容上使用mysql_real_escape_string(如果不使用预准备语句,则应如此)。

您的问题在于输出。

目前的问题是您正在调用html_entity_decode。只需条带即可恢复原始文本。 html_entity_decode正在弄乱你的报价等,因为它正在改变它们。你实际上想要输出html,而不仅仅是纯文本(这是你何时使用html_entities等)。您正在解码您想要编码的内容。

如果您只想显示文本版本,则可以使用实体。如果您担心坏标签,请使用striptags并仅允许您想要的标签(例如b,i等)。

最后,请记住以正确的顺序进行编码和解码。如果你运行mysql_real_escape_String(htmlentities($ str)),那么你需要运行html_entity_decode(stripslashes($ str))。操作顺序很重要。

更新:我没有意识到html_entity_decode也会删除斜杠。该页面上没有明确记录,我从来没有抓住它。我仍然会自动运行它,因为我提出的大多数html我想要留下作为实体,即使我不这样做,我更愿意在我的db类之外根据具体情况做出决定。那样,我知道斜线消失了。

看起来原来的海报正在运行htmlentities(或者他的输入程序,就像tinymce正在为他做的那样),并且他想把它转回内容。因此,html_entity_decode($ Str)应该是所有必需的。