fix: Use crypto.timingSafeEqual, closes #3740
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import crypto from "crypto";
|
||||||
import { Context } from "koa";
|
import { Context } from "koa";
|
||||||
import Router from "koa-router";
|
import Router from "koa-router";
|
||||||
import env from "@server/env";
|
import env from "@server/env";
|
||||||
@@ -13,7 +14,12 @@ const router = new Router();
|
|||||||
const cronHandler = async (ctx: Context) => {
|
const cronHandler = async (ctx: Context) => {
|
||||||
const { token, limit = 500 } = ctx.body as { token?: string; limit: number };
|
const { token, limit = 500 } = ctx.body as { token?: string; limit: number };
|
||||||
|
|
||||||
if (env.UTILS_SECRET !== token) {
|
if (
|
||||||
|
!crypto.timingSafeEqual(
|
||||||
|
Buffer.from(env.UTILS_SECRET),
|
||||||
|
Buffer.from(String(token))
|
||||||
|
)
|
||||||
|
) {
|
||||||
throw AuthenticationError("Invalid secret token");
|
throw AuthenticationError("Invalid secret token");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import crypto from "crypto";
|
||||||
import Router from "koa-router";
|
import Router from "koa-router";
|
||||||
import { escapeRegExp } from "lodash";
|
import { escapeRegExp } from "lodash";
|
||||||
import env from "@server/env";
|
import env from "@server/env";
|
||||||
@@ -19,6 +20,23 @@ import { assertPresent } from "@server/validation";
|
|||||||
|
|
||||||
const router = new Router();
|
const router = new Router();
|
||||||
|
|
||||||
|
function verifySlackToken(token: string) {
|
||||||
|
if (!env.SLACK_VERIFICATION_TOKEN) {
|
||||||
|
throw AuthenticationError(
|
||||||
|
"SLACK_VERIFICATION_TOKEN is not present in environment"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!crypto.timingSafeEqual(
|
||||||
|
Buffer.from(env.SLACK_VERIFICATION_TOKEN),
|
||||||
|
Buffer.from(token)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw AuthenticationError("Invalid token");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// triggered by a user posting a getoutline.com link in Slack
|
// triggered by a user posting a getoutline.com link in Slack
|
||||||
router.post("hooks.unfurl", async (ctx) => {
|
router.post("hooks.unfurl", async (ctx) => {
|
||||||
const { challenge, token, event } = ctx.body;
|
const { challenge, token, event } = ctx.body;
|
||||||
@@ -26,9 +44,8 @@ router.post("hooks.unfurl", async (ctx) => {
|
|||||||
return (ctx.body = ctx.body.challenge);
|
return (ctx.body = ctx.body.challenge);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token !== env.SLACK_VERIFICATION_TOKEN) {
|
assertPresent(token, "token is required");
|
||||||
throw AuthenticationError("Invalid token");
|
verifySlackToken(token);
|
||||||
}
|
|
||||||
|
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
include: [
|
include: [
|
||||||
@@ -88,10 +105,7 @@ router.post("hooks.interactive", async (ctx) => {
|
|||||||
|
|
||||||
assertPresent(token, "token is required");
|
assertPresent(token, "token is required");
|
||||||
assertPresent(callback_id, "callback_id is required");
|
assertPresent(callback_id, "callback_id is required");
|
||||||
|
verifySlackToken(token);
|
||||||
if (token !== env.SLACK_VERIFICATION_TOKEN) {
|
|
||||||
throw AuthenticationError("Invalid verification token");
|
|
||||||
}
|
|
||||||
|
|
||||||
// we find the document based on the users teamId to ensure access
|
// we find the document based on the users teamId to ensure access
|
||||||
const document = await Document.scope("withCollection").findByPk(
|
const document = await Document.scope("withCollection").findByPk(
|
||||||
@@ -125,10 +139,7 @@ router.post("hooks.slack", async (ctx) => {
|
|||||||
assertPresent(token, "token is required");
|
assertPresent(token, "token is required");
|
||||||
assertPresent(team_id, "team_id is required");
|
assertPresent(team_id, "team_id is required");
|
||||||
assertPresent(user_id, "user_id is required");
|
assertPresent(user_id, "user_id is required");
|
||||||
|
verifySlackToken(token);
|
||||||
if (token !== env.SLACK_VERIFICATION_TOKEN) {
|
|
||||||
throw AuthenticationError("Invalid verification token");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle "help" command or no input
|
// Handle "help" command or no input
|
||||||
if (text.trim() === "help" || !text.trim()) {
|
if (text.trim() === "help" || !text.trim()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user