Skip to content

Commit 3a202a8

Browse files
[Security] Multi Index Expression alias wildcard exclusion (#34144)
The Security plugin authorizes actions on indices. Authorization happens on a per index/alias basis. Therefore a request with a Multi Index Expression (containing wildcards) has to be first evaluated in the authorization layer, before the request is handled. For authorization purposes, wildcards in expressions will only be expanded to indices/aliases that are visible by the authenticated user. However, this "constrained" evaluation has to be compatible with the expression evaluation that a cluster without the Security plugin would do. Therefore any change in the evaluation logic in any of these sites has to be mirrored in the other site. This commit mirrors the changes in core from #33518 that allowed for Multi Index Expression in the Get Alias API, loosely speaking.
1 parent 05b5618 commit 3a202a8

File tree

2 files changed

+85
-64
lines changed

2 files changed

+85
-64
lines changed

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/IndicesAndAliasesResolver.java

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -275,26 +275,36 @@ private List<String> loadAuthorizedAliases(List<String> authorizedIndices, MetaD
275275
}
276276

277277
private List<String> replaceWildcardsWithAuthorizedAliases(String[] aliases, List<String> authorizedAliases) {
278-
List<String> finalAliases = new ArrayList<>();
278+
final List<String> finalAliases = new ArrayList<>();
279279

280-
//IndicesAliasesRequest doesn't support empty aliases (validation fails) but GetAliasesRequest does (in which case empty means _all)
281-
boolean matchAllAliases = aliases.length == 0;
282-
if (matchAllAliases) {
280+
// IndicesAliasesRequest doesn't support empty aliases (validation fails) but
281+
// GetAliasesRequest does (in which case empty means _all)
282+
if (aliases.length == 0) {
283283
finalAliases.addAll(authorizedAliases);
284284
}
285285

286-
for (String aliasPattern : aliases) {
287-
if (aliasPattern.equals(MetaData.ALL)) {
288-
matchAllAliases = true;
289-
finalAliases.addAll(authorizedAliases);
290-
} else if (Regex.isSimpleMatchPattern(aliasPattern)) {
291-
for (String authorizedAlias : authorizedAliases) {
292-
if (Regex.simpleMatch(aliasPattern, authorizedAlias)) {
293-
finalAliases.add(authorizedAlias);
286+
for (String aliasExpression : aliases) {
287+
boolean include = true;
288+
if (aliasExpression.charAt(0) == '-') {
289+
include = false;
290+
aliasExpression = aliasExpression.substring(1);
291+
}
292+
if (MetaData.ALL.equals(aliasExpression) || Regex.isSimpleMatchPattern(aliasExpression)) {
293+
final Set<String> resolvedAliases = new HashSet<>();
294+
for (final String authorizedAlias : authorizedAliases) {
295+
if (MetaData.ALL.equals(aliasExpression) || Regex.simpleMatch(aliasExpression, authorizedAlias)) {
296+
resolvedAliases.add(authorizedAlias);
294297
}
295298
}
299+
if (include) {
300+
finalAliases.addAll(resolvedAliases);
301+
} else {
302+
finalAliases.removeAll(resolvedAliases);
303+
}
304+
} else if (include) {
305+
finalAliases.add(aliasExpression);
296306
} else {
297-
finalAliases.add(aliasPattern);
307+
finalAliases.remove(aliasExpression);
298308
}
299309
}
300310

@@ -304,9 +314,10 @@ private List<String> replaceWildcardsWithAuthorizedAliases(String[] aliases, Lis
304314
//a special expression to replace empty set with, which gives us the guarantee that nothing will be returned.
305315
//This is because existing aliases can contain all kinds of special characters, they are only validated since 5.1.
306316
if (finalAliases.isEmpty()) {
307-
String indexName = matchAllAliases ? MetaData.ALL : Arrays.toString(aliases);
317+
String indexName = aliases.length == 0 ? MetaData.ALL : Arrays.toString(aliases);
308318
throw new IndexNotFoundException(indexName);
309319
}
320+
310321
return finalAliases;
311322
}
312323

0 commit comments

Comments
 (0)