Enable trusted-types

This commit adds a policy, and make use of it in the Content-Security-Policy.

I've tested it the best I could, both on a modern browser supporting
trusted-types (Chrome) and on one that doesn't (firefox).

Thanks to @lweichselbaum for giving me a hand to wrap this up!
This commit is contained in:
jvoisin 2024-03-18 00:45:41 +01:00 committed by Frédéric Guillot
parent beb8c80787
commit ed20771194
5 changed files with 20 additions and 4 deletions

View file

@ -36,10 +36,10 @@
{{ if and .user .user.Stylesheet }}
{{ $stylesheetNonce := nonce }}
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src * data:; media-src *; frame-src *; style-src 'self' 'nonce-{{ $stylesheetNonce }}'">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src * data:; media-src *; frame-src *; style-src 'self' 'nonce-{{ $stylesheetNonce }}'; require-trusted-types-for 'script'; trusted-types ttpolicy;">
<style nonce="{{ $stylesheetNonce }}">{{ .user.Stylesheet | safeCSS }}</style>
{{ else }}
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src * data:; media-src *; frame-src *">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src * data:; media-src *; frame-src *; require-trusted-types-for 'script'; trusted-types ttpolicy;">
{{ end }}
<script src="{{ route "javascript" "name" "app" "checksum" .app_js_checksum }}" defer></script>

View file

@ -352,7 +352,7 @@ function handleFetchOriginalContent() {
response.json().then((data) => {
if (data.hasOwnProperty("content") && data.hasOwnProperty("reading_time")) {
document.querySelector(".entry-content").innerHTML = data.content;
document.querySelector(".entry-content").innerHTML = ttpolicy.createHTML(data.content);
const entryReadingtimeElement = document.querySelector(".entry-reading-time");
if (entryReadingtimeElement) {
entryReadingtimeElement.textContent = data.reading_time;

View file

@ -129,7 +129,7 @@ document.addEventListener("DOMContentLoaded", () => {
if ("serviceWorker" in navigator) {
const scriptElement = document.getElementById("service-worker-script");
if (scriptElement) {
navigator.serviceWorker.register(scriptElement.src);
navigator.serviceWorker.register(ttpolicy.createScriptURL(scriptElement.src));
}
}

View file

@ -0,0 +1,15 @@
let ttpolicy;
if (window.trustedTypes && trustedTypes.createPolicy) {
//TODO: use an allow-list for `createScriptURL`
if (!ttpolicy) {
ttpolicy = trustedTypes.createPolicy('ttpolicy', {
createScriptURL: src => src,
createHTML: html => html,
});
}
} else {
ttpolicy = {
createScriptURL: src => src,
createHTML: html => html,
};
}

View file

@ -113,6 +113,7 @@ func GenerateStylesheetsBundles() error {
func GenerateJavascriptBundles() error {
var bundles = map[string][]string{
"app": {
"js/tt.js", // has to be first
"js/dom_helper.js",
"js/touch_handler.js",
"js/keyboard_handler.js",