apneadiving / Google-Maps-for-Rails

Enables easy Google map + overlays creation in Ruby apps
https://apneadiving.github.io/
MIT License
2.27k stars 382 forks source link

Rails 4 escape_html_entities_in_json #468

Open jerefrer opened 9 years ago

jerefrer commented 9 years ago

I've been unable to add an html infowindow to my markers because Rails wouldn't stop escaping html characters (< to \u003 for instance).

It seems Rails 4 added this to prevent XSS attacks.

The only way I found to bypass this is to disable the escaping with ActiveSupport.escape_html_entities_in_json = false. See http://stackoverflow.com/questions/17936318/why-does-is-rails-4-unicode-escaping-in-to-json

What do you think ?

Here's what I'm doing in the controller:

def index
  @map_markers = build_markers(User.geocoded)
end

private

def build_markers(users)
  markers = nil
  without_html_escaping_in_json do
    markers = Gmaps4rails.build_markers(users) do |user, marker|
      marker.infowindow render_to_string(partial: 'users/column', locals: {user: user})
      marker.lat user.latitude
      marker.lng user.longitude
    end.to_json
  end
  markers
end

def without_html_escaping_in_json(&block)
  ActiveSupport.escape_html_entities_in_json = false
  yield
  ActiveSupport.escape_html_entities_in_json = true
end

Bonus question: How do I get rid of this ugly markers = nil and markers at the end of the build_markers method ?

apneadiving commented 9 years ago

How do you use the json? (For your bonus, just remove the markers temp var, blocks should return the results

jerefrer commented 9 years ago

I'm using the JSON like this in a HAML view:

:javascript
  handler = Gmaps.build('Google');
  handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
    markers = handler.addMarkers(#{@map_markers});
    handler.bounds.extendWith(markers);
    handler.fitMapToBounds();
  });

I think I've tried every possible combination of to_json and html_safe either in the controller or the view. This led me to think that this has become impossible to do for the sake of XSS safety.

For the bonus question, the thing is that without_html_escaping_in_json actually returns the value of ActiveSupport.escape_html_entities_in_json = true because it's the last line, so build_markers returns true instead of the return value of Gmaps4rails.build_markers.

apneadiving commented 9 years ago

Weird, I dont have such kinds of issues. I have no computer around to try though.

For bonus:

def without_html_escaping_in_json(&block)
  ActiveSupport.escape_html_entities_in_json = false
  result = yield
  ActiveSupport.escape_html_entities_in_json = true
  result
end
jerefrer commented 9 years ago

Haha so simple I didn't believe we could do this :) Thanks !