Railsのsanitizeヘルパーで違反タグを削除するのではなくエスケープする

/ 28日目/ 6週目・作業週 コメント

Railsのsanitizeヘルパーでは、ホワイトリストに登録されているタグ以外は削除される。この仕様だと、sanitize "(>_<)なんと!(>_<)"(>__<)となってしまい、好ましくない。

confing/initializers/escape_to_sanitize.rbなどに以下のように書いて、違反タグを削除ではなくエスケープする仕様としてみた。

require 'cgi'

# Escape bad tags when sanitized, instead of remove.
HTML::Sanitizer.class_eval do
  protected
  def tokenize(text, options)
    tokenizer = HTML::Tokenizer.new(text)
    result = []
    while token = tokenizer.next
      node = HTML::Node.parse(nil, 0, 0, token, false)
      process_node node, result, options
      # replace bad tags with escaped HTML
      if result.last.nil?
        result[result.length - 1] = CGI::escapeHTML(token)
      end
    end
    result
  end
end

テストしてないので、意図しないバグがあるかもしれない。

他に rgrove/sanitize などを使っても良いと思う。これは、rails標準のsanitizerより柔軟な設定ができるというもので、上記のような要件なら、Transfomersをゴニョゴニョすれば実現できそう。

参考)

コメント