This is an automated email from the ASF dual-hosted git repository.
jerryshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 37343112c4 [#13218] fix(common): exclude credentials from
OAuth2TokenResponse and SecretsResponse toString (#13221)
37343112c4 is described below
commit 37343112c48759bb058b798723f338ef387cee2a
Author: YangJie <[email protected]>
AuthorDate: Sun Sep 20 05:42:16 2026 -0400
[#13218] fix(common): exclude credentials from OAuth2TokenResponse and
SecretsResponse toString (#13221)
### What changes were proposed in this pull request?
`@ToString.Exclude` is added to the credential fields on
`OAuth2TokenResponse` (`accessToken`/`refreshToken`) and
`SecretsResponse` (the secrets map). Jackson serialization,
`equals`/`hashCode`, and `validate()` are unchanged.
### Why are the changes needed?
Lombok `@ToString` rendered the bearer credentials and the secrets map
in plaintext, so any log statement printing these response objects
leaked secret material.
Fix: #13218
### Does this PR introduce _any_ user-facing change?
Yes, in log output: `toString()` on `OAuth2TokenResponse` and
`SecretsResponse` no longer includes the credential values, so log
statements that print these objects no longer leak them. Jackson
serialization, `equals`/`hashCode`, and `validate()` are unchanged.
### How was this patch tested?
Added `TestSecretBearingResponsesToString`, which pins that `toString()`
on both responses does not contain the credential values; it fails on
the pre-fix tree (plaintext visible) and passes after the fix.
---
.../dto/responses/OAuth2TokenResponse.java | 4 ++
.../gravitino/dto/responses/SecretsResponse.java | 3 ++
.../TestSecretBearingResponsesToString.java | 54 ++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git
a/common/src/main/java/org/apache/gravitino/dto/responses/OAuth2TokenResponse.java
b/common/src/main/java/org/apache/gravitino/dto/responses/OAuth2TokenResponse.java
index 796295e205..5d5eba9de5 100644
---
a/common/src/main/java/org/apache/gravitino/dto/responses/OAuth2TokenResponse.java
+++
b/common/src/main/java/org/apache/gravitino/dto/responses/OAuth2TokenResponse.java
@@ -35,6 +35,9 @@ import org.apache.commons.lang3.StringUtils;
@EqualsAndHashCode(callSuper = true)
@ToString
public class OAuth2TokenResponse extends BaseResponse {
+ // Excluded from toString: these are bearer credentials, and the response
object ending up in
+ // a log line must not leak them.
+ @ToString.Exclude
@JsonProperty("access_token")
private final String accessToken;
@@ -51,6 +54,7 @@ public class OAuth2TokenResponse extends BaseResponse {
@JsonProperty("scope")
private final String scope;
+ @ToString.Exclude
@Nullable
@JsonProperty("refresh_token")
private final String refreshToken;
diff --git
a/common/src/main/java/org/apache/gravitino/dto/responses/SecretsResponse.java
b/common/src/main/java/org/apache/gravitino/dto/responses/SecretsResponse.java
index ebef221da0..a2a31e0322 100644
---
a/common/src/main/java/org/apache/gravitino/dto/responses/SecretsResponse.java
+++
b/common/src/main/java/org/apache/gravitino/dto/responses/SecretsResponse.java
@@ -31,6 +31,9 @@ import lombok.ToString;
@EqualsAndHashCode(callSuper = true)
public class SecretsResponse extends BaseResponse {
+ // Excluded from toString: the map holds secret material, and the response
object ending up in
+ // a log line must not leak it.
+ @ToString.Exclude
@JsonProperty("secrets")
private final Map<String, String> secrets;
diff --git
a/common/src/test/java/org/apache/gravitino/dto/responses/TestSecretBearingResponsesToString.java
b/common/src/test/java/org/apache/gravitino/dto/responses/TestSecretBearingResponsesToString.java
new file mode 100644
index 0000000000..039a7b21ca
--- /dev/null
+++
b/common/src/test/java/org/apache/gravitino/dto/responses/TestSecretBearingResponsesToString.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.dto.responses;
+
+import com.google.common.collect.ImmutableMap;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TestSecretBearingResponsesToString {
+
+ @Test
+ public void testOAuth2TokenResponseDoesNotLeakTokens() {
+ OAuth2TokenResponse response =
+ new OAuth2TokenResponse(
+ "secret-access-token-123",
+ "access_token",
+ "bearer",
+ 3600,
+ "read write",
+ "secret-refresh-token-456");
+
+ // Before the fix, Lombok @ToString rendered the bearer credentials in
plaintext, so logging
+ // the response leaked them.
+
Assertions.assertFalse(response.toString().contains("secret-access-token-123"));
+
Assertions.assertFalse(response.toString().contains("secret-refresh-token-456"));
+ // Non-secret fields stay visible so the string remains useful for
debugging.
+ Assertions.assertTrue(response.toString().contains("3600"));
+ Assertions.assertTrue(response.toString().contains("read write"));
+ }
+
+ @Test
+ public void testSecretsResponseDoesNotLeakSecretValues() {
+ SecretsResponse response =
+ new SecretsResponse(ImmutableMap.of("kms.key",
"super-secret-material"));
+
+
Assertions.assertFalse(response.toString().contains("super-secret-material"));
+ }
+}