module Hanami::Helpers::EscapeHelper

Escape helpers

You can include this module inside your view and the view will have access all methods.

By including Hanami::Helpers::EscapeHelper it will inject private methods as markup escape utilities.

@since 0.1.0

Private Instance Methods

escape_html(input) click to toggle source

Escape the given HTML tag content.

This should be used only for untrusted contents: user input.

This should be used only for tag contents. To escape tag attributes please use Hanami::Helpers::EscapeHelper#escape_html_attribute.

@param input [String] the input

@return [String] the escaped string

@since 0.1.0

@see Hanami::Helpers::EscapeHelper#escape_html_attribute

@example Basic usage

require 'hanami/helpers/escape_helper'

class MyView
  include Hanami::Helpers::EscapeHelper

  def good_content
    h "hello"
  end

  def evil_content
    h "<script>alert('xss')</script>"
  end
end

view = MyView.new

view.good_content
  # => "hello"

view.evil_content
  # => "&lt;script&gt;alert(&apos;xss&apos;)&lt;&#x2F;script&gt;"

@example With HTML builder

#
# CONTENTS ARE AUTOMATICALLY ESCAPED
#
require 'hanami/helpers'

class MyView
  include Hanami::Helpers

  def evil_content
    html.div do
      "<script>alert('xss')</script>"
    end
  end
end

view = MyView.new
view.evil_content
  # => "<div>\n&lt;script&gt;alert(&apos;xss&apos;)&lt;&#x2F;script&gt;</div>"
# File lib/hanami/helpers/escape_helper.rb, line 74
def escape_html(input)
  Utils::Escape.html(input)
end
Also aliased as: h
escape_html_attribute(input) click to toggle source

Escape the given HTML tag attribute.

This MUST be used for escaping HTML tag attributes.

This should be used only for untrusted contents: user input.

This can also be used to escape tag contents, but it's slower. For this purpose use Hanami::Helpers::EscapeHelper#escape_html.

@param input [String] the input

@return [String] the escaped string

@since 0.1.0

@see Hanami::Helpers::EscapeHelper#escape_html

@example Basic usage

require 'hanami/helpers/escape_helper'

class MyView
  include Hanami::Helpers::EscapeHelper

  def good_attribute
    attribute = "small"

    %(<span class="#{ ha(attribute) }">hello</span>
  end

  def evil_attribute
    attribute = %(" onclick="javascript:alert('xss')" id=")

    %(<span class="#{ ha(attribute) }">hello</span>
  end
end

view = MyView.new

view.good_attribute
  # => %(<span class="small">hello</span>)

view.evil_attribute
  # => %(<span class="&quot;&#x20;onclick&#x3d;&quot;javascript&#x3a;alert&#x28;&#x27;xss&#x27;&#x29;&quot;&#x20;id&#x3d;&quot;">hello</span>

@example With HTML builder

#
# ATTRIBUTES AREN'T AUTOMATICALLY ESCAPED
#
require 'hanami/helpers'

class MyView
  include Hanami::Helpers

  def evil_attribute
    user_input_attribute = %(" onclick="javascript:alert('xss')" id=")

    html.span id: 'greet', class: ha(user_input_attribute) do
      "hello"
    end
  end
end

view = MyView.new
view.evil_attribute
  # => %(<span class="&quot;&#x20;onclick&#x3d;&quot;javascript&#x3a;alert&#x28;&#x27;xss&#x27;&#x29;&quot;&#x20;id&#x3d;&quot;">hello</span>
# File lib/hanami/helpers/escape_helper.rb, line 146
def escape_html_attribute(input)
  Utils::Escape.html_attribute(input)
end
Also aliased as: ha
escape_url(input, schemes = Utils::Escape::DEFAULT_URL_SCHEMES) click to toggle source

Escape an URL to be used in HTML attributes

This allows only URLs with whitelisted schemes to pass the filter. Everything else is stripped.

Default schemes are:

* http
* https
* mailto

If you want to allow a different set of schemes, you should pass it as second argument.

This should be used only for untrusted contents: user input.

@param input [String] the input @param schemes [Array<String>] an optional array of whitelisted schemes

@return [String] the escaped string

@since 0.1.0

@see Hanami::Utils::Escape.url @see Hanami::Utils::Escape::DEFAULT_URL_SCHEMES

@example Basic usage

require 'hanami/helpers/escape_helper'

class MyView
  include Hanami::Helpers::EscapeHelper

  def good_url
    url = "http://hanamirb.org"

    %(<a href="#{ hu(url) }">Hanami</a>
  end

  def evil_url
    url = "javascript:alert('xss')"

    %(<a href="#{ hu(url) }">Evil</a>
  end
end

view = MyView.new

view.good_url
  # => %(<a href="http://hanamirb.org">Hanami</a>)

view.evil_url
  # => %(<a href="">Evil</a>)

@example Custom schemes

require 'hanami/helpers/escape_helper'

class MyView
  include Hanami::Helpers::EscapeHelper

  def ftp_link
    schemes = ['ftp', 'ftps']
    url     = 'ftps://ftp.example.org'

    %(<a href="#{ hu(url, schemes) }">FTP</a>
  end
end

view = MyView.new

view.ftp_link
  # => %(<a href="ftps://ftp.example.org">FTP</a>)
# File lib/hanami/helpers/escape_helper.rb, line 224
def escape_url(input, schemes = Utils::Escape::DEFAULT_URL_SCHEMES)
  Utils::Escape.url(input, schemes)
end
Also aliased as: hu
h(input)

@since 0.1.0

Alias for: escape_html
ha(input)

@since 0.1.0

hu(input, schemes = Utils::Escape::DEFAULT_URL_SCHEMES)

@since 0.1.0

Alias for: escape_url
raw(input) click to toggle source

Bypass escape.

Please notice that this can be really dangerous. Use at your own peril.

@param input [String] the input

@return [Hanami::Utils::Escape::SafeString] the string marked as safe string

@since 0.1.0

@example

require 'hanami/helpers/escape_helper'

class MyView
  include Hanami::Helpers::EscapeHelper

  def good_content
    raw "<p>hello</p>"
  end

  def evil_content
    raw "<script>alert('xss')</script>"
  end
end

view = MyView.new

view.good_content
  # => "<p>hello</p>"

#
# !!! WE HAVE OPENED OUR APPLICATION TO AN XSS ATTACK !!!
#
view.evil_content
  # => "<script>alert('xss')</script>"
# File lib/hanami/helpers/escape_helper.rb, line 267
def raw(input)
  Utils::Escape::SafeString.new(input)
end