4,700 karma · joined September 29, 2011
Then I started clicking "block this address" from another drop-down - never got any new mail. Much recommended approach.
It is the main reason, yes, but not the only reason. If it wasn't possible to craft cross-site HEAD (which devs use in real life like.. never?) the bug would stop right there.
With an extra method if-else logic turned faulty. I would argue 90% web devs don't even remember of HEAD and what it means. Reasonably so, because it's rather never used.
IMO order of blame: 1) rails 2) browsers 3) github code relying on .get?
Pardon my poor wording indeed, I intended to mean this too.
It absolutely should. Nobody expected Rails to covertly turn HEAD into GET. It must be explicit "get_or_head" method in routes.rb
const authUrl = `https://github.com/login/oauth/authorize?
client_id=${CLIENT_ID}&scope=read:user&authorize=1`;
fetch(
authUrl,
{
method: 'HEAD',
credentials: 'include',
mode: 'no-cors'
}
)Seriously who needs HEAD in their client side development? It's purely a technical method w/o clear use pattern. It's not even valid in <form method=""> so why would it be valid in fetch()? Oh and PATCH/PUT are still invalid in fetch().
We're lucky that this code pattern is only common in Rails. Otherwise it could open a whole class of bugs.
For this reason browser upgrades must be extremely careful to not break older protections.
That's why you cannot set your own referer (which is supposed to mean nothing), you cannot supply Content-type: application/json unless instructed by CORS preflight, etc etc.
Here, the backwards compatibility was clearly broken. It was never possible to send HEAD few years ago with regular XHR or <img>s. Web standards owe $25k back to github. Yes, github's routing was flawed but it wasn't exploitable until browsers allowed HEAD in fetch() no-cors mode.
In a rails env the only way to upgrade to non-standard methods (PATCH, PUT etc) were always to supply _method and pass CSRF protection first.
This trick is clearly a bypass because it instructs browser to make a HEAD request, something it never did before. If you try to make other non-standard request you will get this error:
Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'Window': 'PATCH' is unsupported in no-cors mode.
It also reminded me of why "match" was removed in the first place - http://homakov.blogspot.com/2012/04/whitelist-your-routes-ma... - you could route any POST request via GET therefore bypassing CSRF checks still getting inside the controller.
Also, for no reason Airbnb prohibits from sorting by reviews or price, so I've developed this script - it's super userful: http://sakurity.com/airbnb.js