fix csrf protection on electron build

This commit is contained in:
zadam
2019-03-31 12:49:42 +02:00
parent bec6576620
commit 75dbaa4b77
7 changed files with 97 additions and 125 deletions
@@ -18,10 +18,6 @@ function setProtectedSessionTimeout(encSessTimeout) {
protectedSessionTimeout = encSessTimeout;
}
function getProtectedSessionId() {
return utils.getCookie(PROTECTED_SESSION_ID_KEY);
}
function setProtectedSessionId(id) {
// using session cookie so that it disappears after browser/tab is closed
utils.setSessionCookie(PROTECTED_SESSION_ID_KEY, id);
@@ -46,7 +42,6 @@ function touchProtectedSession() {
}
export default {
getProtectedSessionId,
setProtectedSessionId,
resetProtectedSession,
isProtectedSessionAvailable,
+2 -11
View File
@@ -1,22 +1,13 @@
import protectedSessionHolder from './protected_session_holder.js';
import utils from './utils.js';
import infoService from "./info.js";
function getHeaders() {
let protectedSessionId = null;
try { // this is because protected session might not be declared in some cases
protectedSessionId = protectedSessionHolder.getProtectedSessionId();
}
catch(e) {}
// headers need to be lowercase because node.js automatically converts them to lower case
// so hypothetical protectedSessionId becomes protectedsessionid on the backend
// also avoiding using underscores instead of dashes since nginx filters them out by default
return {
// protectedSessionId is normally carried in cookie, but for electron AJAX requests we bypass
// HTTP so no cookies and we need to pass it here explicitly
'trilium-protected-session-id': protectedSessionId,
// passing it explicitely here because of the electron HTTP bypass
'cookie': document.cookie,
'trilium-source-id': glob.sourceId,
'x-csrf-token': glob.csrfToken
};
+22 -23
View File
@@ -2,32 +2,31 @@ const ipcMain = require('electron').ipcMain;
function init(app) {
ipcMain.on('server-request', (event, arg) => {
const req = {};
req.url = arg.url;
req.method = arg.method;
req.body = arg.data;
req.headers = arg.headers;
req.session = {
loggedIn: true
const req = {
url: arg.url,
method: arg.method,
body: arg.data,
headers: arg.headers,
session: {
loggedIn: true
}
};
const res = {
statusCode: 200
};
res.setHeader = function() {};
res.status = function(statusCode) {
res.statusCode = statusCode;
return res;
};
res.send = function(obj) {
event.sender.send('server-response', {
requestId: arg.requestId,
statusCode: res.statusCode,
body: obj
});
statusCode: 200,
getHeader: () => {},
setHeader: () => {},
status: statusCode => {
res.statusCode = statusCode;
return res;
},
send: obj => {
event.sender.send('server-response', {
requestId: arg.requestId,
statusCode: res.statusCode,
body: obj
});
}
};
return app._router.handle(req, res, () => {});
+8 -11
View File
@@ -307,12 +307,12 @@ async function saveNoteRevision(note) {
const now = new Date();
const noteRevisionSnapshotTimeInterval = parseInt(await optionService.getOption('noteRevisionSnapshotTimeInterval'));
const revisionCutoff = dateUtils.dateStr(new Date(now.getTime() - noteRevisionSnapshotTimeInterval * 1000));
const revisionCutoff = dateUtils.utcDateStr(new Date(now.getTime() - noteRevisionSnapshotTimeInterval * 1000));
const existingNoteRevisionId = await sql.getValue(
"SELECT noteRevisionId FROM note_revisions WHERE noteId = ? AND dateModifiedTo >= ?", [note.noteId, revisionCutoff]);
"SELECT noteRevisionId FROM note_revisions WHERE noteId = ? AND utcDateModifiedTo >= ?", [note.noteId, revisionCutoff]);
const msSinceDateCreated = now.getTime() - dateUtils.parseDateTime(note.dateCreated).getTime();
const msSinceDateCreated = now.getTime() - dateUtils.parseDateTime(note.utcDateCreated).getTime();
if (!existingNoteRevisionId && msSinceDateCreated >= noteRevisionSnapshotTimeInterval * 1000) {
await new NoteRevision({
@@ -323,8 +323,10 @@ async function saveNoteRevision(note) {
type: note.type,
mime: note.mime,
isProtected: false, // will be fixed in the protectNoteRevisions() call
utcDateModifiedFrom: note.utcDateModified,
utcDateModifiedTo: dateUtils.utcNowDateTime(),
dateModifiedFrom: note.dateModified,
dateModifiedTo: dateUtils.nowDate()
dateModifiedTo: dateUtils.localNowDateTime()
}).save();
}
}
@@ -344,17 +346,12 @@ async function updateNote(noteId, noteUpdates) {
note.isProtected = noteUpdates.isProtected;
await note.save();
const noteContent = await note.getNoteContent();
if (!['file', 'image'].includes(note.type)) {
noteUpdates.noteContent.content = await saveLinks(note, noteUpdates.noteContent.content);
noteUpdates.content = await saveLinks(note, noteUpdates.content);
noteContent.content = noteUpdates.noteContent.content;
await note.setContent(noteUpdates.content);
}
noteContent.isProtected = noteUpdates.isProtected;
await noteContent.save();
if (noteTitleChanged) {
await triggerNoteTitleChanged(note);
}
+1 -2
View File
@@ -15,8 +15,7 @@ function setDataKey(decryptedDataKey) {
}
function setProtectedSessionId(req) {
// cookies is the main storage but for electron header is used when bypassing HTTP
cls.namespace.set('protectedSessionId', req.headers['trilium-protected-session-id'] || req.cookies.protectedSessionId);
cls.namespace.set('protectedSessionId', req.cookies.protectedSessionId);
}
function getProtectedSessionId() {