I’ve seen this code quite a few times in app/views: $.get(location.pathname+'?something'). It reads current pathname and requests it with some parameters or loads some extra JSON data. Or adjusts search filters. Lots of use cases. 100% innocent code, isn’t it?

No! location.pathname is considered harmful in Rails! Say, we have /customsearch endpoint.

  1. Rails doesn’t care about extra ‘/’ in the path and strips it. That’s why https://host.com//customsearch works. Thanks Rails!

  2. //customsearch is a path-relative URL and will turn this AJAX request into a cross domain request. Yes it was a bad idea to make // path relative directive. They should have created rel:// path instead for this purpose, would fix a lot of security issues with redirects. Thanks web standards!

  3. While buying 1st level “customsearch” domain is unfeasible there are tons of other cheap domains like customsearch.space, thanks to new affordable TLDs!

  4. https://host.com//customsearch.space will also work because the “.space” part is recognized as params[:format] of the request. Thanks Rails!

  5. Now when jQuery makes a cross domain request to our //customsearch.space we can simply return JS code with content type = text/javascript and it will be automatically executed by jQuery. Thanks jQuery!

This is not a super common bug but I like how couple of Rails “features” turned an absolutely innocent line of code into XSS.

Jun 25, 2015 • Egor Homakov (@homakov)