Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

View and presenters auto escape #60

Merged
merged 6 commits into from
Feb 22, 2015
Merged

View and presenters auto escape #60

merged 6 commits into from
Feb 22, 2015

Conversation

jodosha
Copy link
Member

@jodosha jodosha commented Feb 11, 2015

Starting from now, the output of views and presenters is always autoescaped.

Because Lotus::View supports a lot of template engines, the escape happens at the level of the view and it doesn't delegate to ERB or HAML.

Most of the time everything happens automatically, but there are still some corner cases that need developer's manual intervention.

View autoescape

require 'lotus/view'

User = Struct.new(:name)

module Users
  class Show
    include Lotus::View

    def user_name
      user.name
    end
  end
end

# ERB template
# <div id="user_name"><%= user_name %></div>

user = User.new("<script>alert('xss')</script>")

# THIS IS USEFUL FOR UNIT TESTING:
template = Lotus::View::Template.new('users/show.html.erb')
view     = Users::Show.new(template, user: user)
view.user_name # => "&lt;script&gt;alert(&apos;xss&apos;)&lt;&#x2F;script&gt;"

# THIS IS THE RENDERING OUTPUT:
Users::Show.render(format: :html, user: user)
# => <div id="user_name">&lt;script&gt;alert(&apos;xss&apos;)&lt;&#x2F;script&gt;</div>

Presenter autoescape

require 'lotus/view'

User = Struct.new(:name)

class UserPresenter
  include Lotus::Presenter
end

user      = User.new("<script>alert('xss')</script>")
presenter = UserPresenter.new(user)

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

Escape entire objects

We have seen that concrete methods are in views are automatically escaped.
This is great, but tedious if you need to print a lot of informations from a given object.

Imagine to have user as part of the view locals.
If you want to use <%= user.name %> directly, you're still vulnerable to XSS attacks.

You have two alternatives to fix the problem:

  • To use a concrete presenter (eg. UserPresenter, example above)
  • Escape the entire object (example below)

Both those solutions allow you to keep the template syntax unchanged (<%= user.name %>), but to get a safe output.

require 'lotus/view'

User = Struct.new(:first_name, :last_name)

module Users
  class Show
    include Lotus::View

    def user
      _escape locals[:user]
    end
  end
end

# ERB template:
#
# <div id="first_name">
#   <%= user.first_name %>
# </div>
# <div id="last_name">
#   <%= user.last_name %>
# </div>

first_name = "<script>alert('first_name')</script>"
last_name  = "<script>alert('last_name')</script>"

user = User.new(first_name, last_name)
html = Users::Show.render(format: :html, user: user)

html
  # =>
  # <div id="first_name">
  #   &lt;script&gt;alert(&apos;first_name&apos;)&lt;&#x2F;script&gt;
  # </div>
  # <div id="last_name">
  #   &lt;script&gt;alert(&apos;last_name&apos;)&lt;&#x2F;script&gt;
  # </div>

Raw contents

You can use _raw to mark an output as safe.
Please note that this may open your application to XSS attacks.

Raw contents in views

require 'lotus/view'

User = Struct.new(:name)

module Users
  class Show
    include Lotus::View

    def user_name
      _raw user.name
    end
  end
end

# ERB template
# <div id="user_name"><%= user_name %></div>

user = User.new("<script>alert('xss')</script>")
html = Users::Show.render(format: :html, user: user)

html
# => <div id="user_name"><script>alert('xss')</script></div>

Raw contents in presenters

require 'lotus/view'

User = Struct.new(:name)

class UserPresenter
  include Lotus::Presenter

  def first_name
    _raw @object.first_name
  end
end

user      = User.new("<script>alert('xss')</script>")
presenter = UserPresenter.new(user)

presenter.name # => "<script>alert('xss')</script>"

@jodosha jodosha self-assigned this Feb 11, 2015
@jodosha jodosha added this to the v0.4.0 milestone Feb 11, 2015
@coveralls
Copy link

Coverage Status

Coverage increased (+0.19%) to 97.48% when pulling f9ad885 on auto-escape into d8d35c0 on master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage increased (+0.19%) to 97.48% when pulling f9ad885 on auto-escape into d8d35c0 on master.


**ATTENTION:** In order to prevent XSS attacks, please read the instructions below.
Because Lotus::View supports a lot of template engines, the escape happens at the level of the view.
Most of the times everything happens automatically, but there are still some corner cases that need your manual intervention.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small typo - 'time' instead of 'times'

@tomkadwill
Copy link

👍

1 similar comment
@AlfonsoUceda
Copy link

👍

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.19%) to 97.1% when pulling a5560f4 on auto-escape into d8d35c0 on master.

3 similar comments
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.19%) to 97.1% when pulling a5560f4 on auto-escape into d8d35c0 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.19%) to 97.1% when pulling a5560f4 on auto-escape into d8d35c0 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.19%) to 97.1% when pulling a5560f4 on auto-escape into d8d35c0 on master.

@robyurkowski
Copy link

Love it.

@runlevel5
Copy link
Member

+1

jodosha added a commit that referenced this pull request Feb 22, 2015
View and presenters auto escape
@jodosha jodosha merged commit 03c49a2 into master Feb 22, 2015
@jodosha jodosha deleted the auto-escape branch February 22, 2015 10:24
timriley added a commit that referenced this pull request Mar 15, 2020
…utes

Decorate truthy part attributes only
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants