【问题标题】:j render With Coffeescript in Rails and Understanding How to Sanitize Javascriptj 在 Rails 中使用 Coffeescript 渲染并了解如何清理 Javascript
【发布时间】:2023-03-15 13:25:01
【问题描述】:
  1. 我正在尝试使用 javascript 显示资源的属性。我确定我犯了一个简单的错误或遗漏。

  2. 我试图了解j render 的工作原理以及为什么它是必要的。我知道这与恶意用户输入 javascript 并将在应用程序中执行这可能导致坏事发生的情况有关。

设置:Rails 应用中的简单博客模板:rails g scaffold Blog title:string content:text

views/blogs/show.html.erb

<div id="blogContent"> Javascript should enter result of @blogger.content here: </div>

assets/javascripts/blogs.coffee

$document.on "page:change", ->
    $blogPost = "<%= j render(@blog.content) %>"
    alert($blogPost)
    $('#blogContent').append($blogPost)

以下是我遇到的问题:

  1. 警告框正在返回:&lt;%= j render(@blog.content %&gt;。我希望它返回该博客的内容。

  2. 1234563例如,如果在内容中,恶意用户输入了:&lt;a href='DangerousSite.xyz'&gt;Hacker says click for free stuff&lt;/a&gt;,那么我的应用程序渲染@blog.content 会产生一个链接,上面写着:Hacker says click for free stuff。一旦我向自己证明转义 javascript 是防止此类事情发生所必需的,我希望能够转义它并让结果字面上显示&lt;a href="Dangerous Site"&gt;Hacker says click for free stuff&lt;/a&gt;,或者呈现净化后的 javascript 看起来像的任何其他方式。

【问题讨论】:

    标签: jquery ruby-on-rails coffeescript


    【解决方案1】:

    要回答关于转义 Javascript 的第一部分,让我们看一下这段代码:

    $blogPost = "<%= j render(@blog.content) %>"
    

    现在想象一个用户决定用 DHH 的一句话开始他们的博客文章:

    “Workaholics don't actually accomplish more than nonworkaholics.” 
    

    现在,由于此上下文中的 Javascript 发生在客户端,因此代码中的 Ruby 将首先得到评估。因此,您的 Javascript 现在看起来像这样:

    $blogPost = "“Workaholics don't actually accomplish more than nonworkaholics.”"
    

    如您所见,其中有一组额外的引号从字符串中分离出来。实际的报价将被解释器读取为 Javascript,这将中断,因为那是无效的 Javascript。恶意用户可以通过重写他们的博客文章以包含 Javascript 而不是引用来利用这一点。为了解决这个问题,我们使用 j(escape_javascript 的缩写)转义引号,所以:

    “Workaholics don't actually accomplish more than nonworkaholics.”
    

    变成:

    \&quot;Workaholics don't actually accomplish more than nonworkaholics.\&quot;
    

    现在进入您的第二部分。您的代码实际上返回“j render(@blog.content)”的原因是因为您的代码的那部分是 Ruby 并且需要在您的 Javascript 发送到浏览器之前由 ERB 处理。要让 ERB 处理此文件,只需将 .erb 添加到您的文件名:

    assets/javascripts/blogs.coffee.erb
    

    但是,这是一种不好的做法,因为您的资产中的 Javascript 与您的应用程序处于不同的上下文中,所以我怀疑它不会找到 @blogs 变量。因此,您应该将 blogs.coffee.erb 文件移动到适当的视图文件夹,如下所示:

    app/views/blogs/index.coffee.erb
    

    (尽管一旦将它移到视图中,我相信 .erb 不再需要,正如 Rails 所暗示的那样)

    【讨论】:

      【解决方案2】:


      1. 您可能需要遵循以下提示:
      Rails: access controller instance variable in CoffeeScript or JavaScript asset file

      2.如果您要避免HTML,则应该转义HTML,从我读过的内容来看,j render只会转义Javascript,并阻止其运行,但不会阻止HTML,就像您给出的示例一样。

      要使用 JavaScript 转义 HTML,请使用如下方便的函数:

      var entityMap = {
      "&": "&amp;",
      "<": "&lt;",
      ">": "&gt;",
      '"': '&quot;',
      "'": '&#39;',
      "/": '&#x2F;'
      };
      
      function escapeHtml(string) {
          return String(string).replace(/[&<>"'\/]/g, function (s) {
            return entityMap[s];
          });
      }
      

      取自 Handlebars:https://github.com/wycats/handlebars.js/blob/0a9fc171b00a12fa990d2f7d27310182ed51a41c/lib/handlebars/utils.js

      【讨论】:

      • escape_javascript 不会转义 HTML,因为 Rails 默认会转义 HTML,并且仅在您使用 html_safe 方法覆盖该默认值时才显示 HTML
      猜你喜欢
      • 2015-12-16
      • 1970-01-01
      • 1970-01-01
      • 2014-06-25
      • 2011-03-05
      • 1970-01-01
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多