Skip to content

Commit dda734c

Browse files
authored
[8.18] Handle streaming request body in audit log (elastic#127798) (elastic#127841)
* 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. * Enable incremental bulks in AuditIT
1 parent abced4b commit dda734c

File tree

3 files changed

+32
-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

+32
-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: 24 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.RequestOptions;
1214
import org.elasticsearch.client.Response;
@@ -29,6 +31,7 @@
2931
import org.junit.ClassRule;
3032

3133
import java.io.IOException;
34+
import java.nio.charset.StandardCharsets;
3235
import java.time.Instant;
3336
import java.time.ZonedDateTime;
3437
import java.time.format.DateTimeFormatter;
@@ -39,6 +42,7 @@
3942
import java.util.concurrent.TimeUnit;
4043
import java.util.function.Predicate;
4144

45+
import static org.hamcrest.Matchers.allOf;
4246
import static org.hamcrest.Matchers.containsString;
4347
import static org.hamcrest.Matchers.hasEntry;
4448
import static org.hamcrest.Matchers.hasKey;
@@ -59,6 +63,7 @@ public class AuditIT extends ESRestTestCase {
5963
.setting("xpack.security.audit.enabled", "true")
6064
.setting("xpack.security.audit.logfile.events.include", "[ \"_all\" ]")
6165
.setting("xpack.security.audit.logfile.events.emit_request_body", "true")
66+
.setting("rest.incremental_bulk", "true")
6267
.user("admin_user", "admin-password")
6368
.user(API_USER, "api-password", "superuser", false)
6469
.build();
@@ -105,6 +110,25 @@ public void testFilteringOfRequestBodies() throws Exception {
105110
});
106111
}
107112

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