From 65e559323371e8235b92e2134d9908d69043fac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Thu, 26 Oct 2023 11:21:53 +0200 Subject: [PATCH] fix(core): Upgrade crypto-js to address CVE-2023-46233 (#7519) [GH Advisory](https://github.com/advisories/GHSA-xwcq-pm8m-c4vf) --- packages/core/jest.config.js | 1 + packages/core/package.json | 2 +- packages/core/src/Cipher.ts | 6 ++++-- packages/core/test/Cipher.test.ts | 30 ++++++++++++++++++++++++++++++ packages/core/test/setup-mocks.ts | 1 + packages/workflow/package.json | 2 +- pnpm-lock.yaml | 18 +++++++++++------- 7 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 packages/core/test/Cipher.test.ts create mode 100644 packages/core/test/setup-mocks.ts diff --git a/packages/core/jest.config.js b/packages/core/jest.config.js index a066fe093cf0f..b23dc2442639a 100644 --- a/packages/core/jest.config.js +++ b/packages/core/jest.config.js @@ -2,4 +2,5 @@ module.exports = { ...require('../../jest.config'), globalSetup: '/test/setup.ts', + setupFilesAfterEnv: ['/test/setup-mocks.ts'], }; diff --git a/packages/core/package.json b/packages/core/package.json index deaf1281b38f2..65580564616ce 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -54,7 +54,7 @@ "axios": "^0.21.1", "concat-stream": "^2.0.0", "cron": "~1.7.2", - "crypto-js": "^4.1.1", + "crypto-js": "^4.2.0", "fast-glob": "^3.2.5", "file-type": "^16.5.4", "flatted": "^3.2.4", diff --git a/packages/core/src/Cipher.ts b/packages/core/src/Cipher.ts index 08af32a26ced7..88e25e00aba5d 100644 --- a/packages/core/src/Cipher.ts +++ b/packages/core/src/Cipher.ts @@ -7,13 +7,15 @@ export class Cipher { constructor(private readonly instanceSettings: InstanceSettings) {} encrypt(data: string | object) { + const { encryptionKey } = this.instanceSettings; return AES.encrypt( typeof data === 'string' ? data : JSON.stringify(data), - this.instanceSettings.encryptionKey, + encryptionKey, ).toString(); } decrypt(data: string) { - return AES.decrypt(data, this.instanceSettings.encryptionKey).toString(enc.Utf8); + const { encryptionKey } = this.instanceSettings; + return AES.decrypt(data, encryptionKey).toString(enc.Utf8); } } diff --git a/packages/core/test/Cipher.test.ts b/packages/core/test/Cipher.test.ts new file mode 100644 index 0000000000000..23e0bf4ab42c9 --- /dev/null +++ b/packages/core/test/Cipher.test.ts @@ -0,0 +1,30 @@ +import Container from 'typedi'; +import { InstanceSettings } from '@/InstanceSettings'; +import { Cipher } from '@/Cipher'; +import { mockInstance } from './utils'; + +describe('Cipher', () => { + mockInstance(InstanceSettings, { encryptionKey: 'test_key' }); + const cipher = Container.get(Cipher); + + describe('encrypt', () => { + it('should encrypt strings', () => { + const encrypted = cipher.encrypt('random-string'); + const decrypted = cipher.decrypt(encrypted); + expect(decrypted).toEqual('random-string'); + }); + + it('should encrypt objects', () => { + const encrypted = cipher.encrypt({ key: 'value' }); + const decrypted = cipher.decrypt(encrypted); + expect(decrypted).toEqual('{"key":"value"}'); + }); + }); + + describe('decrypt', () => { + it('should decrypt string', () => { + const decrypted = cipher.decrypt('U2FsdGVkX194VEoX27o3+y5jUd1JTTmVwkOKjVhB6Jg='); + expect(decrypted).toEqual('random-string'); + }); + }); +}); diff --git a/packages/core/test/setup-mocks.ts b/packages/core/test/setup-mocks.ts new file mode 100644 index 0000000000000..d2c9bc6e645e1 --- /dev/null +++ b/packages/core/test/setup-mocks.ts @@ -0,0 +1 @@ +import 'reflect-metadata'; diff --git a/packages/workflow/package.json b/packages/workflow/package.json index 3c3ada756aa76..249d43d0a697c 100644 --- a/packages/workflow/package.json +++ b/packages/workflow/package.json @@ -51,7 +51,7 @@ "@n8n/tournament": "^1.0.2", "@n8n_io/riot-tmpl": "^4.0.0", "ast-types": "0.15.2", - "crypto-js": "^4.1.1", + "crypto-js": "^4.2.0", "deep-equal": "^2.2.0", "esprima-next": "5.8.4", "form-data": "^4.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 342f6c71df515..d844ae60a9032 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -583,8 +583,8 @@ importers: specifier: ~1.7.2 version: 1.7.2 crypto-js: - specifier: ^4.1.1 - version: 4.1.1 + specifier: ^4.2.0 + version: 4.2.0 fast-glob: specifier: ^3.2.5 version: 3.2.12 @@ -1311,8 +1311,8 @@ importers: specifier: 0.15.2 version: 0.15.2 crypto-js: - specifier: ^4.1.1 - version: 4.1.1 + specifier: ^4.2.0 + version: 4.2.0 deep-equal: specifier: ^2.2.0 version: 2.2.0 @@ -6824,7 +6824,7 @@ packages: ts-dedent: 2.2.0 type-fest: 3.13.1 vue: 3.3.4 - vue-component-type-helpers: 1.8.19 + vue-component-type-helpers: 1.8.21 transitivePeerDependencies: - encoding - supports-color @@ -10544,6 +10544,10 @@ packages: resolution: {integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==} dev: false + /crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + dev: false + /crypto-random-string@2.0.0: resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} engines: {node: '>=8'} @@ -21799,8 +21803,8 @@ packages: vue: 3.3.4 dev: false - /vue-component-type-helpers@1.8.19: - resolution: {integrity: sha512-1OANGSZK4pzHF4uc86usWi+o5Y0zgoDtqWkPg6Am6ot+jHSAmpOah59V/4N82So5xRgivgCxGgK09lBy1XNUfQ==} + /vue-component-type-helpers@1.8.21: + resolution: {integrity: sha512-XL37QbmiqqbKrAFHPxqryMXpNgO0KMKd5bIo7LO9QABPMNEysd8xmYRIjwZhh0t2abveXjAJ//ZcAzwdxp/S3Q==} dev: true /vue-component-type-helpers@1.8.4: