Cross-Site Request Forgery (CSRF) in polonel/trudesk
Reported on
Dec 21st 2021
Description
There is a CSRF vulnerability which would allow an attacker to restart the server by simply having a victim with the appropriate privileges visit an attacker's crafted webpage.
The vulnerability exists when performing a GET request to the /api/v1/admin/restart
endpoint
There is also another CSRF vulnerability which would allow an attacker to disable a victim's 2FA (/api/v1/users/<user ID>/removel2auth
). This requires the victim's user ID, but this can easily be obtained by simply deleting a conversation with the victim which is a vulnerability that I described here: https://huntr.dev/bounties/74c6f886-2869-4b32-bef3-2cb3991a9311
Proof of Concept
for resetting the server:
//serverReset.html
<html>
<form action="https://docker.trudesk.io/api/v1/admin/restart" method="GET"/>
<script>
document.forms[0].submit();
</script>
</html>
for disabling 2FA:
<html>
< -- change the user ID to the user ID of the victim for which you're disabling 2FA -- >
<form action="https://docker.trudesk.io/api/v1/users/<user ID>/removel2auth" method="POST"/>
<script>
document.forms[0].submit();
</script>
</html>
Impact
This vulnerability is capable of performing a DoS attack on the server which can have a major business impact. It can be paired with the XSS vulnerability that I found & reported previously to create an even more effective DoS attack.
For example, an attacker could craft an XSS payload that would automatically redirect a victim to their webpage where the CSRF attack that restarts the server would take place. The attacker could spam the victim with messages that contain the XSS payload. Then each time the attacker opens the message, the victim would be redirected & the CSRF attack would take place and the server would restart.
Occurrences
users.js L937
As we can see, the only protection in the code is verifying that the user ID passed in the URL matches the user ID of the person making the request. And if the user IDs do not match up, an error stating "Invalid Account Owner" is returned (lines 939-940).
Moving onto line 949, which is after all error checking is finished, there is no CSRF token check before setting the MFA to null (req.session.l2auth = null
).
This has been fixed in v1.2.2. I will update this report once it is released.