mirror of
https://github.com/MisskeyIO/misskey
synced 2024-11-23 22:56:49 +09:00
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)
|
# Upload or download file size limits (bytes)
|
||||||
#maxFileSize: 262144000
|
#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)
|
# Upload or download file size limits (bytes)
|
||||||
#maxFileSize: 262144000
|
#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', () => {
|
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('LANGS', JSON.stringify(Object.keys(locales))))
|
||||||
|
.pipe(replace('CLIENT_ENTRY', JSON.stringify(clientEntry)))
|
||||||
.pipe(terser({
|
.pipe(terser({
|
||||||
toplevel: true
|
toplevel: true
|
||||||
}))
|
}))
|
||||||
.pipe(gulp.dest('./packages/backend/built/server/web/'));
|
.pipe(gulp.dest('./built/_frontend_dist_/'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('build:backend:style', () => {
|
gulp.task('build:backend:style', () => {
|
||||||
|
@ -48,6 +48,8 @@ export type Source = {
|
|||||||
|
|
||||||
allowedPrivateNetworks?: string[];
|
allowedPrivateNetworks?: string[];
|
||||||
|
|
||||||
|
contentSecurityPolicy?: string;
|
||||||
|
|
||||||
maxFileSize?: number;
|
maxFileSize?: number;
|
||||||
|
|
||||||
accesslog?: string;
|
accesslog?: string;
|
||||||
|
@ -172,6 +172,14 @@ export class ClientServerService {
|
|||||||
fastify.addHook('onRequest', (request, reply, done) => {
|
fastify.addHook('onRequest', (request, reply, done) => {
|
||||||
// クリックジャッキング防止のためiFrameの中に入れられないようにする
|
// クリックジャッキング防止のためiFrameの中に入れられないようにする
|
||||||
reply.header('X-Frame-Options', 'DENY');
|
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();
|
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>
|
<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>
|
</svg>
|
||||||
<h1>An error has occurred!</h1>
|
<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>
|
<span class="button-label-big">Refresh</span>
|
||||||
</button>
|
</button>
|
||||||
<p class="dont-worry">Don't worry, it's (probably) not your fault.</p>
|
<p class="dont-worry">Don't worry, it's (probably) not your fault.</p>
|
||||||
@ -181,6 +181,9 @@
|
|||||||
<br>
|
<br>
|
||||||
<div id="errors"></div>
|
<div id="errors"></div>
|
||||||
`;
|
`;
|
||||||
|
document.getElementById("reload").addEventListener('click', () => {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
errorsElement = document.getElementById('errors');
|
errorsElement = document.getElementById('errors');
|
||||||
}
|
}
|
||||||
const detailsElement = document.createElement('details');
|
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
|
style
|
||||||
include ../style.css
|
include ../style.css
|
||||||
|
|
||||||
script.
|
script(src=`/assets/boot.js?v=${version}`)
|
||||||
var VERSION = "#{version}";
|
|
||||||
var CLIENT_ENTRY = "#{clientEntry.file}";
|
|
||||||
|
|
||||||
script
|
|
||||||
include ../boot.js
|
|
||||||
|
|
||||||
body
|
body
|
||||||
noscript: p
|
noscript: p
|
||||||
|
@ -8,8 +8,7 @@ html
|
|||||||
title Misskey Repair Tool
|
title Misskey Repair Tool
|
||||||
style
|
style
|
||||||
include ../bios.css
|
include ../bios.css
|
||||||
script
|
script(src=`/assets/bios.js?v=${version}`)
|
||||||
include ../bios.js
|
|
||||||
|
|
||||||
body
|
body
|
||||||
header
|
header
|
||||||
|
@ -8,8 +8,7 @@ html
|
|||||||
title Misskey Cli
|
title Misskey Cli
|
||||||
style
|
style
|
||||||
include ../cli.css
|
include ../cli.css
|
||||||
script
|
script(src=`/assets/cli.js?v=${version}`)
|
||||||
include ../cli.js
|
|
||||||
|
|
||||||
body
|
body
|
||||||
header
|
header
|
||||||
|
@ -2,46 +2,4 @@ doctype html
|
|||||||
|
|
||||||
html
|
html
|
||||||
#msg
|
#msg
|
||||||
script.
|
script(src=`/assets/flush.js?v=${version}`)
|
||||||
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>`)
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user