зеркало из
1
0
Форкнуть 0

adding expiration to Nonce and making cookie secure and httpOnly

This commit is contained in:
Aniello Scotto Di Marco 2024-05-06 14:10:25 -07:00
Родитель d9baeb3ced
Коммит fcf764cc1b
3 изменённых файлов: 44 добавлений и 4 удалений

Просмотреть файл

@ -13,3 +13,28 @@ export function hashStateGuid(guid: string) {
hash.update(guid); hash.update(guid);
return hash.digest("hex"); return hash.digest("hex");
} }
export function newNonceWithExpiration() {
const nonceExpiration = Date.now() + 1000 * 60;
return `${newGuid()}_${nonceExpiration}}`;
}
export function isNonceExpired(nonce: string) {
if (!nonce) {
return true;
}
const expirationString = nonce.split("_")[1];
if (!expirationString) {
return true;
}
const expirationParsed = parseInt(expirationString, 10);
if (isNaN(expirationParsed) || expirationParsed < Date.now()) {
return true;
}
return false;
}

Просмотреть файл

@ -4,7 +4,7 @@ import * as https from "https";
import * as querystring from "querystring"; import * as querystring from "querystring";
import { SWA_CLI_API_URI, SWA_CLI_APP_PROTOCOL } from "../../../core/constants"; import { SWA_CLI_API_URI, SWA_CLI_APP_PROTOCOL } from "../../../core/constants";
import { DEFAULT_CONFIG } from "../../../config"; import { DEFAULT_CONFIG } from "../../../config";
import { hashStateGuid } from "../../../core/utils/auth"; import { hashStateGuid, isNonceExpired } from "../../../core/utils/auth";
const getGithubAuthToken = function (codeValue: string, clientId: string, clientSecret: string) { const getGithubAuthToken = function (codeValue: string, clientId: string, clientSecret: string) {
const data = querystring.stringify({ const data = querystring.stringify({
@ -401,6 +401,16 @@ const httpTrigger = async function (context: Context, request: http.IncomingMess
return; return;
} }
if (isNonceExpired(nonce)) {
context.res = response({
context,
status: 401,
headers: { ["Content-Type"]: "text/plain" },
body: "Login timed out. Please try again.",
});
return;
}
const { clientIdSettingName, clientSecretSettingName } = customAuth?.identityProviders?.[providerName]?.registration || {}; const { clientIdSettingName, clientSecretSettingName } = customAuth?.identityProviders?.[providerName]?.registration || {};
if (!clientIdSettingName) { if (!clientIdSettingName) {
@ -466,7 +476,8 @@ const httpTrigger = async function (context: Context, request: http.IncomingMess
name: "Nonce", name: "Nonce",
value: "deleted", value: "deleted",
path: "/", path: "/",
HttpOnly: false, secure: true,
httpOnly: true,
expires: new Date(1).toUTCString(), expires: new Date(1).toUTCString(),
}, },
{ {
@ -474,6 +485,8 @@ const httpTrigger = async function (context: Context, request: http.IncomingMess
value: clientPrincipal === null ? "deleted" : btoa(JSON.stringify(clientPrincipal)), value: clientPrincipal === null ? "deleted" : btoa(JSON.stringify(clientPrincipal)),
domain: DEFAULT_CONFIG.host, domain: DEFAULT_CONFIG.host,
path: "/", path: "/",
secure: true,
httpOnly: true,
expires: clientPrincipal === null ? new Date(1).toUTCString() : new Date(Date.now() + 1000 * 60 * 60 * 8).toUTCString(), expires: clientPrincipal === null ? new Date(1).toUTCString() : new Date(Date.now() + 1000 * 60 * 60 * 8).toUTCString(),
}, },
], ],

Просмотреть файл

@ -2,7 +2,7 @@ import { response } from "../../../core";
import * as http from "http"; import * as http from "http";
import { SWA_CLI_APP_PROTOCOL } from "../../../core/constants"; import { SWA_CLI_APP_PROTOCOL } from "../../../core/constants";
import { DEFAULT_CONFIG } from "../../../config"; import { DEFAULT_CONFIG } from "../../../config";
import { hashStateGuid, newGuid } from "../../../core/utils/auth"; import { hashStateGuid, newNonceWithExpiration } from "../../../core/utils/auth";
const httpTrigger = async function (context: Context, _request: http.IncomingMessage, customAuth?: SWAConfigFileAuth) { const httpTrigger = async function (context: Context, _request: http.IncomingMessage, customAuth?: SWAConfigFileAuth) {
await Promise.resolve(); await Promise.resolve();
@ -43,7 +43,7 @@ const httpTrigger = async function (context: Context, _request: http.IncomingMes
return; return;
} }
const state = newGuid(); const state = newNonceWithExpiration();
const hashedState = hashStateGuid(state); const hashedState = hashStateGuid(state);
const redirectUri = `${SWA_CLI_APP_PROTOCOL}://${DEFAULT_CONFIG.host}:${DEFAULT_CONFIG.port}`; const redirectUri = `${SWA_CLI_APP_PROTOCOL}://${DEFAULT_CONFIG.host}:${DEFAULT_CONFIG.port}`;
@ -60,6 +60,8 @@ const httpTrigger = async function (context: Context, _request: http.IncomingMes
value: btoa(state), value: btoa(state),
domain: DEFAULT_CONFIG.host, domain: DEFAULT_CONFIG.host,
path: "/", path: "/",
secure: true,
httpOnly: true,
}, },
], ],
status: 302, status: 302,