Php 挑战-安全而准确地逃离此文本
这是我最后一个问题的后续问题,贴在那里的答案实际上不起作用。这就是挑战。您将获得以下代码(假设包含jQuery): 失败:完全按照文本字段中的方式复制字符编码。Php 挑战-安全而准确地逃离此文本,php,jquery,escaping,Php,Jquery,Escaping,这是我最后一个问题的后续问题,贴在那里的答案实际上不起作用。这就是挑战。您将获得以下代码(假设包含jQuery): 失败:完全按照文本字段中的方式复制字符编码。 输入:$text=“Déjávu” 输出:字段包含文字dé;jà;vu (二) 这是我对古怪角色最有希望的解决方案,除了… 失败:未对某些字符进行编码(不确定到底是哪个字符,不在乎) 输入:$text=“Déjá” 输出:字段包含/script Déjá 4) 答案中的建议 $("input").val(unes
输入:
$text=“Déjávu”
输出:字段包含文字
dé;jà;vu
(二)
这是我对古怪角色最有希望的解决方案,除了…失败:未对某些字符进行编码(不确定到底是哪个字符,不在乎)
输入:
$text=“Déjá”
输出:字段包含
/script Déjá
4) 答案中的建议
$("input").val(unescape("<?= urlencode($text); ?>"));
$(“输入”).val(unescape(“”);
失败:空格仍然编码为+
$("input").val(unescape(<?= rawurlencode($text); ?>"));
$(“输入”).val(unescape(“);
几乎可以。以前所有的输入都成功,但多字节的东西,如汉字,仍然是编码的。decodeURIComponent
也不喜欢多字节字符
请注意,对我来说,像strip_tags
这样的东西不是一个选项。一切都必须允许。人们用它来编写测验,如果有人想做一个测验来测试你对HTML的知识,那就这样吧。此外,不幸的是,我不能只将htmlentities
转义文本注入输入标记的值字段。这些标记是动态生成的,我必须完全拆除我当前的javascript代码结构才能这样做
我觉得我是索尔,请告诉我我错了多少
编辑
假设用户最初输入了Déjáhär föfrågor漢字将代码>存储到数据库中。这将作为Déjáhär föfrågor漢;字;
存储(您可以在phpMyAdmin中看到它)。您可以使用:
- (可能是最简单的选择)
- 使用
ENT\u引号
或者将htmlspecialchars
与ENT\u NOQUOTES
组合使用,并且如果您不希望引号变成HTML实体
您需要用PHP编码,用JavaScript解码
PHP的:
echo rawurlencode("</script> Déjà");
//result: %3C%2Fscript%3E+D%C3%A9j%C3%A0
var encoded = "%3C%2Fscript%3E+D%C3%A9j%C3%A0";
alert(decodeURIComponent(encoded));
//result: </script> Déjà
echo rawurlencode(“Déjá”);
//结果:%3C%2Fscript%3E+D%C3%A9j%C3%A0
JavaScript的:
echo rawurlencode("</script> Déjà");
//result: %3C%2Fscript%3E+D%C3%A9j%C3%A0
var encoded = "%3C%2Fscript%3E+D%C3%A9j%C3%A0";
alert(decodeURIComponent(encoded));
//result: </script> Déjà
var encoded=“%3C%2Fscript%3E+D%C3%A9j%C3%A0”;
警报(解码组件(编码));
//结果:Déjá
如果不是UTF-8,您的文本是什么编码?如果您不知道,您没有文本,您有一个字节序列,这很难忠实地表示。如果您知道,您可以使用扩展名执行以下操作:
$("input").val(<?= json_encode(mb_convert_encoding($text, "UTF-8", "ISO-8859-1")); ?>);
$(“输入”).val();
在这里,我假设您的输入是ISO-8859-1又名Latin-1编码,这是数据库字符串的常见情况
编辑:这是对关于关闭脚本标记的评论的回应。我制作了这个测试文件,它可以正确显示,至少在Firefox 3.6中是这样的:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Test</title>
<script src='http://code.jquery.com/jquery-1.4.2.js'></script>
</head>
<form name='foo'>
<input name='bar' id='bar'/>
</form>
<script language="JavaScript">
$('input').val("<\/script>");
</script>
</html>
试验
$('input').val(“”);
我找到了一个“足够好”的解决方案,大家可能会感兴趣
utf8\u对进入数据库的字符串进行编码。
二,
这并不是绝对完美的,因为php似乎没有任何方法可以知道用户键入之间的差异漢 或者直接键入漢;
。因此,如果键入后者,它将成为前者。但我怀疑是否有人会希望这样做。ascii字符串的安全javascript转义
<?php
function js_encode($string)
{
$cleaned = is_null($string) ? null : '';
// for each letter of the string
for ($i=0, $len = strlen($string); $i < $len; $i++)
{
// get ascii number
$ord = ord($string[$i]);
// if [0-9] or [A-Z] or [a-z]
$cleaned .= (47 < $ord && $ord < 58 OR 64 < $ord && $ord < 91 OR 96 < $ord && $ord < 123)
// use existing character
? $string[$i]
// otherwise escape it
: '\x'.dechex($ord);
}
return $cleaned;
}
我不明白解决方案#3有什么问题?为什么你关心某些字符没有编码,只要浏览器正确处理它们?如果前面的问题没有解决,你就不应该再发布另一个问题……因为用户会在字段中键入
,提交它,它会在t处吐出/script
哼哼。他们会感到困惑,如果他们在没有注意到的情况下再次提交表单,这将破坏他们的输入。为什么不使用一个丰富的编辑控件而不是纯文本?请给出一个值为$text
的示例,其中$(“输入”).val(unescape(“)
失败。您可以使用rawurlencode而不是urlencode,这样您就不必手动替换加号了。很好,我测试了它,它似乎可以工作。简化我的答案!对不起,失败了!对于某些输入(包括多字节字符),javascript抱怨uri组件格式不正确。@Tess在编码之前将文本转换为UTF-8如何?你说的“准确”。这提供了ByTestStream的精确表示。如果您想对这个问题有更多/更好的答案,您必须提供单元测试。这是正确的答案,您需要先将其标准化为UTF8,它会很好地工作。我一直在尝试,但关闭脚本标记仍然失败。它们变成了
,但这仍然打破了js。此外,多字节字符仍然无法转换回来。你能解释一下“规范化为UTF-8”吗?如果我把这个答案和我的#3结合起来,它不会中断,但是脚本标记根本不会出现。如果你直接把它放在代码中,它会工作吗?这在Firefox的jQuery1.4.2测试HTML文件中适用:$('input').val(“”)代码>--该代码是否没有填充框?如果按原样使用,则多字节字符显示不正确。使用我在编辑结束时提供的完整输入字符串进行尝试。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Test</title>
<script src='http://code.jquery.com/jquery-1.4.2.js'></script>
</head>
<form name='foo'>
<input name='bar' id='bar'/>
</form>
<script language="JavaScript">
$('input').val("<\/script>");
</script>
</html>
function repl($match)
{
return "\u" . dechex($match[1]);
}
function esc($string)
{
$s = json_encode($string);
$s = preg_replace_callback("/&#([0-9]+);/", "repl", $s);
return $s;
}
<?php
function js_encode($string)
{
$cleaned = is_null($string) ? null : '';
// for each letter of the string
for ($i=0, $len = strlen($string); $i < $len; $i++)
{
// get ascii number
$ord = ord($string[$i]);
// if [0-9] or [A-Z] or [a-z]
$cleaned .= (47 < $ord && $ord < 58 OR 64 < $ord && $ord < 91 OR 96 < $ord && $ord < 123)
// use existing character
? $string[$i]
// otherwise escape it
: '\x'.dechex($ord);
}
return $cleaned;
}