From 8b23f0ba57768b7a5f4fe050cfa9b5281eee8a73 Mon Sep 17 00:00:00 2001 From: Jamie Magee <jamie.magee@gmail.com> Date: Sat, 11 Mar 2023 21:52:19 -0800 Subject: [PATCH] refactor: safely parse decrypted config (#20879) --- lib/config/decrypt.ts | 14 ++++++++++++-- lib/config/schema.ts | 7 +++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 lib/config/schema.ts diff --git a/lib/config/decrypt.ts b/lib/config/decrypt.ts index 65099de4aa..660965fc38 100644 --- a/lib/config/decrypt.ts +++ b/lib/config/decrypt.ts @@ -6,6 +6,7 @@ import { maskToken } from '../util/mask'; import { regEx } from '../util/regex'; import { addSecretForSanitizing } from '../util/sanitize'; import { GlobalConfig } from './global'; +import { DecryptedObject } from './schema'; import type { RenovateConfig } from './types'; export async function tryDecryptPgp( @@ -92,8 +93,17 @@ export async function tryDecrypt( const decryptedObjStr = await tryDecryptPgp(privateKey, encryptedStr); if (decryptedObjStr) { try { - const decryptedObj = JSON.parse(decryptedObjStr); - const { o: org, r: repo, v: value } = decryptedObj; + const decryptedObj = DecryptedObject.safeParse( + JSON.parse(decryptedObjStr) + ); + // istanbul ignore if + if (!decryptedObj.success) { + const error = new Error('config-validation'); + error.validationError = `Could not parse decrypted config.`; + throw error; + } + + const { o: org, r: repo, v: value } = decryptedObj.data; if (is.nonEmptyString(value)) { if (is.nonEmptyString(org)) { const orgName = org.replace(regEx(/\/$/), ''); // Strip trailing slash diff --git a/lib/config/schema.ts b/lib/config/schema.ts new file mode 100644 index 0000000000..7a2661c369 --- /dev/null +++ b/lib/config/schema.ts @@ -0,0 +1,7 @@ +import { z } from 'zod'; + +export const DecryptedObject = z.object({ + o: z.string().optional(), + r: z.string().optional(), + v: z.string().optional(), +}); -- GitLab