Snowflake JDBC Driver client-side encryption key in DEBUG logs
Description
Snowflake, a platform for using artificial intelligence in the context of cloud computing, has a vulnerability in the Snowflake JDBC driver ("Driver") in versions 3.0.13 through 3.23.0 of the driver. When the logging level was set to DEBUG, the Driver would log locally the client-side encryption master key of the target stage during the execution of GET/PUT commands. This key by itself does not grant access to any sensitive data without additional access authorizations, and is not logged server-side by Snowflake. Snowflake fixed the issue in version 3.23.1.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
net.snowflake:snowflake-jdbcMaven | >= 3.0.13, < 3.23.1 | 3.23.1 |
Affected products
1- Range: >= 3.0.13, < 3.23.1
Patches
1ef81582ce2f1SNOW-1660591 Remove sensitive encryption info when logging (#2077)
3 files changed · +49 −2
src/main/java/net/snowflake/client/jdbc/SnowflakeFileTransferAgent.java+3 −1 modified@@ -70,6 +70,7 @@ import net.snowflake.client.log.ArgSupplier; import net.snowflake.client.log.SFLogger; import net.snowflake.client.log.SFLoggerFactory; +import net.snowflake.client.util.SecretDetector; import net.snowflake.common.core.FileCompressionType; import net.snowflake.common.core.RemoteStoreFileEncryptionMaterial; import net.snowflake.common.core.SqlState; @@ -1337,7 +1338,8 @@ private static JsonNode parseCommandInGS(SFStatement statement, String command) } JsonNode jsonNode = (JsonNode) result; - logger.debug("Response: {}", jsonNode.toString()); + + logger.debug("Response: {}", SecretDetector.maskSecrets(jsonNode.toString())); SnowflakeUtil.checkErrorAndThrowException(jsonNode); return jsonNode;
src/main/java/net/snowflake/client/util/SecretDetector.java+23 −1 modified@@ -79,6 +79,9 @@ public class SecretDetector { "(token|assertion content)" + "(['\"\\s:=]+)" + "([a-z0-9=/_\\-+]{8,})", Pattern.CASE_INSENSITIVE); + private static final Pattern ENCRYPTION_MATERIAL_PATTERN = + Pattern.compile("\"encryptionMaterial\"\\s*:\\s*\\{.*?\\}", Pattern.CASE_INSENSITIVE); + // only attempt to find secrets in its leading 100Kb SNOW-30961 private static final int MAX_LENGTH = 100 * 1000; @@ -222,7 +225,9 @@ public static String maskSASToken(String text) { public static String maskSecrets(String text) { return filterAccessTokens( filterConnectionTokens( - filterPassword(filterSASTokens(filterAWSKeys(filterOAuthTokens(text)))))); + filterPassword( + filterSASTokens( + filterAWSKeys(filterOAuthTokens(filterEncryptionMaterial(text))))))); } /** @@ -283,6 +288,23 @@ public static String filterAccessTokens(String message) { return message; } + /** + * Filter encryption material that may be buried inside a JSON string. + * + * @param message the message text which may contain encryption material + * @return Return filtered message + */ + public static String filterEncryptionMaterial(String message) { + Matcher matcher = + ENCRYPTION_MATERIAL_PATTERN.matcher( + message.length() <= MAX_LENGTH ? message : message.substring(0, MAX_LENGTH)); + + if (matcher.find()) { + return matcher.replaceAll("\"encryptionMaterial\" : ****"); + } + return message; + } + public static JSONObject maskJsonObject(JSONObject json) { for (Map.Entry<String, Object> entry : json.entrySet()) { if (entry.getValue() instanceof String) {
src/test/java/net/snowflake/client/util/SecretDetectorTest.java+23 −0 modified@@ -421,4 +421,27 @@ public void testMaskJacksonObject() { "Nested Jackson array node is not masked successfully", maskedNestedArrayStr.equals(SecretDetector.maskJacksonNode(objNode4).toString())); } + + @Test + public void testEncryptionMaterialFilter() throws Exception { + String messageText = + "{\"data\":" + + "{\"autoCompress\":true," + + "\"overwrite\":false," + + "\"clientShowEncryptionParameter\":true," + + "\"encryptionMaterial\":{\"queryStageMasterKey\":\"asdfasdfasdfasdf==\",\"queryId\":\"01b6f5ba-0002-0181-0000-11111111da\",\"smkId\":1111}," + + "\"stageInfo\":{\"locationType\":\"AZURE\", \"region\":\"eastus2\"}"; + + String filteredMessageText = + "{\"data\":" + + "{\"autoCompress\":true," + + "\"overwrite\":false," + + "\"clientShowEncryptionParameter\":true," + + "\"encryptionMaterial\" : ****," + + "\"stageInfo\":{\"locationType\":\"AZURE\", \"region\":\"eastus2\"}"; + + String result = SecretDetector.filterEncryptionMaterial(messageText); + + assertEquals(filteredMessageText, result); + } }
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-q298-375f-5q63ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-27496ghsaADVISORY
- github.com/snowflakedb/snowflake-jdbc/commit/ef81582ce2f1dbc3c8794a696c94f4fe65fad507ghsax_refsource_MISCWEB
- github.com/snowflakedb/snowflake-jdbc/security/advisories/GHSA-q298-375f-5q63ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.