diff --git a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldMaskingTest.java b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldMaskingTest.java index 7f4c5bacf2..a7ce8b0c1d 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldMaskingTest.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldMaskingTest.java @@ -30,6 +30,7 @@ import org.opensearch.security.user.User; import org.opensearch.test.framework.TestSecurityConfig; +import static org.opensearch.security.privileges.dlsfls.FieldMasking.Config.BLAKE2B_LEGACY_DEFAULT; import static org.opensearch.security.util.MockIndexMetadataBuilder.indices; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -141,6 +142,18 @@ public void simple() throws Exception { assertNull(expression.getRegexReplacements()); FieldMasking.FieldMaskingRule.Field field = new FieldMasking.FieldMaskingRule.Field(expression, FieldMasking.Config.DEFAULT); + assertEquals("c042e214a8b49561577445be44c188a8e6274006b36cd0c6fba5312253cf9293", field.apply("foobar")); + } + + @Test + public void simple_legacyDefaultAlgorithm() throws Exception { + FieldMasking.FieldMaskingExpression expression = new FieldMasking.FieldMaskingExpression("field_*"); + FieldMasking.FieldMaskingRule.Field field = new FieldMasking.FieldMaskingRule.Field( + expression, + FieldMasking.Config.fromSettings( + Settings.builder().put("plugins.security.masked_fields.algorithm.default", BLAKE2B_LEGACY_DEFAULT).build() + ) + ); assertEquals("96c8d1da7eb153db858d4f0585120319e17ed1162db9e94bee19fb10b6d19727", field.apply("foobar")); } @@ -260,9 +273,9 @@ public void simple() throws Exception { assertFalse("FieldMasking.FieldMaskingRule should return false for isAllowAll()", rule.isAllowAll()); assertTrue("Rule applies to field field_masked_1", rule.isMasked("field_masked_1")); assertFalse("Rule does not apply to field field_other", rule.isMasked("field_other")); - assertEquals("96c8d1da7eb153db858d4f0585120319e17ed1162db9e94bee19fb10b6d19727", rule.get("field_masked_1").apply("foobar")); + assertEquals("c042e214a8b49561577445be44c188a8e6274006b36cd0c6fba5312253cf9293", rule.get("field_masked_1").apply("foobar")); assertEquals( - new BytesRef("96c8d1da7eb153db858d4f0585120319e17ed1162db9e94bee19fb10b6d19727".getBytes(StandardCharsets.UTF_8)), + new BytesRef("c042e214a8b49561577445be44c188a8e6274006b36cd0c6fba5312253cf9293".getBytes(StandardCharsets.UTF_8)), rule.get("field_masked_1").apply(new BytesRef("foobar".getBytes(StandardCharsets.UTF_8))) ); assertEquals("FM:[field_masked_*]", rule.toString()); @@ -275,7 +288,7 @@ public void keyword() throws Exception { assertTrue("Rule applies to field field_masked_1", rule.isMasked("field_masked")); assertTrue("Rule applies to field field_masked_1.keyword", rule.isMasked("field_masked.keyword")); assertEquals( - "96c8d1da7eb153db858d4f0585120319e17ed1162db9e94bee19fb10b6d19727", + "c042e214a8b49561577445be44c188a8e6274006b36cd0c6fba5312253cf9293", rule.get("field_masked.keyword").apply("foobar") ); } diff --git a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FlsDocumentFilterTest.java b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FlsDocumentFilterTest.java index 2b28d6330e..214a940c54 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FlsDocumentFilterTest.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FlsDocumentFilterTest.java @@ -319,7 +319,7 @@ public void maskSimpleAttribute() throws Exception { String expectedDocument = """ { "a": "x", - "b": "1147ddc9246d856b1ce322f1dc9eeda895b56d545c324510c2eca47a9dcc5d3f", + "b": "4b694e9cb9ce9e0983fbe4c5df2d464949610f074460adc76bda5a9d0bcc38a5", "c": "z" } """; @@ -351,7 +351,7 @@ public void maskObjectAttribute() throws Exception { { "a": "x", "b": { - "b1": "19937da9d0b0fb38c3ce369bed130b647fa547914d675e09a62ba260a6d7811b", + "b1": "f16d01664d4270a4f39cdba8c89ac024380b5f249f0fbec1049497bc745cf30f", "b2": "y2" }, "c": "z" diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index 74f432d715..0802cb856c 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -221,6 +221,7 @@ import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.ENDPOINTS_WITH_PERMISSIONS; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.SECURITY_CONFIG_UPDATE; +import static org.opensearch.security.privileges.dlsfls.FieldMasking.Config.BLAKE2B_LEGACY_DEFAULT; import static org.opensearch.security.setting.DeprecatedSettings.checkForDeprecatedSetting; import static org.opensearch.security.support.ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER; import static org.opensearch.security.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX; @@ -448,7 +449,7 @@ public List run() { try { String maskingAlgorithmDefault = settings.get(ConfigConstants.SECURITY_MASKED_FIELDS_ALGORITHM_DEFAULT); - if (StringUtils.isNotEmpty(maskingAlgorithmDefault)) { + if (StringUtils.isNotEmpty(maskingAlgorithmDefault) && !BLAKE2B_LEGACY_DEFAULT.equalsIgnoreCase(maskingAlgorithmDefault)) { MessageDigest.getInstance(maskingAlgorithmDefault); } } catch (Exception ex) { diff --git a/src/main/java/org/opensearch/security/privileges/dlsfls/FieldMasking.java b/src/main/java/org/opensearch/security/privileges/dlsfls/FieldMasking.java index b0b77375be..b16aa7b616 100644 --- a/src/main/java/org/opensearch/security/privileges/dlsfls/FieldMasking.java +++ b/src/main/java/org/opensearch/security/privileges/dlsfls/FieldMasking.java @@ -235,12 +235,14 @@ public static class Field { private final String hashAlgorithm; private final Salt salt; private final byte[] saltBytes; + private final boolean useLegacyDefaultAlgorithm; Field(FieldMaskingExpression expression, FieldMasking.Config fieldMaskingConfig) { this.expression = expression; this.hashAlgorithm = expression.getAlgoName() != null ? expression.getAlgoName() : StringUtils.isNotEmpty(fieldMaskingConfig.getDefaultHashAlgorithm()) ? fieldMaskingConfig.getDefaultHashAlgorithm() : null; + this.useLegacyDefaultAlgorithm = fieldMaskingConfig.useLegacyDefaultAlgorithm(); this.salt = fieldMaskingConfig.getSalt(); this.saltBytes = this.salt.getSalt16(); } @@ -252,10 +254,12 @@ public WildcardMatcher getPattern() { public byte[] apply(byte[] value) { if (expression.getRegexReplacements() != null) { return applyRegexReplacements(value, expression.getRegexReplacements()); + } else if (this.useLegacyDefaultAlgorithm) { + return blake2bHash(value, true); } else if (this.hashAlgorithm != null) { return customHash(value, this.hashAlgorithm); } else { - return blake2bHash(value); + return blake2bHash(value, false); } } @@ -301,10 +305,13 @@ private byte[] applyRegexReplacements(byte[] value, List