0

在我们的 Rails 3.2.13 应用程序中,我们的 ERB 视图之一中有此代码:

<script language="javascript">
function copy_address ()
{
    document.getElementById("account_firm_name").value = '<%= escape_javascript firm_name %>';
    document.getElementById("account_address_line_1").value = '<%= escape_javascript address %>';
    document.getElementById("account_city").value = '<%= escape_javascript city %>';
    document.getElementById("account_state_id").value = '<%= escape_javascript state_id.to_s %>';
    document.getElementById("account_zip_code").value = '<%= escape_javascript zip %>';
}
</script>

<%# snip %>

<%= form_tag %>
  <table>
    <tr class="two_columns">
      <td><label for="firm_name">Firm Name*</label></td>
      <td><%= text_field 'account', 'firm_name' %></td>
    </tr>
    <%# snip %>
  </table>
</form>

它是一个 Rails 表单和一个将一些已知值复制到表单中的 JS 函数。

如果 ERB 注入的 、 、 或字符串中有任何特殊字符,firm_nameaddress它们cityzip被不适当的 HTML 转义。例如,如果firm_name = '&',则生成的 HTML 包含 JS 函数:

<script language="javascript">
function copy_address ()
{
    document.getElementById("account_firm_name").value = '&amp;';
    // snip

并执行该函数将字符串&amp;(不是&)插入到表单中的相应文本字段中。

有没有一种安全的方法来防止 ERB 转义字符串的值,或者在将字符串放入文本字​​段之前使用 JavaScript 取消转义字符串?

(到目前为止,我已经尝试使用.html_safeand rawRails 方法,但没有骰子。)

4

2 回答 2

0

我在尝试动态设置页面的标题元素时遇到了同样的问题。我最终决定了要检查哪些字符,然后gsub像这样在视图助手中做一个:

在 application_helper.rb

def title_sanitize(string)
    sanitize(string).gsub('&amp;', '&').html_safe
end

那么在你看来

document.getElementById("account_firm_name").value = '<%= title_sanitize(firm_name) %>';
于 2013-10-05T01:08:37.203 回答
0

我意识到在视图的其他地方,我们有这样的代码:

<% firm_name = h(@agency.name) %>
<% address = h(@agency.address) %>
<% city = h(@agency.city) %>
<% state_id = @agency.state_id %>
<% zip = h(@agency.zip_code) %>

如果您遇到与我相同的问题,请确保您没有任何代码预先转义您要使用的字符串。

我最终使用了这段代码:

function copy_address ()
{
    document.getElementById("account_firm_name").value = '<%= raw (escape_javascript @agency.name) %>';
    document.getElementById("account_address_line_1").value = '<%= raw (escape_javascript @agency.address) %>';
    document.getElementById("account_city").value = '<%= raw (escape_javascript @agency.city) %>';
    document.getElementById("account_state_id").value = '<%= raw (escape_javascript (@agency.state_id.to_s)) %>';
    document.getElementById("account_zip_code").value = '<%= raw (escape_javascript @agency.zip_code) %>';
}

直接使用@agency属性,在它们被运行之前h()

于 2013-10-10T18:25:17.343 回答