Skip to content

Commit

Permalink
check csrf from join to jwt session csrf and do not process join if t…
Browse files Browse the repository at this point in the history
…hey don't match; some comments towards csrf on forms
  • Loading branch information
floodfx committed Feb 8, 2022
1 parent ec4cf47 commit cfb84e5
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions src/server/socket/component_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export class LiveViewComponentManager {
private intervals: NodeJS.Timeout[] = [];
private lastHeartbeat: number = Date.now();
private socketIsClosed: boolean = false;
csrfToken?: string;

constructor(component: LiveViewComponent<unknown, unknown>, signingSecret: string) {
this.component = component;
Expand All @@ -31,16 +32,22 @@ export class LiveViewComponentManager {

// extract params, session and socket from payload
const { params: payloadParams, session: payloadSession, static: payloadStatic } = payload;
// set component manager csfr token
this.csrfToken = payloadParams._csrf_token;

// TODO - use session from cookie
let session = {}
let session: Omit<SessionData, "cookie">;
try {
session = jwt.verify(payloadSession, this.signingSecret) as Partial<SessionData>;
session = jwt.verify(payloadSession, this.signingSecret) as Omit<SessionData, "cookie">;
// compare sesison csrfToken with csrfToken from payload
if (session.csrfToken !== this.csrfToken) {
// if session csrfToken does not match payload csrfToken, reject join
console.log("Rejecting join due to mismatched csrfTokens", session.csrfToken, this.csrfToken);
return;
}
} catch (e) {
console.log("failed to decode session", e);
console.log("Error decoding session", e);
return;
}
// TODO - check csfr token?
// TODO - compare csfr token with session _csrf?

const liveViewSocket = this.buildLiveViewSocket(ws, topic);
// pass in phx_join payload params, session, and socket
Expand Down Expand Up @@ -80,6 +87,8 @@ export class LiveViewComponentManager {
} else if (type === "form") {
// @ts-ignore - URLSearchParams has an entries method but not typed
value = Object.fromEntries(new URLSearchParams(payload.value))
// TODO - check value for _csrf_token here from phx_submit and validate against session csrf?
// TODO - check for _target variable from phx_change here and remove it from value?
} else if (type === "keyup" || type === "keydown") {
value = payload.value;
} else if (type === "blur" || type === "focus") {
Expand Down Expand Up @@ -107,7 +116,7 @@ export class LiveViewComponentManager {
this.sendPhxReply(ws, newPhxReply(message, replyPayload));
}
else {
console.error("no handleEvent in component", this.component);
console.error("no handleEvent method in component. add handleEvent method in your component to fix this error");
return;
}

Expand Down

0 comments on commit cfb84e5

Please sign in to comment.