Allow remote config to set valid origins (#205)
This commit is contained in:
parent
bad6a60d07
commit
d85c96d408
|
@ -6,7 +6,7 @@ export enum Platform {
|
||||||
|
|
||||||
interface ConfigContext {
|
interface ConfigContext {
|
||||||
platform: Platform;
|
platform: Platform;
|
||||||
allowedParentFrameOrigins: RegExp;
|
allowedParentFrameOrigins: string[];
|
||||||
gitSha?: string;
|
gitSha?: string;
|
||||||
proxyPath?: string;
|
proxyPath?: string;
|
||||||
AAD_ENDPOINT: string;
|
AAD_ENDPOINT: string;
|
||||||
|
@ -30,7 +30,12 @@ interface ConfigContext {
|
||||||
// Default configuration
|
// Default configuration
|
||||||
let configContext: Readonly<ConfigContext> = {
|
let configContext: Readonly<ConfigContext> = {
|
||||||
platform: Platform.Portal,
|
platform: Platform.Portal,
|
||||||
allowedParentFrameOrigins: /^https:\/\/portal\.azure\.com$|^https:\/\/portal\.azure\.us$|^https:\/\/portal\.azure\.cn$|^https:\/\/portal\.microsoftazure\.de$|^https:\/\/.+\.portal\.azure\.com$|^https:\/\/.+\.portal\.azure\.us$|^https:\/\/.+\.portal\.azure\.cn$|^https:\/\/.+\.portal\.microsoftazure\.de$|^https:\/\/main\.documentdb\.ext\.azure\.com$|^https:\/\/main\.documentdb\.ext\.microsoftazure\.de$|^https:\/\/main\.documentdb\.ext\.azure\.cn$|^https:\/\/main\.documentdb\.ext\.azure\.us$/,
|
allowedParentFrameOrigins: [
|
||||||
|
`^https:\\/\\/cosmos.azure.(com|cn|us)$`,
|
||||||
|
`^https:\\/\\/[\\.\\w]+.portal.azure.(com|cn|us)$`,
|
||||||
|
`^https:\\/\\/[\\.\\w]+.ext.azure.(com|cn|us)$`,
|
||||||
|
`^https:\\/\\/[\\.\\w]+microsoftazure.de$`
|
||||||
|
],
|
||||||
// Webpack injects this at build time
|
// Webpack injects this at build time
|
||||||
gitSha: process.env.GIT_SHA,
|
gitSha: process.env.GIT_SHA,
|
||||||
hostedExplorerURL: "https://cosmos.azure.com/",
|
hostedExplorerURL: "https://cosmos.azure.com/",
|
||||||
|
@ -73,8 +78,13 @@ export async function initializeConfiguration(): Promise<ConfigContext> {
|
||||||
const response = await fetch("./config.json");
|
const response = await fetch("./config.json");
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
try {
|
try {
|
||||||
const externalConfig = await response.json();
|
const { allowedParentFrameOrigins, ...externalConfig } = await response.json();
|
||||||
Object.assign(configContext, externalConfig);
|
Object.assign(configContext, externalConfig);
|
||||||
|
if (allowedParentFrameOrigins && allowedParentFrameOrigins.length > 0) {
|
||||||
|
updateConfigContext({
|
||||||
|
allowedParentFrameOrigins: [...configContext.allowedParentFrameOrigins, ...allowedParentFrameOrigins]
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Unable to parse json in config file");
|
console.error("Unable to parse json in config file");
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { isInvalidParentFrameOrigin } from "./MessageValidation";
|
||||||
|
|
||||||
|
test.each`
|
||||||
|
domain | expected
|
||||||
|
${"https://cosmos.azure.com"} | ${false}
|
||||||
|
${"https://cosmos.azure.us"} | ${false}
|
||||||
|
${"https://cosmos.azure.cn"} | ${false}
|
||||||
|
${"https://cosmos.microsoftazure.de"} | ${false}
|
||||||
|
${"https://subdomain.portal.azure.com"} | ${false}
|
||||||
|
${"https://subdomain.portal.azure.us"} | ${false}
|
||||||
|
${"https://subdomain.portal.azure.cn"} | ${false}
|
||||||
|
${"https://subdomain.microsoftazure.de"} | ${false}
|
||||||
|
${"https://main.documentdb.ext.azure.com"} | ${false}
|
||||||
|
${"https://main.documentdb.ext.azure.us"} | ${false}
|
||||||
|
${"https://main.documentdb.ext.azure.cn"} | ${false}
|
||||||
|
${"https://main.documentdb.ext.microsoftazure.de"} | ${false}
|
||||||
|
${"https://random.domain"} | ${true}
|
||||||
|
${"https://malicious.cloudapp.azure.com"} | ${true}
|
||||||
|
`("returns $expected when called with $domain", ({ domain, expected }) => {
|
||||||
|
expect(isInvalidParentFrameOrigin({ origin: domain } as MessageEvent)).toBe(expected);
|
||||||
|
});
|
|
@ -4,13 +4,18 @@ export function isInvalidParentFrameOrigin(event: MessageEvent): boolean {
|
||||||
return !isValidOrigin(configContext.allowedParentFrameOrigins, event);
|
return !isValidOrigin(configContext.allowedParentFrameOrigins, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidOrigin(allowedOrigins: RegExp, event: MessageEvent): boolean {
|
function isValidOrigin(allowedOrigins: string[], event: MessageEvent): boolean {
|
||||||
const eventOrigin = (event && event.origin) || "";
|
const eventOrigin = (event && event.origin) || "";
|
||||||
const windowOrigin = (window && window.origin) || "";
|
const windowOrigin = (window && window.origin) || "";
|
||||||
if (eventOrigin === windowOrigin) {
|
if (eventOrigin === windowOrigin) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = allowedOrigins && allowedOrigins.test(eventOrigin);
|
for (const origin of allowedOrigins) {
|
||||||
return result;
|
const result = new RegExp(origin).test(eventOrigin);
|
||||||
|
if (result) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue