This is an automated email from the ASF dual-hosted git repository.

ramackri pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new b4fd13c20 RANGER-5716: Fix swapped client IP and resource in KMS 
Ranger audits (#1118)
b4fd13c20 is described below

commit b4fd13c20be154e7fc0b1377f16ea5b5c1327e12
Author: Ramachandran Krishnan <[email protected]>
AuthorDate: Fri Jul 31 07:39:14 2026 +0530

    RANGER-5716: Fix swapped client IP and resource in KMS Ranger audits (#1118)
    
    Pass the HTTP client address and key name to the correct assertAccess
    overload for invalidate cache and reencrypt operations so Ranger audit
    records show the real client IP and key resource instead of swapping them.
    
    Co-authored-by: ramk <[email protected]>
---
 .../apache/hadoop/crypto/key/kms/server/KMS.java   | 48 ++++++++++++----------
 .../hadoop/crypto/key/kms/server/TestKMS.java      |  9 +++-
 2 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMS.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMS.java
index 49ff02fcd..424e89aa7 100644
--- a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMS.java
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMS.java
@@ -111,7 +111,7 @@ public Response createKey(Map jsonKey, @Context 
HttpServletRequest request) thro
 
             validateKeyName(name);
 
-            assertAccess(Type.CREATE, user, KMSOp.CREATE_KEY, name, 
request.getRemoteAddr());
+            assertAccess(Type.CREATE, user, KMSOp.CREATE_KEY, name, 
getClientIp(request));
 
             final String cipher      = (String) 
jsonKey.get(KMSRESTConstants.CIPHER_FIELD);
             final String material    = (String) 
jsonKey.get(KMSRESTConstants.MATERIAL_FIELD);
@@ -123,7 +123,7 @@ public Response createKey(Map jsonKey, @Context 
HttpServletRequest request) thro
             Map<String, String> attributes = (Map<String, String>) 
jsonKey.get(KMSRESTConstants.ATTRIBUTES_FIELD);
 
             if (material != null) {
-                assertAccess(Type.SET_KEY_MATERIAL, user, KMSOp.CREATE_KEY, 
name, request.getRemoteAddr());
+                assertAccess(Type.SET_KEY_MATERIAL, user, KMSOp.CREATE_KEY, 
name, getClientIp(request));
             }
 
             final KeyProvider.Options options = new 
KeyProvider.Options(KMSWebApp.getConfiguration());
@@ -155,7 +155,7 @@ public Response createKey(Map jsonKey, @Context 
HttpServletRequest request) thro
 
             kmsAudit.ok(user, KMSOp.CREATE_KEY, name, "UserProvidedMaterial:" 
+ (material != null) + " Description:" + description);
 
-            if (!KMSWebApp.getACLs().hasAccess(Type.GET, user, 
request.getRemoteAddr())) {
+            if (!KMSWebApp.getACLs().hasAccess(Type.GET, user, 
getClientIp(request))) {
                 keyVersion = removeKeyMaterial(keyVersion);
             }
 
@@ -199,7 +199,7 @@ public Response deleteKey(@PathParam("name") final String 
name, @Context HttpSer
 
             UserGroupInformation user = HttpUserGroupInformation.get();
 
-            assertAccess(Type.DELETE, user, KMSOp.DELETE_KEY, name, 
request.getRemoteAddr());
+            assertAccess(Type.DELETE, user, KMSOp.DELETE_KEY, name, 
getClientIp(request));
 
             checkNotEmpty(name, "name");
 
@@ -235,14 +235,14 @@ public Response rolloverKey(@PathParam("name") final 
String name, Map jsonMateri
 
             UserGroupInformation user = HttpUserGroupInformation.get();
 
-            assertAccess(Type.ROLLOVER, user, KMSOp.ROLL_NEW_VERSION, name, 
request.getRemoteAddr());
+            assertAccess(Type.ROLLOVER, user, KMSOp.ROLL_NEW_VERSION, name, 
getClientIp(request));
 
             checkNotEmpty(name, "name");
 
             final String material = (String) 
jsonMaterial.get(KMSRESTConstants.MATERIAL_FIELD);
 
             if (material != null) {
-                assertAccess(Type.SET_KEY_MATERIAL, user, 
KMSOp.ROLL_NEW_VERSION, name, request.getRemoteAddr());
+                assertAccess(Type.SET_KEY_MATERIAL, user, 
KMSOp.ROLL_NEW_VERSION, name, getClientIp(request));
             }
 
             KeyVersion keyVersion = 
user.doAs((PrivilegedExceptionAction<KeyVersion>) () -> {
@@ -261,7 +261,7 @@ public Response rolloverKey(@PathParam("name") final String 
name, Map jsonMateri
 
             kmsAudit.ok(user, KMSOp.ROLL_NEW_VERSION, name, 
"UserProvidedMaterial:" + (material != null) + " NewVersion:" + 
keyVersion.getVersionName());
 
-            if (!KMSWebApp.getACLs().hasAccess(Type.GET, user, 
request.getRemoteAddr())) {
+            if (!KMSWebApp.getACLs().hasAccess(Type.GET, user, 
getClientIp(request))) {
                 keyVersion = removeKeyMaterial(keyVersion);
             }
 
@@ -279,7 +279,7 @@ public Response rolloverKey(@PathParam("name") final String 
name, Map jsonMateri
 
     @POST
     @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" + 
KMSRESTConstants.INVALIDATECACHE_RESOURCE)
-    public Response invalidateCache(@PathParam("name") final String name) 
throws Exception {
+    public Response invalidateCache(@PathParam("name") final String name, 
@Context HttpServletRequest request) throws Exception {
         LOG.debug("==> invalidateCache({})", name);
 
         try (APIMetric apiMetric = 
kmsMetricsCollector.createAPIMetric(KMSMetrics.KMSMetric.INVALIDATE_CACHE_COUNT,
 KMSMetrics.KMSMetric.INVALIDATE_CACHE_ELAPSED_TIME)) {
@@ -289,7 +289,7 @@ public Response invalidateCache(@PathParam("name") final 
String name) throws Exc
 
             UserGroupInformation user = HttpUserGroupInformation.get();
 
-            assertAccess(Type.ROLLOVER, user, KMSOp.INVALIDATE_CACHE, name);
+            assertAccess(Type.ROLLOVER, user, KMSOp.INVALIDATE_CACHE, name, 
getClientIp(request));
 
             user.doAs((PrivilegedExceptionAction<Void>) () -> {
                 provider.invalidateCache(name);
@@ -323,7 +323,7 @@ public Response 
getKeysMetadata(@QueryParam(KMSRESTConstants.KEY) List<String> k
             final UserGroupInformation user     = 
HttpUserGroupInformation.get();
             final String[]             keyNames = keyNamesList.toArray(new 
String[0]);
 
-            assertAccess(Type.GET_METADATA, user, KMSOp.GET_KEYS_METADATA, 
request.getRemoteAddr());
+            assertAccess(Type.GET_METADATA, user, KMSOp.GET_KEYS_METADATA, 
getClientIp(request));
 
             KeyProvider.Metadata[] keysMeta = 
user.doAs((PrivilegedExceptionAction<KeyProvider.Metadata[]>) () -> 
provider.getKeysMetadata(keyNames));
             Object                 json     = 
KMSServerJSONUtils.toJSON(keyNames, keysMeta);
@@ -353,7 +353,7 @@ public Response getKeyNames(@Context HttpServletRequest 
request) throws Exceptio
 
             UserGroupInformation user = HttpUserGroupInformation.get();
 
-            assertAccess(Type.GET_KEYS, user, KMSOp.GET_KEYS, 
request.getRemoteAddr());
+            assertAccess(Type.GET_KEYS, user, KMSOp.GET_KEYS, 
getClientIp(request));
 
             List<String> json = 
user.doAs((PrivilegedExceptionAction<List<String>>) provider::getKeys);
 
@@ -398,7 +398,7 @@ public Response getMetadata(@PathParam("name") final String 
name, @Context HttpS
 
             checkNotEmpty(name, "name");
 
-            assertAccess(Type.GET_METADATA, user, KMSOp.GET_METADATA, name, 
request.getRemoteAddr());
+            assertAccess(Type.GET_METADATA, user, KMSOp.GET_METADATA, name, 
getClientIp(request));
 
             KeyProvider.Metadata metadata = 
user.doAs((PrivilegedExceptionAction<KeyProvider.Metadata>) () -> 
provider.getMetadata(name));
             Object               json     = KMSServerJSONUtils.toJSON(name, 
metadata);
@@ -428,7 +428,7 @@ public Response getCurrentVersion(@PathParam("name") final 
String name, @Context
 
             checkNotEmpty(name, "name");
 
-            assertAccess(Type.GET, user, KMSOp.GET_CURRENT_KEY, name, 
request.getRemoteAddr());
+            assertAccess(Type.GET, user, KMSOp.GET_CURRENT_KEY, name, 
getClientIp(request));
 
             KeyVersion keyVersion = 
user.doAs((PrivilegedExceptionAction<KeyVersion>) () -> 
provider.getCurrentKey(name));
             Object     json       = KMSUtil.toJSON(keyVersion);
@@ -458,7 +458,7 @@ public Response getKeyVersion(@PathParam("versionName") 
final String versionName
 
             checkNotEmpty(versionName, "versionName");
 
-            assertAccess(Type.GET, user, KMSOp.GET_KEY_VERSION, 
request.getRemoteAddr());
+            assertAccess(Type.GET, user, KMSOp.GET_KEY_VERSION, 
getClientIp(request));
 
             KeyVersion keyVersion = 
user.doAs((PrivilegedExceptionAction<KeyVersion>) () -> 
provider.getKeyVersion(versionName));
 
@@ -491,7 +491,7 @@ public Response generateDataKey(@PathParam("name") final 
String name, @Context H
 
             EncryptedKeyVersion encryptedKeyVersion = null;
             try (APIMetric apiMetric = 
kmsMetricsCollector.createAPIMetric(KMSMetrics.KMSMetric.EEK_GENERATE_COUNT, 
KMSMetrics.KMSMetric.EEK_GENERATE_ELAPSED_TIME)) {
-                assertAccess(Type.GENERATE_EEK, user, KMSOp.GENERATE_EEK, 
name, request.getRemoteAddr());
+                assertAccess(Type.GENERATE_EEK, user, KMSOp.GENERATE_EEK, 
name, getClientIp(request));
 
                 encryptedKeyVersion = 
user.doAs((PrivilegedExceptionAction<EncryptedKeyVersion>) () -> 
provider.generateEncryptedKey(name));
                 kmsAudit.ok(user, KMSOp.GENERATE_EEK, name, "generateDataKey 
execution");
@@ -499,7 +499,7 @@ public Response generateDataKey(@PathParam("name") final 
String name, @Context H
 
             KeyVersion retKeyVersion = null;
             try (APIMetric apiMetric = 
kmsMetricsCollector.createAPIMetric(KMSMetrics.KMSMetric.EEK_DECRYPT_COUNT, 
KMSMetrics.KMSMetric.EEK_DECRYPT_ELAPSED_TIME)) {
-                assertAccess(Type.DECRYPT_EEK, user, KMSOp.DECRYPT_EEK, name, 
request.getRemoteAddr());
+                assertAccess(Type.DECRYPT_EEK, user, KMSOp.DECRYPT_EEK, name, 
getClientIp(request));
 
                 EncryptedKeyVersion finalEncryptedKeyVersion = 
encryptedKeyVersion;
                 retKeyVersion = 
user.doAs((PrivilegedExceptionAction<KeyVersion>) () -> {
@@ -547,7 +547,7 @@ public Response generateEncryptedKeys(@PathParam("name") 
final String name, @Que
             if (edekOp.equals(KMSRESTConstants.EEK_GENERATE)) {
                 final List<EncryptedKeyVersion> retEdeks = new LinkedList<>();
 
-                assertAccess(Type.GENERATE_EEK, user, KMSOp.GENERATE_EEK, 
name, request.getRemoteAddr());
+                assertAccess(Type.GENERATE_EEK, user, KMSOp.GENERATE_EEK, 
name, getClientIp(request));
                 try {
                     user.doAs((PrivilegedExceptionAction<Void>) () -> {
                         for (int i = 0; i < numKeys; i++) {
@@ -599,7 +599,7 @@ public Response generateEncryptedKeys(@PathParam("name") 
final String name, @Que
     @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" + 
KMSRESTConstants.REENCRYPT_BATCH_SUB_RESOURCE)
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    public Response reencryptEncryptedKeys(@PathParam("name") final String 
name, final List<Map> jsonPayload) throws Exception {
+    public Response reencryptEncryptedKeys(@PathParam("name") final String 
name, final List<Map> jsonPayload, @Context HttpServletRequest request) throws 
Exception {
         LOG.debug("==> reencryptEncryptedKeys(name={}, count={})", name, 
(jsonPayload != null ? jsonPayload.size() : 0));
 
         final Stopwatch sw = Stopwatch.createStarted();
@@ -616,7 +616,7 @@ public Response reencryptEncryptedKeys(@PathParam("name") 
final String name, fin
                 LOG.warn("Payload size {} too big for reencryptEncryptedKeys 
from" + " user {}.", jsonPayload.size(), user);
             }
 
-            assertAccess(Type.GENERATE_EEK, user, KMSOp.REENCRYPT_EEK_BATCH, 
name);
+            assertAccess(Type.GENERATE_EEK, user, KMSOp.REENCRYPT_EEK_BATCH, 
name, getClientIp(request));
 
             final List<EncryptedKeyVersion> ekvs = 
KMSUtil.parseJSONEncKeyVersions(name, jsonPayload);
 
@@ -685,7 +685,7 @@ public Response 
handleEncryptedKeyOp(@PathParam("versionName") final String vers
                 KMSWebApp.getDecryptEEKCallsMeter().mark();
                 apiMetric.setMetrics(KMSMetrics.KMSMetric.EEK_DECRYPT_COUNT, 
KMSMetrics.KMSMetric.EEK_DECRYPT_ELAPSED_TIME);
 
-                assertAccess(Type.DECRYPT_EEK, user, KMSOp.DECRYPT_EEK, 
keyName, request.getRemoteAddr());
+                assertAccess(Type.DECRYPT_EEK, user, KMSOp.DECRYPT_EEK, 
keyName, getClientIp(request));
 
                 KeyVersion retKeyVersion = 
user.doAs((PrivilegedExceptionAction<KeyVersion>) () -> {
                     KMSEncryptedKeyVersion ekv = new 
KMSEncryptedKeyVersion(keyName, versionName, iv, 
KeyProviderCryptoExtension.EEK, encMaterial);
@@ -700,7 +700,7 @@ public Response 
handleEncryptedKeyOp(@PathParam("versionName") final String vers
                 KMSWebApp.getReencryptEEKCallsMeter().mark();
                 apiMetric.setMetrics(KMSMetrics.KMSMetric.EEK_REENCRYPT_COUNT, 
KMSMetrics.KMSMetric.EEK_REENCRYPT_ELAPSED_TIME);
 
-                assertAccess(Type.GENERATE_EEK, user, KMSOp.REENCRYPT_EEK, 
keyName);
+                assertAccess(Type.GENERATE_EEK, user, KMSOp.REENCRYPT_EEK, 
keyName, getClientIp(request));
 
                 EncryptedKeyVersion retEncryptedKeyVersion = 
user.doAs((PrivilegedExceptionAction<EncryptedKeyVersion>) () -> {
                     KMSEncryptedKeyVersion ekv = new 
KMSEncryptedKeyVersion(keyName, versionName, iv, 
KeyProviderCryptoExtension.EEK, encMaterial);
@@ -748,7 +748,7 @@ public Response getKeyVersions(@PathParam("name") final 
String name, @Context Ht
 
             checkNotEmpty(name, "name");
 
-            assertAccess(Type.GET, user, KMSOp.GET_KEY_VERSIONS, name, 
request.getRemoteAddr());
+            assertAccess(Type.GET, user, KMSOp.GET_KEY_VERSIONS, name, 
getClientIp(request));
 
             List<KeyVersion> ret  = 
user.doAs((PrivilegedExceptionAction<List<KeyVersion>>) () -> 
provider.getKeyVersions(name));
             Object           json = KMSServerJSONUtils.toJSON(ret);
@@ -765,6 +765,10 @@ public Response getKeyVersions(@PathParam("name") final 
String name, @Context Ht
         }
     }
 
+    private static String getClientIp(HttpServletRequest request) {
+        return request != null ? request.getRemoteAddr() : null;
+    }
+
     private void assertAccess(Type aclType, UserGroupInformation ugi, KMSOp 
operation, String clientIp) throws AccessControlException {
         KMSWebApp.getACLs().assertAccess(aclType, ugi, operation, null, 
clientIp);
     }
diff --git 
a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java 
b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java
index 65a01e107..ec0cdb804 100644
--- a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java
+++ b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java
@@ -142,10 +142,12 @@ public void testReencryptEncryptedKeys() throws Exception 
{
         Field meterField = KMSWebApp.class.getDeclaredField("adminCallsMeter");
         meterField.setAccessible(true);
         meterField.set(null, dummyMeter);
+        HttpServletRequest request = mock(HttpServletRequest.class);
+        lenient().when(request.getRemoteAddr()).thenReturn("127.0.0.1");
         KMS kms = new KMS();
 
         try {
-            kms.reencryptEncryptedKeys(keyName, jsonPayload);
+            kms.reencryptEncryptedKeys(keyName, jsonPayload, request);
             fail("Expected exception due to missing provider/user context");
         } catch (Exception e) {
             System.out.println("Caught expected exception: " + e.getMessage());
@@ -435,10 +437,13 @@ void testInvalidateCacheWithOnlyInputValues() throws 
Exception {
         meterField.setAccessible(true);
         meterField.set(null, dummyMeter);
 
+        HttpServletRequest request = mock(HttpServletRequest.class);
+        lenient().when(request.getRemoteAddr()).thenReturn("127.0.0.1");
+
         KMS kms = new KMS();
 
         try {
-            kms.invalidateCache(keyName);
+            kms.invalidateCache(keyName, request);
             fail("Expected exception due to missing dependencies 
(provider/user)");
         } catch (Exception e) {
             System.out.println("Expected exception: " + e.getMessage());

Reply via email to