Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What about Same-Origin Resource Sharing? #546

Closed
pak0s opened this issue Feb 8, 2019 · 7 comments
Closed

What about Same-Origin Resource Sharing? #546

pak0s opened this issue Feb 8, 2019 · 7 comments

Comments

@pak0s
Copy link

pak0s commented Feb 8, 2019

The idea is about to prevent XSS to RCE scenarios because its successful mostly because of SOP. For example if there is a XSS in Wordpress theme, it can be easily converted into RCE using following Javascript code.

var ajaxRequest = new XMLHttpRequest();
var requestURL = "/wp-admin/user-new.php";
var wp_nonceRegex = /ser" value="([^"]*?)"/g;
ajaxRequest.open("GET", requestURL, false);
ajaxRequest.send();
var nonceMatch = wp_nonceRegex.exec(ajaxRequest.responseText);
var nonce = nonceMatch[1];
var params = "action=createuser&_wpnonce_create-user="+nonce+"&user_login=config&email=email@attacker.com&pass1=attackpass&pass2=attackpass&role=administrator";
ajaxRequest = new XMLHttpRequest();
ajaxRequest.open("POST", requestURL, true);
ajaxRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajaxRequest.send(params);

The 1st XHR request fetches the CSRF token and then 2nd sends CSRF request to add admin user. Though I already shared this idea on whatwg but the solution wasn't feasible since its implementation could have been very complex. So I came around another solution like what if the server initiates this already existing heaeder Access-Control-Allow-Origin: none and the user-agent restricts the response to be fetched by Javascript. The none will dictate browser to not share content even with Same-Origin.
On the legit XHR/Ajax calls i.e. wp-admin/admin-ajax.php, this header shouldn't be initiated by server. The server wasn't expecting any XHR request on wp-admin/user-new.php whatsoever.
One of the use cases is that an attacker can open an iframe or a child window and walk through its DOM. The potential solution for this is, user-agent should not load iframe or child window if this header exists. In case of iframe, this header will work similar to X-Frame-Options: deny
This technique may limit the impact of XSS on the vulnerable URL only and restrict attacker from abusing SOP. What do you guys think about this or if there is any other use case?

@ericlaw1979
Copy link

In what scenario would the content be allowed to load at all? If you allow it to load in a top-level window, the same-origin attacker can still walk the DOM of that window. One could imagine that this header implicitly disavows the opener, I guess.

But stepping back a bit-- Access-Control-Allow-Origin is about controlling access to the response. In the case you've described, you're trying to block the request to user-new.php, not the accessibility of the response. And that requires a different methodology entirely, a la http://randomdross.blogspot.com/2014/08/entry-point-regulation-for-web-apps.html

@pak0s
Copy link
Author

pak0s commented Feb 11, 2019

Content should only be loaded on a simple http request. For example I am not expecting any XHR request on wp-admin/user-new.php so I will initiate a header Access-Control-Allow-Origin: deny. So if XSS payload is trying to steal the CSRF token at that request, the browser will restrict access to it just like it does on a normal CORS request. But on a CORS request, browser isn't expecting any specific header to restrict access to response. While in this case, browser will only restrict access to response if it finds this header Access-Control-Allow-Origin: deny in response

In the case you've described, you're trying to block the request to user-new.php, not the accessibility of the response.

In this case, I am trying to block the accessibility of the response, not the request. My previous solution was to initiate new header on the request and then block it at the server side but it wasn't feasible.

@ericlaw1979
Copy link

In this case, I am trying to block the accessibility of the response, not the request

Ah, is the theory here that user-new.php is the page that contains some anti-CSRF token that you're trying to hide?

@pak0s
Copy link
Author

pak0s commented Feb 11, 2019 via email

@mozfreddyb
Copy link
Contributor

I can see some value about what you're trying to achieve, but I can't find a way around the Same-Origin Policy biting you along the way.

If you block XHR/fetch, you also need to block navigation (window.open(), <iframe>, <a target=_blank> etc.). If you fix those holes, you would arrive at something like Entry Point Regulation, as @ericlaw1979 linked above, no?

@pak0s
Copy link
Author

pak0s commented Feb 13, 2019

Yeah window.open() and iframe were the worst case scenarios. So the potential solution is to restrict them from getting loaded if header Control-Allow-Origin: deny exists. As I said above, if this header exists, it will act like X-Frame-Options: deny in case of iframe.
Just checked EPR and as per my understanding, it helps prevent CSRF, Reflected XSS and similar attacks by loading set of rules in manifest file. But can it prevent requests from same-origin?

@arturjanc
Copy link
Contributor

What you're proposing sounds similar in spirit to Suborigins: https://w3c.github.io/webappsec-suborigins/ (with some context in this doc) -- the idea is to allow parts of your application to isolate themselves from the rest of the origin. Sadly, this proposal is not actively pursued at the moment.

As @mozfreddyb says, there is likely no tractable way to make this happen without extending the same-origin policy to separate documents that are currently considered-same origin -- there are simply too many interactions allowed under the SOP to provide meaningful guarantees otherwise.

@dveditz dveditz closed this as completed Feb 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants