Puzzle #2: Really Curious XSS in Rails
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.
-
Rails doesn’t care about extra ‘/’ in the path and strips it. That’s why https://host.com//customsearch works. Thanks Rails!
-
//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 createdrel://
path instead for this purpose, would fix a lot of security issues with redirects. Thanks web standards! -
While buying 1st level “customsearch” domain is unfeasible there are tons of other cheap domains like
customsearch.space
, thanks to new affordable TLDs! -
https://host.com//customsearch.space will also work because the “.space” part is recognized as params[:format] of the request. Thanks Rails!
-
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.