Encrypt cookies, set them to expire at the end of time, httpOnly and sameSite as good security practices
This commit is contained in:
parent
b6e8242bb6
commit
b7cb6f69e7
|
@ -24,6 +24,7 @@ const Sentry = require("@sentry/node");
|
||||||
const metrics = require("./metrics");
|
const metrics = require("./metrics");
|
||||||
const sgMail = require("@sendgrid/mail");
|
const sgMail = require("@sendgrid/mail");
|
||||||
const ejs = require("ejs");
|
const ejs = require("ejs");
|
||||||
|
const cookieEncrypter = require("cookie-encrypter");
|
||||||
|
|
||||||
let ssbServer;
|
let ssbServer;
|
||||||
let mode = process.env.MODE || "client";
|
let mode = process.env.MODE || "client";
|
||||||
|
@ -75,8 +76,17 @@ app.use(bodyParser.json());
|
||||||
app.use(bodyParser.urlencoded({ extended: true }));
|
app.use(bodyParser.urlencoded({ extended: true }));
|
||||||
app.set("view engine", "ejs");
|
app.set("view engine", "ejs");
|
||||||
app.use(express.static("public"));
|
app.use(express.static("public"));
|
||||||
app.use(cookieParser());
|
|
||||||
app.use(fileUpload());
|
app.use(fileUpload());
|
||||||
|
const cookieSecret =
|
||||||
|
process.env.COOKIES_SECRET || "set_cookie_secret_you_are_unsafe"; // has to be 32-bits
|
||||||
|
const cookieOptions = {
|
||||||
|
httpOnly: true,
|
||||||
|
signed: true,
|
||||||
|
expires: new Date(253402300000000), // Friday, 31 Dec 9999 23:59:59 GMT, nice date from stackoverflow
|
||||||
|
sameSite: true,
|
||||||
|
};
|
||||||
|
app.use(cookieParser(cookieSecret));
|
||||||
|
app.use(cookieEncrypter(cookieSecret));
|
||||||
app.use(async (req, res, next) => {
|
app.use(async (req, res, next) => {
|
||||||
if (!ssbServer) {
|
if (!ssbServer) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -93,7 +103,7 @@ app.use(async (req, res, next) => {
|
||||||
res.locals.context = req.context;
|
res.locals.context = req.context;
|
||||||
try {
|
try {
|
||||||
const identities = await ssbServer.identities.list();
|
const identities = await ssbServer.identities.list();
|
||||||
const key = req.cookies["ssb_key"];
|
const key = req.signedCookies["ssb_key"];
|
||||||
if (!key) return next();
|
if (!key) return next();
|
||||||
|
|
||||||
const parsedKey = JSON.parse(key);
|
const parsedKey = JSON.parse(key);
|
||||||
|
@ -165,7 +175,7 @@ router.post("/login", async (req, res) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const decodedKey = reconstructKeys(submittedKey);
|
const decodedKey = reconstructKeys(submittedKey);
|
||||||
res.cookie("ssb_key", JSON.stringify(decodedKey));
|
res.cookie("ssb_key", JSON.stringify(decodedKey), cookieOptions);
|
||||||
|
|
||||||
decodedKey.private = "[removed]";
|
decodedKey.private = "[removed]";
|
||||||
debug("Login with key", decodedKey);
|
debug("Login with key", decodedKey);
|
||||||
|
@ -210,7 +220,7 @@ router.post("/signup", async (req, res) => {
|
||||||
|
|
||||||
debug("Created new user with id", profileId);
|
debug("Created new user with id", profileId);
|
||||||
|
|
||||||
res.cookie("ssb_key", JSON.stringify(key));
|
res.cookie("ssb_key", JSON.stringify(key), cookieOptions);
|
||||||
key.private = "[removed]";
|
key.private = "[removed]";
|
||||||
debug("Generated key", key);
|
debug("Generated key", key);
|
||||||
|
|
||||||
|
@ -234,7 +244,7 @@ router.post("/signup", async (req, res) => {
|
||||||
router.get("/keys", (req, res) => {
|
router.get("/keys", (req, res) => {
|
||||||
res.render("keys", {
|
res.render("keys", {
|
||||||
useEmail: process.env.SENDGRID_API_KEY,
|
useEmail: process.env.SENDGRID_API_KEY,
|
||||||
key: req.cookies["ssb_key"],
|
key: req.signedCookies["ssb_key"],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -244,7 +254,7 @@ router.post("/keys/email", async (req, res) => {
|
||||||
|
|
||||||
let html = await ejs.renderFile("views/email_sign_in.ejs", {
|
let html = await ejs.renderFile("views/email_sign_in.ejs", {
|
||||||
origin,
|
origin,
|
||||||
ssb_key: req.cookies["ssb_key"],
|
ssb_key: req.signedCookies["ssb_key"],
|
||||||
});
|
});
|
||||||
|
|
||||||
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
|
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
|
||||||
|
@ -260,7 +270,7 @@ router.post("/keys/email", async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/keys/copy", (req, res) => {
|
router.get("/keys/copy", (req, res) => {
|
||||||
res.render("keys_copy", { key: req.cookies["ssb_key"] });
|
res.render("keys_copy", { key: req.signedCookies["ssb_key"] });
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/keys/download", async (req, res) => {
|
router.get("/keys/download", async (req, res) => {
|
||||||
|
|
|
@ -740,6 +740,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
||||||
},
|
},
|
||||||
|
"cookie-encrypter": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie-encrypter/-/cookie-encrypter-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-T0EPLKs2vwyaJyRIs3oZ3B/52ny3e09KK+JiMf/6orthjFYCPPX+L8ahlYlipUjIf+ZfXvC0RqDCrxqRRFa05A=="
|
||||||
|
},
|
||||||
"cookie-parser": {
|
"cookie-parser": {
|
||||||
"version": "1.4.5",
|
"version": "1.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
"@sendgrid/mail": "^7.0.1",
|
"@sendgrid/mail": "^7.0.1",
|
||||||
"@sentry/node": "^5.15.4",
|
"@sentry/node": "^5.15.4",
|
||||||
"chokidar": "^3.3.1",
|
"chokidar": "^3.3.1",
|
||||||
|
"cookie-encrypter": "^1.0.1",
|
||||||
"cookie-parser": "^1.4.5",
|
"cookie-parser": "^1.4.5",
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"ejs": "^3.0.2",
|
"ejs": "^3.0.2",
|
||||||
|
|
Loading…
Reference in New Issue