草庐IT

php - 为 html 和输入字段安全地转义输出

coder 2023-08-11 原文

在我的网络应用程序中,用户可以输入文本数据。这些数据可以展示给其他用户,原作者也可以回去编辑他们的数据。我正在寻找安全转义此数据的正确方法。

我只是在进入过程中对 sql 进行清理,因此所有内容都按读取方式存储。假设我在数据库中有“déjà vu”。或者,更极端一点,一个 <script>标签。这可能是有效的输入,甚至不是恶意输入。

我正在使用 htmlentities()在出去的路上确保一切都逃脱了。问题是 html 和输入字段对待事物的方式不同。我想确保它在 HTML 中是安全的,但作者在编辑文本时能够准确地看到他们在输入字段中键入的内容。我还使用 jQuery 动态地用数据填充表单字段。

如果我这样做:

 <p><?=htmlentities("déjà vu");?></p>
 <input type=text value="<?=htmlentities("déjà vu");?>">

页面源放d&eacute;j&agrave; vu在这两个地方(我不得不反引号,否则你会看到“déjà vu”!)问题是 <p> 中的输出是正确的,但输入只显示转义文本。如果用户重新提交他们的表单,他们会双重转义并破坏他们的输入。

我知道我仍然必须清理进入该字段的文本,否则您可能会结束值(value)引用并做坏事。我找到的唯一解决方案是这个。同样,我正在使用 jQuery。

var temp = $("<div></div>").html("<?=htmlentities("déjà vu");?>");
$("input").val(temp.html());

这是可行的,因为它会导致 div 将转义文本读取为编码字符,然后 jquery 将这些编码字符复制到输入标签,并妥善保存。

所以我的问题是:这仍然安全吗,还是某处存在安全漏洞?更重要的是,这是唯一/正确的方法吗?我是否遗漏了有关 html 和字符编码如何工作的一些信息,从而使这个问题成为一个需要解决的小问题?

编辑

这实际上是错误的,我过度简化了我的示例,以至于它无法正常工作。问题实际上是因为我正在使用 jQuery 的 val() 将文本插入到字段中。

<input>
<script>$("input").val("<?=htmlentities("déjà vu");?>");</script>

原因是表单是动态的——用户可以随意添加或删除字段,因此它们是在页面加载后生成的。

所以看起来 jQuery 正在转义数据以进入输入,但这还不够好 - 如果我自己什么都不做,用户仍然可以输入 </script>标记,杀死我的代码并插入恶意代码。但这里还有另一个论点。既然只有原作者才能看到输入框里的文字,那我还要费心吗?基本上,他们唯一可以对他们执行 XSS 攻击的人就是他们自己。

最佳答案

很抱歉,我无法重现您描述的行为。我一直使用 htmlspecialchars() (它与 htmlentities() 的任务基本相同)并且它永远不会导致任何类型的双重编码。页面源显示d&eacute;j&agrave; vu在这两个地方(当然!这就是重点!)但呈现的页面显示了适当的值,这就是发送回服务器的内容。

您能否发布展示此类行为的完整独立代码片段?

更新:一些测试代码:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>

<?php

$default_value = 'déjà vu <script> ¿foo?';

if( !isset($_GET['foo']) ){
    $_GET['foo'] = $default_value;
}

?>

<form action="" method="get">
    <p><?php echo htmlentities($_GET['foo']); ?></p>
    <input type="text" name="foo" value="<?php echo htmlentities($_GET['foo']); ?>">
    <input type="submit" value="Submit">
</form>

</body>
</html>

更新问题的答案

htmlentities()函数,顾名思义,用于生成 HTML 输出。这就是为什么它在第二个示例中用处不大:JavaScript 不是 HTML。它是一种自己的语言,有自己的语法。

现在,您要解决的问题是如何生成符合以下两个规则的输出:

  1. 它是 JavaScript 中的有效字符串。
  2. 它可以安全地嵌入到 HTML 文档中。

据我所知,最接近#1 的 PHP 函数是 json_encode() .由于 JSON 语法是 JavaScript 的子集,如果您向它提供 PHP 字符串,它将输出 JavaScript 字符串。

关于 #2,一旦浏览器进入一个 JavaScript block ,它就期望一个 </script>。标记离开它。 json_encode() 函数负责处理并正确转义它 ( <\/script> )。

我修改后的测试代码:

<?php

$default_value = 'déjà vu </script> ¿foo?';

if( !isset($_GET['foo']) ){
    $_GET['foo'] = $default_value;
}

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript"><!--
$(function(){
    $("input[type=text]").val(<?php echo json_encode(utf8_encode($_GET['foo'])); ?>);
});
//--></script>
</head>
<body>


<form action="" method="get">
    <p><?php echo htmlentities($_GET['foo']); ?></p>
    <input type="text" name="foo" value="(to be replaced)">
    <input type="submit" value="Submit">
</form>

</body>
</html>

备注:utf8_encode()从 ISO-8859-1 转换为 UTF-8,如果您的数据已经是 UTF-8(推荐),则不需要。

关于php - 为 html 和输入字段安全地转义输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3148820/

有关php - 为 html 和输入字段安全地转义输出的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  3. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  4. ruby - 匹配未转义的平衡定界符对 - 2

    如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。

  5. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  6. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  7. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  8. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  9. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  10. ruby - 如何进行排列以有效地定制输出 - 2

    这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][

随机推荐