fix: handle unsupported protocols

This commit is contained in:
Mohamed Marrouchi 2024-12-02 16:21:36 +01:00
parent 5c21212a96
commit 2407ce86b9

View File

@ -294,57 +294,64 @@ export default abstract class BaseWebChannelHandler<
res: Response | SocketResponse, res: Response | SocketResponse,
) { ) {
const settings = await this.getSettings<typeof WEB_CHANNEL_NAMESPACE>(); const settings = await this.getSettings<typeof WEB_CHANNEL_NAMESPACE>();
// If we have an origin header...
if (req.headers && req.headers.origin) {
// Get the allowed origins
const origins: string[] = settings.allowed_domains.split(',');
const foundOrigin = origins
.map((origin) => {
try {
return new URL(origin.trim()).origin;
} catch (error) {
this.logger.error(
`Web Channel Handler : Invalid URL in allowed domains: ${origin}`,
error,
);
return null;
}
})
.filter(
(normalizedOrigin): normalizedOrigin is string =>
normalizedOrigin !== null,
)
.some((origin: string) => {
// If we find a whitelisted origin, send the Access-Control-Allow-Origin header
// to greenlight the request.
return origin === req.headers.origin;
});
if (!foundOrigin && !origins.includes('*')) { // Check if we have an origin header...
// For HTTP requests, set the Access-Control-Allow-Origin header to '', which the browser will if (!req.headers?.origin) {
// interpret as, 'no way Jose.' this.logger.debug('Web Channel Handler : No origin ', req.headers);
res.set('Access-Control-Allow-Origin', ''); throw new Error('CORS - No origin provided!');
this.logger.debug( }
'Web Channel Handler : No origin found ',
req.headers.origin, const originUrl = new URL(req.headers.origin);
); const allowedProtocols = new Set(['http:', 'https:']);
throw new Error('CORS - Domain not allowed!'); if (!allowedProtocols.has(originUrl.protocol)) {
} else { throw new Error('CORS - Invalid origin!');
res.set('Access-Control-Allow-Origin', req.headers.origin); }
}
// Determine whether or not to allow cookies to be passed cross-origin // Get the allowed origins
res.set('Access-Control-Allow-Credentials', 'true'); const origins: string[] = settings.allowed_domains.split(',');
// This header lets a server whitelist headers that browsers are allowed to access const foundOrigin = origins
res.set('Access-Control-Expose-Headers', ''); .map((origin) => {
// Handle preflight requests try {
if (req.method == 'OPTIONS') { return new URL(origin.trim()).origin;
res.set('Access-Control-Allow-Methods', 'GET, POST'); } catch (error) {
res.set('Access-Control-Allow-Headers', 'content-type'); this.logger.error(
} `Web Channel Handler : Invalid URL in allowed domains: ${origin}`,
return; error,
);
return null;
}
})
.filter(
(normalizedOrigin): normalizedOrigin is string =>
normalizedOrigin !== null,
)
.some((origin: string) => {
// If we find a whitelisted origin, send the Access-Control-Allow-Origin header
// to greenlight the request.
return origin === originUrl.origin;
});
if (!foundOrigin && !origins.includes('*')) {
// For HTTP requests, set the Access-Control-Allow-Origin header to '', which the browser will
// interpret as, 'no way Jose.'
res.set('Access-Control-Allow-Origin', '');
this.logger.debug(
'Web Channel Handler : No origin found ',
req.headers.origin,
);
throw new Error('CORS - Domain not allowed!');
} else {
res.set('Access-Control-Allow-Origin', originUrl.origin);
}
// Determine whether or not to allow cookies to be passed cross-origin
res.set('Access-Control-Allow-Credentials', 'true');
// This header lets a server whitelist headers that browsers are allowed to access
res.set('Access-Control-Expose-Headers', '');
// Handle preflight requests
if (req.method == 'OPTIONS') {
res.set('Access-Control-Allow-Methods', 'GET, POST');
res.set('Access-Control-Allow-Headers', 'content-type');
} }
this.logger.debug('Web Channel Handler : No origin ', req.headers);
throw new Error('CORS - No origin provided!');
} }
/** /**