elastic/elasticsearch#3667 Changes to DLS to support preventing requests that use scripts or now() from being cached

Changes to DLS to support preventing requests that use scripts or now() from being cached

Original commit: elastic/x-pack-elasticsearch@b69c2f5ca4
This commit is contained in:
Colin Goodheart-Smithe 2016-10-06 10:24:59 +01:00 committed by GitHub
commit 288f682fee
3 changed files with 15 additions and 12 deletions

View File

@ -159,7 +159,7 @@ public class SecurityIndexSearcherWrapper extends IndexSearcherWrapper {
Optional<QueryBuilder> queryBuilder = queryShardContext.newParseContext(parser).parseInnerQueryBuilder();
if (queryBuilder.isPresent()) {
verifyRoleQuery(queryBuilder.get());
failIfQueryUsesClient(queryBuilder.get(), queryShardContext);
failIfQueryUsesClient(scriptService, queryBuilder.get(), queryShardContext);
ParsedQuery parsedQuery = queryShardContext.toQuery(queryBuilder.get());
filter.add(parsedQuery.query(), SHOULD);
}
@ -388,12 +388,15 @@ public class SecurityIndexSearcherWrapper extends IndexSearcherWrapper {
}
/**
* Fall back validation that verifies that queries during rewrite don't use the client to make
* remote calls. In the case of DLS this can cause a dead lock if DLS is also applied on these remote calls.
* For example in the case of terms query with lookup, this can cause recursive execution of the
* DLS query until the get thread pool has been exhausted: https://github.com/elastic/x-plugins/issues/3145
* Fall back validation that verifies that queries during rewrite don't use
* the client to make remote calls. In the case of DLS this can cause a dead
* lock if DLS is also applied on these remote calls. For example in the
* case of terms query with lookup, this can cause recursive execution of
* the DLS query until the get thread pool has been exhausted:
* https://github.com/elastic/x-plugins/issues/3145
*/
static void failIfQueryUsesClient(QueryBuilder queryBuilder, QueryRewriteContext original) throws IOException {
static void failIfQueryUsesClient(ScriptService scriptService, QueryBuilder queryBuilder, QueryRewriteContext original)
throws IOException {
Client client = new FilterClient(original.getClient()) {
@Override
protected <Request extends ActionRequest<Request>, Response extends ActionResponse,
@ -402,8 +405,8 @@ public class SecurityIndexSearcherWrapper extends IndexSearcherWrapper {
throw new IllegalStateException("role queries are not allowed to execute additional requests");
}
};
QueryRewriteContext copy = new QueryRewriteContext(original.getIndexSettings(), original.getMapperService(),
original.getScriptService(), null, client, original.getIndexReader(), original.getClusterState());
QueryRewriteContext copy = new QueryRewriteContext(original.getIndexSettings(), original.getMapperService(), scriptService, null,
client, original.getIndexReader(), original.getClusterState());
queryBuilder.rewrite(copy);
}
}

View File

@ -31,7 +31,6 @@ import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.query.ParsedQuery;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.TermQueryBuilder;
@ -75,8 +74,9 @@ public class SecurityIndexSearcherWrapperIntegrationTests extends ESTestCase {
IndicesQueriesRegistry indicesQueriesRegistry = mock(IndicesQueriesRegistry.class);
Client client = mock(Client.class);
when(client.settings()).thenReturn(Settings.EMPTY);
final long nowInMillis = randomPositiveLong();
QueryShardContext realQueryShardContext = new QueryShardContext(indexSettings, null, null, mapperService, null,
null, indicesQueriesRegistry, client, null, null);
null, indicesQueriesRegistry, client, null, null, () -> nowInMillis);
QueryShardContext queryShardContext = spy(realQueryShardContext);
QueryParseContext queryParseContext = mock(QueryParseContext.class);
IndexSettings settings = IndexSettingsModule.newIndexSettings("_index", Settings.EMPTY);

View File

@ -813,11 +813,11 @@ public class SecurityIndexSearcherWrapperUnitTests extends ESTestCase {
when(client.settings()).thenReturn(Settings.EMPTY);
QueryRewriteContext context = new QueryRewriteContext(null, mapperService, scriptService, null, client, null, null);
QueryBuilder queryBuilder1 = new TermsQueryBuilder("field", "val1", "val2");
SecurityIndexSearcherWrapper.failIfQueryUsesClient(queryBuilder1, context);
SecurityIndexSearcherWrapper.failIfQueryUsesClient(scriptService, queryBuilder1, context);
QueryBuilder queryBuilder2 = new TermsQueryBuilder("field", new TermsLookup("_index", "_type", "_id", "_path"));
Exception e = expectThrows(IllegalStateException.class,
() -> SecurityIndexSearcherWrapper.failIfQueryUsesClient(queryBuilder2, context));
() -> SecurityIndexSearcherWrapper.failIfQueryUsesClient(scriptService, queryBuilder2, context));
assertThat(e.getMessage(), equalTo("role queries are not allowed to execute additional requests"));
}
}