Content-Security-Policy-Report-Onlyを追加
This commit is contained in:
parent
ddde68ad2d
commit
b888c66ca2
|
@ -144,3 +144,6 @@ signToActivityPubGet: true
|
|||
|
||||
# Upload or download file size limits (bytes)
|
||||
#maxFileSize: 262144000
|
||||
|
||||
# Value of Content-Security-Policy header
|
||||
#contentSecurityPolicy: "script-src 'self' 'unsafe-eval' https://challenges.cloudflare.com https://hcaptcha.com https://*.hcaptcha.com https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ https://www.recaptcha.net/recaptcha/; base-uri 'self'; object-src 'self';"
|
||||
|
|
|
@ -145,3 +145,6 @@ signToActivityPubGet: true
|
|||
|
||||
# Upload or download file size limits (bytes)
|
||||
#maxFileSize: 262144000
|
||||
|
||||
# Value of Content-Security-Policy header
|
||||
#contentSecurityPolicy: "script-src 'self' 'unsafe-eval' https://challenges.cloudflare.com https://hcaptcha.com https://*.hcaptcha.com https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ https://www.recaptcha.net/recaptcha/; base-uri 'self'; object-src 'self';"
|
||||
|
|
10
gulpfile.js
10
gulpfile.js
|
@ -36,12 +36,18 @@ gulp.task('copy:frontend:locales', cb => {
|
|||
});
|
||||
|
||||
gulp.task('build:backend:script', () => {
|
||||
return gulp.src(['./packages/backend/src/server/web/boot.js', './packages/backend/src/server/web/bios.js', './packages/backend/src/server/web/cli.js'])
|
||||
const clientManifestExists = fs.existsSync('./built/_vite_/manifest.json');
|
||||
const clientEntry = clientManifestExists ?
|
||||
JSON.parse(fs.readFileSync('./built/_vite_/manifest.json', 'utf-8'))['src/init.ts'].file
|
||||
: 'src/init.ts'
|
||||
|
||||
return gulp.src(['./packages/backend/src/server/web/boot.js', './packages/backend/src/server/web/bios.js', './packages/backend/src/server/web/cli.js', './packages/backend/src/server/web/flush.js'])
|
||||
.pipe(replace('LANGS', JSON.stringify(Object.keys(locales))))
|
||||
.pipe(replace('CLIENT_ENTRY', JSON.stringify(clientEntry)))
|
||||
.pipe(terser({
|
||||
toplevel: true
|
||||
}))
|
||||
.pipe(gulp.dest('./packages/backend/built/server/web/'));
|
||||
.pipe(gulp.dest('./built/_frontend_dist_/'));
|
||||
});
|
||||
|
||||
gulp.task('build:backend:style', () => {
|
||||
|
|
|
@ -48,6 +48,8 @@ export type Source = {
|
|||
|
||||
allowedPrivateNetworks?: string[];
|
||||
|
||||
contentSecurityPolicy?: string;
|
||||
|
||||
maxFileSize?: number;
|
||||
|
||||
accesslog?: string;
|
||||
|
|
|
@ -172,6 +172,14 @@ export class ClientServerService {
|
|||
fastify.addHook('onRequest', (request, reply, done) => {
|
||||
// クリックジャッキング防止のためiFrameの中に入れられないようにする
|
||||
reply.header('X-Frame-Options', 'DENY');
|
||||
|
||||
// XSSが存在した場合に影響を軽減する
|
||||
// (script-srcにunsafe-inline等を追加すると意味が無くなるので注意)
|
||||
const csp = this.config.contentSecurityPolicy
|
||||
?? 'script-src \'self\' \'unsafe-eval\' ' +
|
||||
'https://challenges.cloudflare.com https://hcaptcha.com https://*.hcaptcha.com https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ https://www.recaptcha.net/recaptcha/; ' +
|
||||
'base-uri \'self\'; object-src \'self\';';
|
||||
reply.header('Content-Security-Policy', csp);
|
||||
done();
|
||||
});
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@
|
|||
<path d="M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75"></path>
|
||||
</svg>
|
||||
<h1>An error has occurred!</h1>
|
||||
<button class="button-big" onclick="location.reload();">
|
||||
<button class="button-big" id="reload">
|
||||
<span class="button-label-big">Refresh</span>
|
||||
</button>
|
||||
<p class="dont-worry">Don't worry, it's (probably) not your fault.</p>
|
||||
|
@ -181,6 +181,9 @@
|
|||
<br>
|
||||
<div id="errors"></div>
|
||||
`;
|
||||
document.getElementById("reload").addEventListener('click', () => {
|
||||
location.reload();
|
||||
});
|
||||
errorsElement = document.getElementById('errors');
|
||||
}
|
||||
const detailsElement = document.createElement('details');
|
||||
|
|
44
packages/backend/src/server/web/flush.js
Normal file
44
packages/backend/src/server/web/flush.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
'use strict';
|
||||
|
||||
const msg = document.getElementById('msg');
|
||||
const successText = `\nSuccess Flush! <a href="/">Back to Misskey</a>\n成功しました。<a href="/">Misskeyを開き直してください。</a>`;
|
||||
|
||||
message('Start flushing.');
|
||||
|
||||
(async function () {
|
||||
try {
|
||||
localStorage.clear();
|
||||
message('localStorage cleared.');
|
||||
|
||||
const idbPromises = ['MisskeyClient', 'keyval-store'].map((name, i, arr) => new Promise((res, rej) => {
|
||||
const delidb = indexedDB.deleteDatabase(name);
|
||||
delidb.onsuccess = () => res(message(`indexedDB "${name}" cleared. (${i + 1}/${arr.length})`));
|
||||
delidb.onerror = e => rej(e)
|
||||
}));
|
||||
|
||||
await Promise.all(idbPromises);
|
||||
|
||||
if (navigator.serviceWorker.controller) {
|
||||
navigator.serviceWorker.controller.postMessage('clear');
|
||||
await navigator.serviceWorker.getRegistrations()
|
||||
.then(registrations => {
|
||||
return Promise.all(registrations.map(registration => registration.unregister()));
|
||||
})
|
||||
.catch(e => { throw new Error(e) });
|
||||
}
|
||||
|
||||
message(successText);
|
||||
} catch (e) {
|
||||
message(`\n${e}\n\nFlush Failed. <a href="/flush">Please retry.</a>\n失敗しました。<a href="/flush">もう一度試してみてください。</a>`);
|
||||
message(`\nIf you retry more than 3 times, clear the browser cache or contact to instance admin.\n3回以上試しても失敗する場合、ブラウザのキャッシュを消去し、それでもだめならインスタンス管理者に連絡してみてください。\n`)
|
||||
|
||||
console.error(e);
|
||||
setTimeout(() => {
|
||||
location = '/';
|
||||
}, 10000)
|
||||
}
|
||||
})();
|
||||
|
||||
function message(text) {
|
||||
msg.insertAdjacentHTML('beforeend', `<p>[${(new Date()).toString()}] ${text.replace(/\n/g, '<br>')}</p>`)
|
||||
}
|
|
@ -63,12 +63,7 @@ html
|
|||
style
|
||||
include ../style.css
|
||||
|
||||
script.
|
||||
var VERSION = "#{version}";
|
||||
var CLIENT_ENTRY = "#{clientEntry.file}";
|
||||
|
||||
script
|
||||
include ../boot.js
|
||||
script(src=`/assets/boot.js?v=${version}`)
|
||||
|
||||
body
|
||||
noscript: p
|
||||
|
|
|
@ -8,8 +8,7 @@ html
|
|||
title Misskey Repair Tool
|
||||
style
|
||||
include ../bios.css
|
||||
script
|
||||
include ../bios.js
|
||||
script(src=`/assets/bios.js?v=${version}`)
|
||||
|
||||
body
|
||||
header
|
||||
|
|
|
@ -8,8 +8,7 @@ html
|
|||
title Misskey Cli
|
||||
style
|
||||
include ../cli.css
|
||||
script
|
||||
include ../cli.js
|
||||
script(src=`/assets/cli.js?v=${version}`)
|
||||
|
||||
body
|
||||
header
|
||||
|
|
|
@ -2,46 +2,4 @@ doctype html
|
|||
|
||||
html
|
||||
#msg
|
||||
script.
|
||||
const msg = document.getElementById('msg');
|
||||
const successText = `\nSuccess Flush! <a href="/">Back to Misskey</a>\n成功しました。<a href="/">Misskeyを開き直してください。</a>`;
|
||||
|
||||
message('Start flushing.');
|
||||
|
||||
(async function() {
|
||||
try {
|
||||
localStorage.clear();
|
||||
message('localStorage cleared.');
|
||||
|
||||
const idbPromises = ['MisskeyClient', 'keyval-store'].map((name, i, arr) => new Promise((res, rej) => {
|
||||
const delidb = indexedDB.deleteDatabase(name);
|
||||
delidb.onsuccess = () => res(message(`indexedDB "${name}" cleared. (${i + 1}/${arr.length})`));
|
||||
delidb.onerror = e => rej(e)
|
||||
}));
|
||||
|
||||
await Promise.all(idbPromises);
|
||||
|
||||
if (navigator.serviceWorker.controller) {
|
||||
navigator.serviceWorker.controller.postMessage('clear');
|
||||
await navigator.serviceWorker.getRegistrations()
|
||||
.then(registrations => {
|
||||
return Promise.all(registrations.map(registration => registration.unregister()));
|
||||
})
|
||||
.catch(e => { throw new Error(e) });
|
||||
}
|
||||
|
||||
message(successText);
|
||||
} catch (e) {
|
||||
message(`\n${e}\n\nFlush Failed. <a href="/flush">Please retry.</a>\n失敗しました。<a href="/flush">もう一度試してみてください。</a>`);
|
||||
message(`\nIf you retry more than 3 times, clear the browser cache or contact to instance admin.\n3回以上試しても失敗する場合、ブラウザのキャッシュを消去し、それでもだめならインスタンス管理者に連絡してみてください。\n`)
|
||||
|
||||
console.error(e);
|
||||
setTimeout(() => {
|
||||
location = '/';
|
||||
}, 10000)
|
||||
}
|
||||
})();
|
||||
|
||||
function message(text) {
|
||||
msg.insertAdjacentHTML('beforeend', `<p>[${(new Date()).toString()}] ${text.replace(/\n/g,'<br>')}</p>`)
|
||||
}
|
||||
script(src=`/assets/flush.js?v=${version}`)
|
||||
|
|
Loading…
Reference in a new issue