Skip to content

Commit 2e3e1c9

Browse files
DaveCTurnerjfreden
authored andcommitted
Handle streaming request body in audit log (elastic#127798)
The audit event for a successfully-authenticated REST request occurs when we start to process the request. For APIs that accept a streaming request body this means we have received the request headers, but not its body, at the time of the audit event. Today such requests will fail with a `ClassCastException` if the `emit_request_body` flag is set. This change fixes the handling of streaming requests in the audit log to now report that the request body was not available when writing the audit entry.
1 parent 6e16843 commit 2e3e1c9

File tree

3 files changed

+31
-0
lines changed
  • docs/changelog
  • x-pack/plugin/security
    • qa/audit/src/javaRestTest/java/org/elasticsearch/xpack/security/audit
    • src/main/java/org/elasticsearch/xpack/security/audit

3 files changed

+31
-0
lines changed

docs/changelog/127798.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 127798
2+
summary: Handle streaming request body in audit log
3+
area: Audit
4+
type: bug
5+
issues: []

x-pack/plugin/security/qa/audit/src/javaRestTest/java/org/elasticsearch/xpack/security/audit/AuditIT.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
package org.elasticsearch.xpack.security.audit;
99

10+
import org.apache.http.entity.ContentType;
11+
import org.apache.http.entity.StringEntity;
1012
import org.elasticsearch.client.Request;
1113
import org.elasticsearch.client.Response;
1214
import org.elasticsearch.common.bytes.BytesReference;
@@ -27,6 +29,7 @@
2729
import org.junit.ClassRule;
2830

2931
import java.io.IOException;
32+
import java.nio.charset.StandardCharsets;
3033
import java.time.Instant;
3134
import java.time.ZonedDateTime;
3235
import java.time.format.DateTimeFormatter;
@@ -37,6 +40,7 @@
3740
import java.util.concurrent.TimeUnit;
3841
import java.util.function.Predicate;
3942

43+
import static org.hamcrest.Matchers.allOf;
4044
import static org.hamcrest.Matchers.containsString;
4145
import static org.hamcrest.Matchers.hasEntry;
4246
import static org.hamcrest.Matchers.hasKey;
@@ -103,6 +107,25 @@ public void testFilteringOfRequestBodies() throws Exception {
103107
});
104108
}
105109

110+
public void testAuditAuthenticationSuccessForStreamingRequest() throws Exception {
111+
final Request request = new Request("POST", "/testindex/_bulk");
112+
request.setEntity(new StringEntity("""
113+
{"index":{}}
114+
{}
115+
""", ContentType.create("application/x-ndjson", StandardCharsets.UTF_8)));
116+
executeAndVerifyAudit(
117+
request,
118+
AuditLevel.AUTHENTICATION_SUCCESS,
119+
event -> assertThat(
120+
event,
121+
allOf(
122+
hasEntry(LoggingAuditTrail.AUTHENTICATION_TYPE_FIELD_NAME, "REALM"),
123+
hasEntry(LoggingAuditTrail.REQUEST_BODY_FIELD_NAME, "Request body had not been received at the time of the audit event")
124+
)
125+
)
126+
);
127+
}
128+
106129
private void executeAndVerifyAudit(Request request, AuditLevel eventType, CheckedConsumer<Map<String, Object>, Exception> assertions)
107130
throws Exception {
108131
Instant start = Instant.now();

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/AuditUtil.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ public class AuditUtil {
2727

2828
public static String restRequestContent(RestRequest request) {
2929
if (request.hasContent()) {
30+
if (request.isStreamedContent()) {
31+
return "Request body had not been received at the time of the audit event";
32+
}
3033
var content = request.content();
3134
try {
3235
return XContentHelper.convertToJson(content, false, false, request.getXContentType());

0 commit comments

Comments
 (0)