From 89930453b9509e4016907a9ea75ae870ebbc147d Mon Sep 17 00:00:00 2001 From: Neeraj Joseph Koilparambil Date: Fri, 12 Apr 2024 14:40:57 +0100 Subject: [PATCH] Updates for CVE-2023-51074 and CVE-2023-5072 Updates the org.json.json and com.jayway.jsonpath.json-path libraries which fix CVE-2023-51074 and CVE-2023-5072. Had to make code changes because the json-path library introduced a bug in the updated version which fails a few unit tests in our repo. See this PR to track the issue https://github.com/json-path/JsonPath/pull/871 --- pom.xml | 4 +- .../encryption/FieldLevelEncryption.java | 2 +- .../developer/encryption/JsonParser.java | 14 ++++++- .../developer/encryption/JweEncryption.java | 6 +-- .../developer/encryption/JsonParserTest.java | 42 +++++++++++++++++++ 5 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 src/test/java/com/mastercard/developer/encryption/JsonParserTest.java diff --git a/pom.xml b/pom.xml index 4187cfc..4bb3e0a 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ com.jayway.jsonpath json-path - 2.6.0 + 2.9.0 @@ -148,7 +148,7 @@ org.json json - 20230227 + 20240303 test diff --git a/src/main/java/com/mastercard/developer/encryption/FieldLevelEncryption.java b/src/main/java/com/mastercard/developer/encryption/FieldLevelEncryption.java index d722f20..7717236 100644 --- a/src/main/java/com/mastercard/developer/encryption/FieldLevelEncryption.java +++ b/src/main/java/com/mastercard/developer/encryption/FieldLevelEncryption.java @@ -210,7 +210,7 @@ private static Object readAndDeleteJsonKey(DocumentContext context, String objec } JsonProvider jsonProvider = JsonParser.jsonPathConfig.jsonProvider(); Object value = jsonProvider.getMapValue(object, key); - context.delete(objectPath + "." + key); + JsonParser.deleteIfExists(context, objectPath + "." + key); return value; } } diff --git a/src/main/java/com/mastercard/developer/encryption/JsonParser.java b/src/main/java/com/mastercard/developer/encryption/JsonParser.java index 05a7409..8f5fbf6 100644 --- a/src/main/java/com/mastercard/developer/encryption/JsonParser.java +++ b/src/main/java/com/mastercard/developer/encryption/JsonParser.java @@ -47,7 +47,7 @@ static void addDecryptedDataToPayload(DocumentContext payloadContext, String dec int length = jsonProvider.length(decryptedValueJsonElement); Collection propertyKeys = (0 == length) ? Collections.emptyList() : jsonProvider.getPropertyKeys(decryptedValueJsonElement); for (String key : propertyKeys) { - payloadContext.delete(jsonPathOut + "." + key); + deleteIfExists( payloadContext, jsonPathOut + "." + key); payloadContext.put(jsonPathOut, key, jsonProvider.getMapValue(decryptedValueJsonElement, key)); } } @@ -86,4 +86,16 @@ static Object readJsonObject(DocumentContext context, String jsonPathString) { } return jsonElement; } + + // Upgrading the json-path lib from 2.6.0 to 2.9.0 introduced a bug where when you + // try to delete a non-existent key in a DocumentContext with the SUPPRESS_EXCEPTIONS flag, + // it would throw a ClassCastException. This method is a workaround for the issue. + // Once this issue is fixed this method's usages can be replaced with a simple DocumentContext.delete(path). + // Track the issue here https://github.com/json-path/JsonPath/issues/870 + static void deleteIfExists(DocumentContext context, String jsonPathString){ + Object value = context.read(jsonPathString); + if(value != null){ + context.delete(jsonPathString); + } + } } diff --git a/src/main/java/com/mastercard/developer/encryption/JweEncryption.java b/src/main/java/com/mastercard/developer/encryption/JweEncryption.java index 209ff92..bfb2dfd 100644 --- a/src/main/java/com/mastercard/developer/encryption/JweEncryption.java +++ b/src/main/java/com/mastercard/developer/encryption/JweEncryption.java @@ -92,7 +92,7 @@ private static DocumentContext encryptPayloadPath(DocumentContext payloadContext // Delete data in clear if (!"$".equals(jsonPathIn)) { - payloadContext.delete(jsonPathIn); + JsonParser.deleteIfExists(payloadContext, jsonPathIn); } else { // We can't reuse the same DocumentContext. We have to create a new DocumentContext // with the appropriate internal representation (JSON object). @@ -135,12 +135,12 @@ private static DocumentContext decryptPayloadPath(DocumentContext payloadContext } // Remove the input - payloadContext.delete(jsonPathIn); + JsonParser.deleteIfExists(payloadContext, jsonPathIn); return payloadContext; } private static Object readAndDeleteJsonKey(DocumentContext context, Object object, String key) { - context.delete(key); + JsonParser.deleteIfExists(context, key); return object; } diff --git a/src/test/java/com/mastercard/developer/encryption/JsonParserTest.java b/src/test/java/com/mastercard/developer/encryption/JsonParserTest.java new file mode 100644 index 0000000..ed701b0 --- /dev/null +++ b/src/test/java/com/mastercard/developer/encryption/JsonParserTest.java @@ -0,0 +1,42 @@ +package com.mastercard.developer.encryption; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import org.junit.Test; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; + +public class JsonParserTest { + + @Test + public void testDeleteIfExists_shouldDeleteIfElementExists() { + final String key = "dummyKey"; + JsonObject dummyObject = new JsonObject(); + dummyObject.addProperty(key, "dummyValue"); + + DocumentContext context = JsonPath.parse(new Gson().toJson(dummyObject), JsonParser.jsonPathConfig); + + JsonParser.deleteIfExists(context, key); + + Object value = context.read(key); + + assertNull(value); + } + + @Test + public void testDeleteIfExists_doNothingIfElementDoesNotExist() { + final String key = "dummyKey"; + JsonObject dummyObject = new JsonObject(); + dummyObject.addProperty(key, "dummyValue"); + + DocumentContext context = JsonPath.parse(new Gson().toJson(dummyObject), JsonParser.jsonPathConfig); + + JsonParser.deleteIfExists(context, "keyWhichDoesNotExist"); + + Object value = context.read(key); + assertNotNull(value); + } +}