GravCMS: XSS via SVG

Marcin Teodorczyk
Apr 2 · 3 min read

Previously I’ve described privilege escalation with XSS and how to use user settings to gain admin privileges. Now it’s time for the last article in the series on Grav CMS — the least severe but quite interesting and often overlooked SVG file upload.

Environment

I’ve worked on Grav Devel and Admin Devel versions as of 21th of December, 2018, the default Grav installation, admin account and user account with following privileges:

The Bug

The Grav Team surely takes security of their platform seriously. Users can upload their own avatar file, but are restricted to precisely defined file types. Such whitelist approaches are most of the time the best from the perspective of security. However in this particular case, the allowed list of avatar file types includes SVG — quite complicated format, allowing embedded JavaScript.

A Malicious users can upload an SVG avatar. The avatar is then accessible with direct link in the domain of the CMS. If someone opens it in a browser, JavaScript will be executed in the context of the CMS domain and current user session if such exists.

Proof of Concept

Low privilege user1 can upload SVG avatar including embedded JavaScript with two requests.

First, the user uploads a malicious file. As we can see in the request, the content of the file includes classic JavaScript PoC code: alert(1).

/admin/user/user1.json request (first)
/admin/user/user1.json response

Second, the user sets the previously uploaded file as his avatar.

/admin/user/user1 request (second)
/admin/user/user1 response

Starting from now on, the file is available through the browser under the following endpoint /user/accounts/avatars/1i0FpO3bmsq8ycD.svg, which can be obtained from the above requests/replies.

If any user (or admin in particular) opens the endpoint in a browser, JavaScript will be executed as shown below:

If the victim is logged in, JavaScript might be able to perform some actions on behalf of the victim.

Summary

The presented bug is the least severe in the series of articles about Grav CMS. Many prerequisites are required to exploit it: a malicious user has to have an account and upload a malicious SVG avatar; then he has to somehow make a victim user open the direct link to the avatar — all while hoping that the victim will be logged in when opening the link.

Real world security is never black and white. Risks, costs and benefits always have to be taken into account. The presented scenario is quite low probable and poses rather low risk. In some cases it might be reasonably to give such bug low priority or even accept the risk. Nonetheless, surely it was fun to find it.

intive Developers

At intive we’re building great digital products for our customers. Day by day. We want to share with you our way of doing things, the challenges we face, the tricks and shortcuts we discover. A little peek behind the scenes — welcome to our intive_dev blog!

Marcin Teodorczyk

Written by

intive Developers

At intive we’re building great digital products for our customers. Day by day. We want to share with you our way of doing things, the challenges we face, the tricks and shortcuts we discover. A little peek behind the scenes — welcome to our intive_dev blog!