What does rails_xss in Rails 2.3.5 mean for plugin/gem authors?

28 views
Skip to first unread message

Mislav Marohnić

unread,
Dec 2, 2009, 2:19:16 PM12/2/09
to Rails core
A will_paginate user opened a issue in my tracker saying that he wants to use will_paginate in a Rails 2.3.5 app using the rails_xss plugin.

Evidently, HTML output from will_paginate view helpers (`page_entries_info` specifically) isn't marked "safe", so rails_xss escapes the HTML which is clearly unwanted behavior.

I tried conditionally marking these view helpers safe with the `safe_helper` method rails_xss provides on Module, but this can't work because will_paginate gem is loaded before rails_xss plugin (gems are loaded before plugins) and `safe_helper` is not available at that time.

Also, because plugins are loaded in alphabetical order, most plugins will load before rails_xss. These plugins will also be unable to use `safe_helper` or `html_safe!` methods unless the user changes plugin order in his environment.rb.

What is the preferred way to approach this? Thanks


Jeremy Kemper

unread,
Dec 2, 2009, 2:37:05 PM12/2/09
to rubyonra...@googlegroups.com
The rails_xss plugin would need to be restructured a bit to make it
easier to explicitly require and initialize.

Otherwise users have to explicitly config.plugins = [:rails_xss,
:will_paginate, ...]

jeremy

Mislav Marohnić

unread,
Dec 2, 2009, 2:40:41 PM12/2/09
to rubyonra...@googlegroups.com
On Wed, Dec 2, 2009 at 20:37, Jeremy Kemper <jer...@bitsweat.net> wrote:

The rails_xss plugin would need to be restructured a bit to make it
easier to explicitly require and initialize.

Otherwise users have to explicitly config.plugins = [:rails_xss,
:will_paginate, ...]

Yes, this will work for plugins, but gems are still loaded before plugins.

Even if rails_xss initializer is restructured so that a simple `require 'rails_xss'` is enough, I can't do that from plugin code. How do I know if the user *wants* to load rails_xss?

Maybe loading of rails_xss, being an important 3.0 feature, could be special-cased in Rails 2.3.6 loading strategy?

Mislav Marohnić

unread,
Dec 2, 2009, 2:41:17 PM12/2/09
to rubyonra...@googlegroups.com
On Wed, Dec 2, 2009 at 20:40, Mislav Marohnić <mislav....@gmail.com> wrote:

Even if rails_xss initializer is restructured so that a simple `require 'rails_xss'` is enough, I can't do that from plugin code.

I wanted to say "I can't do that from *gem* code"

Yehuda Katz

unread,
Dec 2, 2009, 2:52:28 PM12/2/09
to rubyonra...@googlegroups.com
Ideally, you'd be able to do:

require "rails_xss"

... use html_safe here ...

Yehuda Katz
Developer | Engine Yard
(ph) 718.877.1325


--

You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.

Matt Jones

unread,
Dec 2, 2009, 2:50:15 PM12/2/09
to rubyonra...@googlegroups.com

On Dec 2, 2009, at 2:40 PM, Mislav Marohnić wrote:

> On Wed, Dec 2, 2009 at 20:37, Jeremy Kemper <jer...@bitsweat.net>
> wrote:
>
> The rails_xss plugin would need to be restructured a bit to make it
> easier to explicitly require and initialize.
>
> Otherwise users have to explicitly config.plugins = [:rails_xss,
> :will_paginate, ...]
>
> Yes, this will work for plugins, but gems are still loaded before
> plugins.
>

Note that plugins that are gems get two shots at loading; they first
get loaded via require (from config.gem or equivalent) and then rails/
init.rb is loaded, if present. So in your case, it might work to load
normally on require and then mark the helpers as safe in rails/
init.rb, if rails_xss is loaded.

--Matt Jones

Bruno Michel

unread,
Dec 2, 2009, 2:58:06 PM12/2/09
to rubyonra...@googlegroups.com
Hi,

Nathan Weizenbaum, the author of Haml, has found a solution to this
problem of the order of plugins/gems: he has used
Rails.configuration.after_initialize[1] to do stuff when the rails_xss
is here.

It's tricky and not very friendly to the authors of gems/plugins, but it
can be a temporary solution before Rails 2.3.6 or 3.0.

[1] http://github.com/nex3/haml/blob/master/lib/haml/template.rb#L59

++
Bruno

Mislav Marohnić

unread,
Dec 2, 2009, 3:19:09 PM12/2/09
to rubyonra...@googlegroups.com
On Wed, Dec 2, 2009 at 20:58, Bruno Michel <brmi...@free.fr> wrote:

Nathan Weizenbaum, the author of Haml, has found a solution to this
problem of the order of plugins/gems: he has used
Rails.configuration.after_initialize[1] to do stuff when the rails_xss
is here.

I like it. It solves the problem.

Yehuda, regarding you comment — how is requiring "rails_xss" my responsibility (as plugin/gem author)? 

Michael Koziarski

unread,
Dec 2, 2009, 3:31:20 PM12/2/09
to rubyonra...@googlegroups.com
> Also, because plugins are loaded in alphabetical order, most plugins will
> load before rails_xss. These plugins will also be unable to use
> `safe_helper` or `html_safe!` methods unless the user changes plugin order
> in his environment.rb.

html_safe! and friends are defined in ActiveSupport, they're always
there before your plugin is. safe_helper isn't and so you'll have the
loading problems you mentioned. If you use html_safe! you won't have
to worry about loading order.

> What is the preferred way to approach this? Thanks

If your helpers build their tags using tag and content_tag they'll be
marked safe automatically. That's the simplest way by far.

There's a more fundamental problem in trying to support all three
options with one codebase

* <=2.3.4
* >= 2.3.5
* >= 2.3.5 with plugin

Because you're supporting <= 2.3.4 you can't just blindly call
.html_safe!, and because you want to support the plugins you ... kinda
have to.

My advice would be to add a rails_xss_support file to will_paginate
which calls safe_helper on all your helpers and tell people using the
rails_xss plugin to require that in after_initialize. If you wanted
to automagically work you could conditionally require that file in an
after_initialize hook based on the existence and value of


ActionView::Base.xss_safe?

If that's true, we're auto escaping and it's


--
Cheers

Koz
Reply all
Reply to author
Forward
0 new messages