require 'lotus/utils/escape' module Lotus module Helpers # Escape helpers # # You can include this module inside your view and # the view will have access all methods. # # By including Lotus::Helpers::EscapeHelper it will inject private # methods as markup escape utilities. # # @since 0.1.0 module EscapeHelper private # 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 Lotus::Helpers::EscapeHelper#escape_html_attribute. # # @param input [String] the input # # @return [String] the escaped string # # @since 0.1.0 # # @see Lotus::Helpers::EscapeHelper#escape_html_attribute # # @example Basic usage # require 'lotus/helpers/escape_helper' # # class MyView # include Lotus::Helpers::EscapeHelper # # def good_content # h "hello" # end # # def evil_content # h "" # end # end # # view = MyView.new # # view.good_content # # => "hello" # # view.evil_content # # => "<script>alert('xss')</script>" # # @example With HTML builder # # # # CONTENTS ARE AUTOMATICALLY ESCAPED # # # require 'lotus/helpers' # # class MyView # include Lotus::Helpers # # def evil_content # html.div do # "" # end # end # end # # view = MyView.new # view.evil_content # # => "
\n<script>alert('xss')</script>
" def escape_html(input) Utils::Escape.html(input) end # @since 0.1.0 alias_method :h, :escape_html # 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 Lotus::Helpers::EscapeHelper#escape_html. # # @param input [String] the input # # @return [String] the escaped string # # @since 0.1.0 # # @see Lotus::Helpers::EscapeHelper#escape_html # # @example Basic usage # require 'lotus/helpers/escape_helper' # # class MyView # include Lotus::Helpers::EscapeHelper # # def good_attribute # attribute = "small" # # %(hello # end # # def evil_attribute # attribute = %(" onclick="javascript:alert('xss')" id=") # # %(hello # end # end # # view = MyView.new # # view.good_attribute # # => %(hello) # # view.evil_attribute # # => %(hello # # @example With HTML builder # # # # ATTRIBUTES AREN'T AUTOMATICALLY ESCAPED # # # require 'lotus/helpers' # # class MyView # include Lotus::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 # # => %(hello def escape_html_attribute(input) Utils::Escape.html_attribute(input) end # @since 0.1.0 alias_method :ha, :escape_html_attribute # 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] an optional array of whitelisted schemes # # @return [String] the escaped string # # @since 0.1.0 # # @see Lotus::Utils::Escape.url # @see Lotus::Utils::Escape::DEFAULT_URL_SCHEMES # # @example Basic usage # require 'lotus/helpers/escape_helper' # # class MyView # include Lotus::Helpers::EscapeHelper # # def good_url # url = "http://lotusrb.org" # # %(Lotus # end # # def evil_url # url = "javascript:alert('xss')" # # %(Evil # end # end # # view = MyView.new # # view.good_url # # => %(Lotus) # # view.evil_url # # => %(Evil) # # @example Custom schemes # require 'lotus/helpers/escape_helper' # # class MyView # include Lotus::Helpers::EscapeHelper # # def ftp_link # schemes = ['ftp', 'ftps'] # url = 'ftps://ftp.example.org' # # %(FTP # end # end # # view = MyView.new # # view.ftp_link # # => %(FTP) def escape_url(input, schemes = Utils::Escape::DEFAULT_URL_SCHEMES) Utils::Escape.url(input, schemes) end # @since 0.1.0 alias_method :hu, :escape_url # Bypass escape. # # Please notice that this can be really dangerous. # Use at your own peril. # # @param input [String] the input # # @return [Lotus::Utils::Escape::SafeString] the string marked as safe string # # @since 0.1.0 # # @example # require 'lotus/helpers/escape_helper' # # class MyView # include Lotus::Helpers::EscapeHelper # # def good_content # raw "

hello

" # end # # def evil_content # raw "" # end # end # # view = MyView.new # # view.good_content # # => "

hello

" # # # # # !!! WE HAVE OPENED OUR APPLICATION TO AN XSS ATTACK !!! # # # view.evil_content # # => "" def raw(input) Utils::Escape::SafeString.new(input) end end end end