解码 mysql_real_escape_string() 以输出 HTML

发布于 2024-08-27 19:09:15 字数 447 浏览 21 评论 0原文

我试图保护自己免受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));

I'm trying to protect myself from sql injection and am using:

mysql_real_escape_string($string);

When posting HTML it looks something like this:

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

I'm not sure how many other variations real_escape_string adds so don't want to just replace a few and miss others... How do I "decode" this back into correctly formatted HTML, with something like:

html_entity_decode(stripslashes($string));

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

铃予 2024-09-03 19:09:15

mysql_real_escape_string() 不必解码,它仅用于 SQL,但转义字符永远不会存储在数据库中。当然,它不应该被用来净化 HTML。在输出网页数据之前没有理由使用它。此外,mysql_real_escape_string() 也不应用于要放入数据库的数据。您的清理过程应如下所示:

输入

  1. 接受来自表单或 HTTP 请求的用户输入
  2. 使用准备好的语句创建数据库查询

输出

  1. 从数据库中提取数据
  2. 运行任何用户 -在打印之前通过 htmlspecialchars() 定义数据

使用数据库驱动程序,例如 MySQLi 或 < a href="http://php.net/pdo" rel="nofollow noreferrer">PDO 将允许您使用准备好的语句,它会为您转义大多数输入。

mysql_real_escape_string() doesn't have to be decoded, it is only used for SQL, but escape characters are never stored in the database. And of course it shouldn't be used to sanitize HTML. There's no reason to use it before outputting web page data. Besides, mysql_real_escape_string() shouldn't be used on data that you're about to put into the database either. Your sanitization process should look something like this:

Input

  1. Accept user input from a form or HTTP request
  2. Create database query using prepared statements

Output

  1. Fetch data out of the database
  2. Run any user-defined data through htmlspecialchars() before printing

Using a database driver such as MySQLi or PDO will allow you to use prepared statements, which take care of escaping most inputs for you.

落墨 2024-09-03 19:09:15

你把一切都搞乱了。

mysql_real_escape_string 不需要任何解码!

如果您用斜杠取回数据,则意味着它已被转义两次。而不是删除额外的斜杠,你不应该首先添加它们。

更不用说任何转义都已过时,您应该

使用准备好的语句

而不是任何转义字符串。

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

You've got everything messed up.

mysql_real_escape_string doesn't need any decoding!

If you get your data back with slashes, it means that it has been escaped twice. And instead of stripping out the extra slashes you just shouldn't to add them in the first place.

Not to mention that whatever escaping is obsoleted and you ought to

use prepared statements

instead of whatever escape string.

So, never escape, never decode.
The problem solved.

我也只是我 2024-09-03 19:09:15

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

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

mysql_real_escape_string is used to prevent SQL injection when storing user provided data into the database, but a better method would be to use data binding using PDO (for example). I always recommend using that instead of messing with escaping.

That being said, regarding your question on how to display it afterwards - after the data is stored, when you retrieve it the data is complete and valid without any need to be "unescaped". Unless you added your own escaping sequences, so please don't do that.

茶花眉 2024-09-03 19:09:15

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

stripslashes();

例如。
$html=stripslashes($html);
或者
$html=stripslashes($row["fieldname"]);

use the following function to remove slashes while showing on HTML page:

stripslashes();

eg.
$html=stripslashes($html);
OR
$html=stripslashes($row["fieldname"]);

蘑菇王子 2024-09-03 19:09:15

不知道我所看到的格式是怎么回事,但你的 html 表单

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

应该很简单;

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

当您取回它时,在将其放入数据库之前,您可以使用 mysql_real_escape_string() 将其转义,以确保您不会遭受 sql 注入攻击。

因此,您正在转义准备好放置文本下一步的值。

当您将其从数据库中取出(或将其中的任何内容作为 html 显示给用户)时,您可以再次转义它,准备好使用 htmlentities() 等接下来要进入的位置(html),以保护您的用户免受 XSS 攻击。

这构成了咒语 FIEO(过滤输入,逃逸输出)的 EO 部分,您应该将其纹在眼睑内侧。

Not sure what is going on with the formatting as I can see it but your html form

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

should be simply;

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

When you get it back, before you put it into the database you escape it using mysql_real_escape_string() to make sure you do not suffer an sql injection attack.

Hence you are escaping the values ready for place the text is going next.

When you get it out of the database ( or display ANY of it to users as html) then you escape it again ready for that that place it is going next (html) with htmlentities() etc to protect your users from XSS attacks.

This forms the EO part of the mantra FIEO, Filter Input, Escape Output, which you should tatoo on the inside of your eyelids.

雨后咖啡店 2024-09-03 19:09:15

我想知道为什么这个例程没有附带的解码器例程。 MySQL 可能以与未转义完全相同的方式对其进行解释。当您执行 $row=mysql_fetch_array($res, MYSQL_ASSOC)'; 时,您会得到未转义的结果

I was wondering why this routine doesn't have a accompanying decoder routine. Its probably interpreted by MySQL the exact same way as if it were not escaped. You get the un-escaped results when you do a $row=mysql_fetch_array($res, MYSQL_ASSOC)';

赠我空喜 2024-09-03 19:09:15

好吧,我尝试了一种老式的方式,到目前为止我看不出我的方法有什么问题。显然这有点粗糙,但它完成了工作:

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;
}

这应该涵盖大多数情况。

Well, I took a stab at this the old fashion way and so far I am unable to see anything wrong with my approach. Obviously it's a bit crude but it gets the job done:

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;
}

This should cover most cases.

微暖i 2024-09-03 19:09:15

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

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

Even if it's an old question...
I've had the same problem than Peter Craig.
In fact I've to deal with an old CMS. In order to prevent SQL Injection, all $_POST and $_GET values are "sql-escaped". Unfortunatly this is done in a central point so all your modules are receiving all data sql-escaped! In some cases you want to directly display these data so you face a problem: how to display a sql-escaped string without gettng it from DB?
The answer is:
use stripcslashes (NOT stripslashes!!)

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

喜你已久 2024-09-03 19:09:15

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

您在输入的内容上使用 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) 应该是所需要的。

I think a number of other answers missed the obvious issue...

You are using mysql_real_escape_string on the inputted content (as you should if not using prepared statements).

Your issue is with the output.

The current issue is that you are calling html_entity_decode. Just stripslashes is all you need to restore the original text. html_entity_decode is what is messing up your quotes, etc, as it is changing them. You actually want to output the html, not just plain text (which is when you would use html_entities, etc). You are decoding something you want encoded.

If you only want the text version to show up, you can use the entities. If you are worried about bad tags, use striptags and allow only the tags you want (such as b, i, etc).

Finally, remember to encode and decode in the proper order. if you ran mysql_real_escape_String(htmlentities($str)), then you need to run html_entity_decode(stripslashes($str)). The order of operations matters.

UPDATE: I did not realize that html_entity_decode also strips out slashes. It was not clearly documented on that page, and I just never caught it. I will still automatically run it though, as most html that I present I want left as entities, and even when I don't, I prefer to make that decision outside of my db class, on a case by case basis. That way, I know the slashes are gone.

It appears the original poster is running htmlentities (or his input program, like tinymce is doing it for him), and he wants to turn it back to content. So, html_entity_decode($Str) should be all that is required.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文