codex-team / editor.js

A block-style editor with clean JSON output
https://editorjs.io
Apache License 2.0
28.52k stars 2.08k forks source link

Security: does Editor.js sanitize the text and links before displaying it? #2582

Open collimarco opened 9 months ago

collimarco commented 9 months ago

Suppose that you have multiple users that collaborate on the same document.

For example:

  1. User A creates a document and inserts some malicious code like This is a paragraph with [a link](javascript:alert('XSS!'))
  2. The document is sent to the server
  3. User B opens the document and the existing data is loaded into Editor.js
  4. If the HTML is not sanitized by Editor.js, the JSON is converted back to HTML and arbitrary JS execution happens.

Does Editor.js sanitize the HTML tags and links when it loads them from existing JSON data?

Ideally Editor.js should perform the following sanitizations:

collimarco commented 9 months ago

I made some testing now and unfortunately Editor.js seems vulnerable:

  1. Just try to add a link and type javascript:alert('test') as the URL
  2. The href is added to the page without any sanitization
  3. Save and reload the document from JSON
  4. Again, the JSON is converted to HTML without any sanitization (you will see <a href="javascript:alert('test')"> in the code)
collimarco commented 9 months ago

Another test:

  1. Add some code to the text in the saved JSON, like "This is a paragraph <script> alert('xss') </script>"
  2. If you load the Editor.js with that JSON, the script is injected in the page
  3. However from my test the script doesn't seem to be executed, probably because the HTML is appended to the DOM (and I think that append or similar functions don't execute the scripts)
collimarco commented 9 months ago

Editor.js sanitizes all content in several cases: on render, on paste, and on save. https://editorjs.io/inline-tool-sanitizing/

This sentence is strange, because it's not the behavior that I am seeing.

ConnectGrid commented 9 months ago

Not sure which server-side language you use, but that shouldn't matter much. The output of EditorJS is JSON, so you convert that to whatever object representation your server-side language supports, sanitize each block, and then convert back to JSON. This should be fairly easy to do in the server side programming, and you have full control over it.

collimarco commented 9 months ago

you convert that to whatever object representation your server-side language supports, sanitize each block, and then convert back to JSON

I've done that properly for our application, but it's really a tedious task: you need to unwrap the JSON and parse each field. And you need to implement that for each block that you use, it's not a single function.

I guess that many applications are vulnerable and simply load the saved JSON data into Editor.js.