From 477ab8d5973645b27abdbc469a9f048c424b7bb0 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Mon, 11 Jul 2022 15:42:40 +1000 Subject: [PATCH] Ensure CreateApiKey always creates a new document (#88413) The OpType of the indexRequest used for creating new API keys does not have its OpType configured. This means it defaults to OpType.INDEX which allows it to replace an existing document. This PR fixes it by explicity set OpType to CREATE so that it always create a new document (or throw error if ID conflict does happen). Since API key ID is time-based random base64 UUID, it is unlikely for this to happen in practice and we are not aware of any related bug report. --- docs/changelog/88413.yaml | 5 +++++ .../elasticsearch/xpack/security/authc/ApiKeyService.java | 2 ++ .../xpack/security/authc/ApiKeyServiceTests.java | 2 ++ 3 files changed, 9 insertions(+) create mode 100644 docs/changelog/88413.yaml diff --git a/docs/changelog/88413.yaml b/docs/changelog/88413.yaml new file mode 100644 index 0000000000000..5b2a172b1ba6e --- /dev/null +++ b/docs/changelog/88413.yaml @@ -0,0 +1,5 @@ +pr: 88413 +summary: Ensure `CreateApiKey` always creates a new document +area: Security +type: bug +issues: [] diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java index 447ff9191ab6f..96b7ad03dc042 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java @@ -304,6 +304,7 @@ private void createApiKeyAndIndexIt( final IndexRequest indexRequest = client.prepareIndex(SECURITY_MAIN_ALIAS) .setSource(builder) .setId(request.getId()) + .setOpType(DocWriteRequest.OpType.CREATE) .setRefreshPolicy(request.getRefreshPolicy()) .request(); final BulkRequest bulkRequest = toSingleItemBulkRequest(indexRequest); @@ -317,6 +318,7 @@ private void createApiKeyAndIndexIt( bulkRequest, TransportSingleItemBulkWriteAction.wrapBulkResponse(ActionListener.wrap(indexResponse -> { assert request.getId().equals(indexResponse.getId()); + assert indexResponse.getResult() == DocWriteResponse.Result.CREATED; final ListenableFuture listenableFuture = new ListenableFuture<>(); listenableFuture.onResponse(new CachedApiKeyHashResult(true, apiKey)); apiKeyAuthCache.put(request.getId(), listenableFuture); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java index 338dea27b9936..c67ce159250bc 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java @@ -206,6 +206,8 @@ public void testCreateApiKeyUsesBulkIndexAction() throws Exception { assertThat(bulkRequest.requests().get(0), instanceOf(IndexRequest.class)); IndexRequest indexRequest = (IndexRequest) bulkRequest.requests().get(0); assertThat(indexRequest.id(), is(createApiKeyRequest.getId())); + // The index request has opType create so that it will *not* override any existing document + assertThat(indexRequest.opType(), is(DocWriteRequest.OpType.CREATE)); bulkActionInvoked.set(true); return null; }).when(client).execute(eq(BulkAction.INSTANCE), any(BulkRequest.class), any());