You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Ajax.Request#isSameOrigin() treats protocol-relative URLs as same-origin #369
While going through the Ajax code in src/prototype/ajax/request.js I noticed that isSameOrigin() classifies a protocol-relative URL (for example //evil.example/x.js) as same-origin, even though it points at a different origin. Since isSameOrigin() is one of the gates that decides whether a response body gets evaluated as JavaScript, this lets a cross-origin response slip past that check.
The regex only matches an absolute http:// or https:// prefix. For any URL that does not start with one of those, m is null, so !m short-circuits to true and the URL is treated as same-origin. That is correct for genuinely relative URLs like /api/x, but it also captures protocol-relative URLs like //host/x, which are cross-origin.
Why it matters: combined with the default evalJS: true, a request whose URL is built from data that can begin with // can end up executing an attacker-controlled response in the page's origin, because evalResponse() runs the response body through eval() when the content type looks like JavaScript.
Suggested fix: resolve the URL against location (for example new URL(this.url, location.href)) and compare .origin against location.origin, so protocol-relative URLs are treated as potentially cross-origin. It would also be worth dropping document.domain from the comparison, since it can be relaxed at runtime.
Activity