diff --git a/docs/changelog/127798.yaml b/docs/changelog/127798.yaml new file mode 100644 index 0000000000000..f9f2ceb93b4f1 --- /dev/null +++ b/docs/changelog/127798.yaml @@ -0,0 +1,5 @@ +pr: 127798 +summary: Handle streaming request body in audit log +area: Audit +type: bug +issues: [] diff --git a/x-pack/plugin/security/qa/audit/src/javaRestTest/java/org/elasticsearch/xpack/security/audit/AuditIT.java b/x-pack/plugin/security/qa/audit/src/javaRestTest/java/org/elasticsearch/xpack/security/audit/AuditIT.java index 2c329db5e3b50..9d6e49b63f395 100644 --- a/x-pack/plugin/security/qa/audit/src/javaRestTest/java/org/elasticsearch/xpack/security/audit/AuditIT.java +++ b/x-pack/plugin/security/qa/audit/src/javaRestTest/java/org/elasticsearch/xpack/security/audit/AuditIT.java @@ -7,6 +7,8 @@ package org.elasticsearch.xpack.security.audit; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; import org.elasticsearch.client.Request; import org.elasticsearch.client.Response; import org.elasticsearch.common.bytes.BytesReference; @@ -27,6 +29,7 @@ import org.junit.ClassRule; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.time.Instant; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -37,6 +40,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Predicate; +import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasKey; @@ -103,6 +107,25 @@ public void testFilteringOfRequestBodies() throws Exception { }); } + public void testAuditAuthenticationSuccessForStreamingRequest() throws Exception { + final Request request = new Request("POST", "/testindex/_bulk"); + request.setEntity(new StringEntity(""" + {"index":{}} + {} + """, ContentType.create("application/x-ndjson", StandardCharsets.UTF_8))); + executeAndVerifyAudit( + request, + AuditLevel.AUTHENTICATION_SUCCESS, + event -> assertThat( + event, + allOf( + hasEntry(LoggingAuditTrail.AUTHENTICATION_TYPE_FIELD_NAME, "REALM"), + hasEntry(LoggingAuditTrail.REQUEST_BODY_FIELD_NAME, "Request body had not been received at the time of the audit event") + ) + ) + ); + } + private void executeAndVerifyAudit(Request request, AuditLevel eventType, CheckedConsumer, Exception> assertions) throws Exception { Instant start = Instant.now(); diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditUtil.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditUtil.java index c584945bc3bd2..fde2c2457d952 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditUtil.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditUtil.java @@ -27,6 +27,9 @@ public class AuditUtil { public static String restRequestContent(RestRequest request) { if (request.hasContent()) { + if (request.isStreamedContent()) { + return "Request body had not been received at the time of the audit event"; + } var content = request.content(); try { return XContentHelper.convertToJson(content, false, false, request.getXContentType());