thewca / worldcubeassociation.org

All of the code that runs on worldcubeassociation.org
https://www.worldcubeassociation.org/
GNU General Public License v3.0
328 stars 176 forks source link

Visual bug in profile's sections #893

Open viroulep opened 8 years ago

viroulep commented 8 years ago

When an undefined section name is specified, the profile is all on one page, see the screenshot: undefined-tab

I think we want to display only "General" in this case, like when no section is provided.

jonatanklosko commented 8 years ago

Actually in your case it's not undefined but equal to "g". We only ensure that it's "general" by default if nothing else is specified (here). It could be easily fixed by:

unless %w(general email preferences password avatar).include? params[:section]
  params[:section] = "general"
end

But this requires us to remember that we need to add here every new section. Is it worth doing? Manually setting other section param seems unlikely, anyway it's probably right to avoid such side effects.

jfly commented 8 years ago

It is this line of javascript that hides everything except for the magical tab? It looks like we're allowing arbitrary user input to show up as javascript. This feels like an XSS vector...

jfly commented 8 years ago

I just played around with this a bit, and fortunately, the call to j seems to be protecting us from someone trying to craft a malicious section parameter, but I still don't feel comfortable with this.

I support sanitizing the value of params[:section]. Fortunately, we won't have to worry about forgetting to do this, as it will be impossible to add a new section without updating the sanitization code. We already do a similar thing in: https://github.com/cubing/worldcubeassociation.org/blob/d8d9e728e8a570b21ec1836a670e79d832634387/WcaOnRails/app/controllers/competitions_controller.rb#L60 with params[:display].

timhabermaas commented 8 years ago

Depending on how involved the sections are you could also avoid duplication by extracting the common pieces:

def form_sections = [
  Section.new(title: 'Foo', param: 'foo', partial: 'bar/_foo'),
  # ...
]

unless form_sections.map(&:param).include? params[:section]
  params[:section] = form_sections.first.param
end
Speaking of ad-hoc sanitation/params parsing I've had similar problems in the past where Rails' strong parameters didn't cut it (especially no type coercion until the ActiveRecord layer was annoying). So I built a small library which can take care of sanitation, type coercion and whitelisting attributes (replacing strong parameters): ``` ruby def params_parser Coercer.lift( Coercer.date.fmap(&:beginning_of_month).from_key(:from_date), Coercer.date.from_key(:to_date), Coercer.string.default('pending').one_of(%w(pending finished failed)).from_key(:status), &FilterOrderParams.method(:new)) end filter_options = params_parser.run!({from_date: "2014-10-20", to_date: "2015-02-03", status: "bar"}) filter_options.from_date # => Wed, 01 Oct 2014 filter_options.status # => "pending" ``` (For anyone familiar with Haskell: It's basically a parser combinator with arbitrary input instead of textual data.) If this sounds useful to anyone I'll extract it from the project it's currently living in and release it as a gem. Sidenote: There are other solutions to the same problem like `dry-types`, but I don't really like their APIs/lack of extensibility.
jfly commented 8 years ago

That's a neat idea for a library, @timhabermaas. We've definitely suffered from that "no type coercion until the ActiveRecord layer" problem. For example, we have a lot of calls to ActiveRecord::Type::Boolean.new.type_cast_from_database.

jonatanklosko commented 8 years ago

@jfly

I support sanitizing the value of params[:section]. Fortunately, we won't have to worry about forgetting to do this, as it will be impossible to add a new section without updating the sanitization code.

Actually it's not true, you'd be able to add a new tab and access it. The only thing that wouldn't work is the url, so if you'd refresh the page (with the new tab open) then you'd be 'redirected' to the general section. Don't have better solution though.