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

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

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

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?

I wanted to say “I can’t do that from gem code”

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

Ideally, you’d be able to do:

require “rails_xss”

… use html_safe here …

Yehuda Katz Developer | Engine Yard (ph) 718.877.1325

Mislav Marohnić 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?

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

I like it. It solves the problem.

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

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