Vulnerability: In Vendure versions 0.1.0-alpha.2 to 1.5.1 are affected by Stored XSS vulnerability, where an attacker having catalog permission can upload a SVG file that contains malicious JavaScript into the “Assets” tab. The uploaded file will affect administrators as well as regular users.
Vulnerability ID: CVE-2022-23065
CWE: CWE-79
Severity score: 2.9
Project: https://github.com/vendure-ecommerce/vendure
Published: 2022-05-02
File: packages/asset-server-plugin/src/plugin.ts
Commit message: fix(asset-server-plugin): Fix svg XSS vulnerability

It was discovered that a malicious SVG file containing javascript could be executed when opening the
source file in a new tab. This is now mitigated by adding a Content Security Policy header
to responses from the AssetServerPlugin.
Commit author: Michael Bromley

Vulnerable version (before fix):
 export class AssetServerPlugin implements NestModule, OnApplicationBootstrap {                     mimeType = (await fromBuffer(file))?.mime || 'application/octet-stream';                 }                 res.contentType(mimeType);                 res.send(file);             } catch (e) {                 const err = new Error('File not found'); export class AssetServerPlugin implements NestModule, OnApplicationBootstrap {                             Logger.debug(`Saved cached asset: ${cachedFileName}`, loggerCtx);                         }                         res.set('Content-Type', `image/${(await image.metadata()).format}`);                         res.send(imageBuffer);                         return;                     } catch (e) {

Fixed version (after fix):
 export class AssetServerPlugin implements NestModule, OnApplicationBootstrap {                     mimeType = (await fromBuffer(file))?.mime || 'application/octet-stream';                 }                 res.contentType(mimeType);                 res.setHeader('content-security-policy', `default-src 'self'`);                 res.send(file);             } catch (e) {                 const err = new Error('File not found'); export class AssetServerPlugin implements NestModule, OnApplicationBootstrap {                             Logger.debug(`Saved cached asset: ${cachedFileName}`, loggerCtx);                         }                         res.set('Content-Type', `image/${(await image.metadata()).format}`);                         res.setHeader('content-security-policy', `default-src 'self'`);                         res.send(imageBuffer);                         return;                     } catch (e) {

Patch:
patch: @@ -212,6 +212,7 @@ export class AssetServerPlugin implements NestModule, OnApplicationBootstrap {
                     mimeType = (await fromBuffer(file))?.mime || 'application/octet-stream';
                 }
                 res.contentType(mimeType);
+                res.setHeader('content-security-policy', `default-src 'self'`);
                 res.send(file);
             } catch (e) {
                 const err = new Error('File not found');
@@ -251,6 +252,7 @@ export class AssetServerPlugin implements NestModule, OnApplicationBootstrap {
                             Logger.debug(`Saved cached asset: ${cachedFileName}`, loggerCtx);
                         }
                         res.set('Content-Type', `image/${(await image.metadata()).format}`);
+                        res.setHeader('content-security-policy', `default-src 'self'`);
                         res.send(imageBuffer);
                         return;
                     } catch (e) {
path: packages/asset-server-plugin/src/plugin.ts