From e2d40617bac2aab7bd4b12d05c0cc1a3cbdaf54d Mon Sep 17 00:00:00 2001 From: Marat Miribyan Date: Fri, 10 Oct 2025 11:36:36 +0400 Subject: [PATCH 1/3] ECWID-172338 Option and attribute names are masked in logs - removed general name key value pattern from secure patterns, added specific patterns for billingPerson, personInfo, and shippingAddress --- src/main/kotlin/com/ecwid/apiclient/v3/util/SecurePatterns.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/util/SecurePatterns.kt b/src/main/kotlin/com/ecwid/apiclient/v3/util/SecurePatterns.kt index fb4df914..4df54a07 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/util/SecurePatterns.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/util/SecurePatterns.kt @@ -18,7 +18,9 @@ private val GLOBAL_SECURE_PATTERNS = listOf( createKeyValueSecurePattern("postalCode"), createKeyValueSecurePattern("stateOrProvinceCode"), createKeyValueSecurePattern("phone"), - createKeyValueSecurePattern("name"), + createKeyValueSecurePattern("BillingPerson\\([^)]*name"), + createKeyValueSecurePattern("PersonInfo\\([^)]*name"), + createKeyValueSecurePattern("ShippingAddress\\([^)]*name"), createKeyValueSecurePattern("contact"), createKeyValueSecurePattern("note"), createJsonSecurePattern("email"), From 7a01ff6eb9628fd598648d97cb9d43d062dae0fd Mon Sep 17 00:00:00 2001 From: Marat Miribyan Date: Fri, 10 Oct 2025 11:42:49 +0400 Subject: [PATCH 2/3] ECWID-172338 Option and attribute names are masked in logs - added new test for secure pattern with name parametr, changed the previous tests using the createSecurePatterns() method, updated the expected result since the unmaskedLength was modified to the default value of 6 --- .../ecwid/apiclient/v3/MaskUtilsUnitTest.kt | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/MaskUtilsUnitTest.kt b/src/test/kotlin/com/ecwid/apiclient/v3/MaskUtilsUnitTest.kt index a5b6c906..69d5e1c1 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/MaskUtilsUnitTest.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/MaskUtilsUnitTest.kt @@ -1,6 +1,7 @@ package com.ecwid.apiclient.v3 -import com.ecwid.apiclient.v3.util.SecurePattern + +import com.ecwid.apiclient.v3.util.createSecurePatterns import com.ecwid.apiclient.v3.util.maskLogString import com.ecwid.apiclient.v3.util.maskSensitive import org.junit.jupiter.api.Assertions.assertEquals @@ -11,15 +12,11 @@ class MaskUtilsUnitTest { @Test fun testMaskLogKeyValueString() { val logString = - "token=secret_RandomToken0jwOrgYc5sSKBYcvO0DbP; PasswordCredentials(email=test@example.com, password=123456)" - val securePatterns = listOf( - SecurePattern(Regex("token=(?:secret_|public_|)([^;,)]+)"), 6), - SecurePattern(Regex("email=([^;,)]+)"), 4), - SecurePattern(Regex("password=([^;,)]+)"), 2), - ) + "token=secret_RandomToken0jwOrgYc5sSKBYcvO0DbP; PasswordCredentials(email=test@example.com, password=1234567890)" + val securePatterns = createSecurePatterns() val maskedLogString = logString.maskLogString(securePatterns) - val expectedMaskedLogString = "token=secret_Ran***DbP; PasswordCredentials(email=te***om, password=1***6)" + val expectedMaskedLogString = "token=sec***DbP; PasswordCredentials(email=tes***com, password=12***890)" assertEquals(expectedMaskedLogString, maskedLogString) } @@ -27,12 +24,7 @@ class MaskUtilsUnitTest { fun testMaskLogJsonString() { val logString = """{"billingPerson":{"email":"alexis@ecwid.com","firstName":"John","lastName":"Smith","phone":"123467890"}}""" - val securePatterns = listOf( - SecurePattern(Regex(""""email":\s*"([^"]*)""""), 6), - SecurePattern(Regex(""""firstName":\s*"([^"]*)""""), 6), - SecurePattern(Regex(""""lastName":\s*"([^"]*)""""), 6), - SecurePattern(Regex(""""phone":\s*"([^"]*)""""), 6), - ) + val securePatterns = createSecurePatterns() val maskedLogString = logString.maskLogString(securePatterns) val expectedMaskedLogString = @@ -40,6 +32,16 @@ class MaskUtilsUnitTest { assertEquals(expectedMaskedLogString, maskedLogString) } + @Test + fun testMaskLogKeyValueStringWithNameParameter() { + val logString = + "UpdatedProduct(name={unmasked}, attributes=[AttributeValue(name={unmasked})], options=[RadioOption(name={unmasked})], billingPerson=BillingPerson(name={unmasked}), shippingAddresses=[ShippingAddress(name={unmasked}), ShippingAddress(name={unmasked})], personInfo=PersonInfo(name={unmasked}))" + val securePatterns = createSecurePatterns() + val maskedLogString = logString.maskLogString(securePatterns) + val expectedMaskedLogString = "UpdatedProduct(name={unmasked}, attributes=[AttributeValue(name={unmasked})], options=[RadioOption(name={unmasked})], billingPerson=BillingPerson(name={u***ed}), shippingAddresses=[ShippingAddress(name={u***ed}), ShippingAddress(name={u***ed})], personInfo=PersonInfo(name={u***ed}))" + assertEquals(expectedMaskedLogString, maskedLogString) + } + @Test fun testMaskSensitive() { assertEquals("te***ng", "test string".maskSensitive(4)) From 1282f376346b481e0c38e8e15aaad9b39be84df6 Mon Sep 17 00:00:00 2001 From: Marat Miribyan Date: Fri, 10 Oct 2025 16:30:28 +0400 Subject: [PATCH 3/3] ECWID-172338 Option and attribute names are masked in logs - formatting updates --- .../com/ecwid/apiclient/v3/MaskUtilsUnitTest.kt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/MaskUtilsUnitTest.kt b/src/test/kotlin/com/ecwid/apiclient/v3/MaskUtilsUnitTest.kt index 69d5e1c1..9326fc25 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/MaskUtilsUnitTest.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/MaskUtilsUnitTest.kt @@ -35,10 +35,23 @@ class MaskUtilsUnitTest { @Test fun testMaskLogKeyValueStringWithNameParameter() { val logString = - "UpdatedProduct(name={unmasked}, attributes=[AttributeValue(name={unmasked})], options=[RadioOption(name={unmasked})], billingPerson=BillingPerson(name={unmasked}), shippingAddresses=[ShippingAddress(name={unmasked}), ShippingAddress(name={unmasked})], personInfo=PersonInfo(name={unmasked}))" + "UpdatedProduct(name={unmasked}, " + + "attributes=[AttributeValue(name={unmasked})], " + + "options=[RadioOption(name={unmasked})], " + + "billingPerson=BillingPerson(name={unmasked}), " + + "shippingAddresses=[ShippingAddress(name={unmasked}), " + + "ShippingAddress(name={unmasked})], " + + "personInfo=PersonInfo(name={unmasked}))" val securePatterns = createSecurePatterns() val maskedLogString = logString.maskLogString(securePatterns) - val expectedMaskedLogString = "UpdatedProduct(name={unmasked}, attributes=[AttributeValue(name={unmasked})], options=[RadioOption(name={unmasked})], billingPerson=BillingPerson(name={u***ed}), shippingAddresses=[ShippingAddress(name={u***ed}), ShippingAddress(name={u***ed})], personInfo=PersonInfo(name={u***ed}))" + val expectedMaskedLogString = + "UpdatedProduct(name={unmasked}, " + + "attributes=[AttributeValue(name={unmasked})], " + + "options=[RadioOption(name={unmasked})], " + + "billingPerson=BillingPerson(name={u***ed}), " + + "shippingAddresses=[ShippingAddress(name={u***ed}), " + + "ShippingAddress(name={u***ed})], " + + "personInfo=PersonInfo(name={u***ed}))" assertEquals(expectedMaskedLogString, maskedLogString) }