From ef724d0fc287bde94553f46ffde9787fc0f7eb4e Mon Sep 17 00:00:00 2001 From: Erik Michelson Date: Wed, 3 Dec 2025 22:16:05 +0100 Subject: [PATCH] fix(renderer): use credentialless and sandbox attributes on iframes Websites loaded via an iframe could interrupt the user's workflow by initiating certain actions like opening print dialogs, alert boxes, etc. on the user's browser or even initiate file downloads. By using the sandbox attribute, the iframe is limited in it's actions and can't access browser APIs such as to download files. With the additional credentialless attribute, the page in the iframe is loaded in a completely separate browsing context on Chromium-based browsers, thus isolating the content even more. The functionality could previously be abused to initiate certain actions on 3rd-party websites where the user is logged-in, if these 3rd-party websites have no proper CSRF protection. However, this is not a security risk to HedgeDoc itself. Signed-off-by: Erik Michelson --- public/docs/release-notes.md | 1 + public/js/extra.js | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/public/docs/release-notes.md b/public/docs/release-notes.md index 3fa12931..9f7b6f78 100644 --- a/public/docs/release-notes.md +++ b/public/docs/release-notes.md @@ -14,6 +14,7 @@ - Ignore the healthcheck endpoint in the "too busy" limiter - Send the referrer origin for YouTube embeddings due to their requirement - Force kill the server after a timeout when waiting for the realtime server to close connections on shutdown +- Secure iframes with `credentialless` and `sandbox` attributes - Fix regexes for `[time=...]`, `[name=...]` and `[color=...]` shortcodes in lists ## 1.10.3 2025-04-09 diff --git a/public/js/extra.js b/public/js/extra.js index c2a4c367..fc2405cd 100644 --- a/public/js/extra.js +++ b/public/js/extra.js @@ -461,7 +461,7 @@ export function finishView (view) { inner.attr('target', '_blank') $(value).append(inner) }) - // pdf + // pdf view.find('div.pdf.raw').removeClass('raw') .each(function (key, value) { const url = $(value).attr('data-pdfurl') @@ -471,7 +471,12 @@ export function finishView (view) { height: '400px' }) }) - // syntax highlighting + // iframe + view.find('iframe') + .each((key, value) => { + $(value).attr('credentialless', '').attr('sandbox', '') + }) + // syntax highlighting view.find('code.raw').removeClass('raw') .each((key, value) => { const langDiv = $(value)