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