【问题标题】:Is handlebars' default escaping safe for use in HTML attributes在 HTML 属性中使用车把的默认转义是否安全
【发布时间】:2020-08-05 21:56:01
【问题描述】:

我正在为一个具有多种 HTML 转义方法的项目做一些合同工作。一些属性在后端转义并使用三重句柄{{{escaped-in-backend}}} 呈现为原始字符串,其他属性从后端原始传递并使用double handlebars{{unsafe}} 转义。

JS 后端编码是使用(旧版?)ESAPI 库完成的,并混合使用encodeForHtml()encodeForHtmlAttribute()。我找不到关于此的大量信息,但this post 建议属性编码也将空格转义为 ,以便被认为可以免受 XSS 攻击。这可能是促使之前开发者在后端进行转义的原因。

后端转义很讨厌,我想摆脱它并依赖把手。我已经很多年没有做过 F/E 工作了,所以我只是想仔细检查一下车把的转义策略是否对属性值是安全的,例如:<input type="text" value="{{unsafe-value}}"/>

我倾向于“是”,因为车把非常普遍,这将是一个非常明显的安全漏洞,但我找不到任何明确的文档说明。

【问题讨论】:

    标签: html attributes escaping handlebars.js esapi


    【解决方案1】:

    您遇到了程序员逆向工程问题。你正在推翻以前程序员做出的决定!

    您遇到的问题是 HTML 属性中的转义规则与中间标签的转义不同,因此我们将这些转义函数分开,因为它们不是 1:1。即。

    <textarea>{{HTMLEscapingIsDoneHere}}</textarea>
    
    <span background="[HTMLAttributeEscapingIsHere]"> ...
    

    HTML 转义比 HTML 属性编码涵盖更多的字符。危险在于您可能会比您想要的更多地转义,从而破坏了一些其他功能,例如 css 或 jquery 选择器,这些功能可能试图键入这些属性值并且现在会失败,因为您已经转义了太多并且这些函数需要纯文本而不是 HTML 属性。 Handlebars 本身可能具有一些功能,这些功能可以键入属性值,如果您对它们进行 HTML 转义,则会破坏它们。 [不知道,没用过..]

    如果您注意前面逃逸的内容和后面逃逸的内容,并且之前的开发人员一致认为唯一逃逸的是您的 HTML 属性......那么我敢打赌,他们尝试了 50 美元将所有内容转义为完整的 HTML,破坏了某些内容,然后提出了后端转义作为当时最简单的解决方案。如果它们不一致,那么所有的赌注都会被取消。

    在您的情况下,也许尝试将所有内容转义为 HTML 以查看是否破坏了任何内容,但特别是如果它有效,您将希望清楚地记录您的方法,您可能会在未来与其他动态框架不兼容。如果你说不出来,我以前也遇到过。接受或拒绝这种风险是企业的工作。

    我的第一个建议是,如果您在 JSP 中使用车把,那么只需导入 ESAPI 标记库并利用那里的编码功能。丑陋?当然。您正在使用多个 FE 框架。

    我的第二个建议是,因为您可能已经与车把结婚,所以在这里包装您要使用的 esapi 编码函数并将它们引入车把。例如,在 JSP 中,您拥有允许您使用 ESAPI 或编写自定义包装器的标记库。因为我知道 ESAPI 编码时从未考虑到把手,所以我会编写包装函数并使用把手显式转义 HTML,并使用插入的把手函数来转义 HTML 属性。如果车把无法让您插入自己的转义功能,那么后端转义恐怕是下一个最佳选择。以前的开发人员看到了分离这些转义函数的价值,但在 FE 代码中无法这样做。

    至于更广泛的问题,“将属性转义为 HTML 而不是 HTML 属性是否安全”,这是我已经克服了陷阱的那些“是的,但是……”的答案之一。使用单页 Web 应用程序框架时,大多数这些陷阱都会消失,但那是因为您已将 所有 客户端/服务器通信标准化为 Javascript。这也是题外话,但你应该在承包商的箭筒里放一个箭头。

    【讨论】:

      【解决方案2】:

      作为目前正在使用车把和 esapi4js 的程序员,我可以建议您在单独的 js 文件中使用车把助手进行转义,如下所示;

          (function() {
          Handlebars.registerHelper('encodeFor', function(forWhat, param) {
              switch(forWhat) {
                  case 'html':
                      return $ESAPI.encoder().encodeForHTML(param);
                  case 'htmlAttribute':
                      return $ESAPI.encoder().encodeForHTMLAttribute(param);
              }
          });
      
      })();
      

      encodeFor 是辅助函数的名称 forWhat 和 param 是那个的参数

      注册助手后,您可以在您的车把模板中使用它,例如 ;

      <input type="text" value="{{encodeFor 'htmlAttribute' unsafe-value}}"/>
      
      <td class="headerColumn">{{{encodeFor 'html' unsafe-value}}}</td>
      

      【讨论】:

      • 把手是如何执行这样的javscript代码的?它是依赖浏览器还是在将响应发送回浏览器之前全部在服务器端处理?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      • 2017-01-04
      • 1970-01-01
      • 2015-09-22
      • 2016-08-15
      • 1970-01-01
      相关资源
      最近更新 更多