Skip to content

Commit 4fd53cd

Browse files
committed
fix direct access to .fs and .ds indices
1 parent 337f6e1 commit 4fd53cd

File tree

2 files changed

+56
-10
lines changed

2 files changed

+56
-10
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/IndicesPermission.java

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,11 @@ public boolean isPartOfDataStream() {
430430
public boolean checkIndex(Group group) {
431431
final DataStream ds = indexAbstraction == null ? null : indexAbstraction.getParentDataStream();
432432
if (ds != null) {
433-
if (group.checkIndex(ds.getName())) {
433+
boolean isFailureStoreIndex = ds.isFailureStoreIndex(indexAbstraction.getName());
434+
if (isFailureStoreIndex
435+
&& group.checkIndex(IndexNameExpressionResolver.combineSelector(ds.getName(), IndexComponentSelector.FAILURES))) {
436+
return true;
437+
} else if (isFailureStoreIndex == false && group.checkIndex(ds.getName())) {
434438
return true;
435439
}
436440
}
@@ -907,12 +911,9 @@ static String convertToExcludeFailures(String indexPattern) {
907911
assert indexPattern != "*" : "* is a special case and should never exclude failures";
908912
assert indexPattern.endsWith("*") || Automatons.isLuceneRegex(indexPattern)
909913
: "Only patterns with a trailing wildcard " + "or regular expressions should explicitly exclude failures";
910-
// TODO: [Jake] also properly convert `?` and properly escape any characters such as `.` that is valid in index names but have
911-
// special meaning in the regular expression
912914
StringBuilder sb = new StringBuilder();
913915
if (indexPattern.endsWith("*")) {
914-
// using Strings.replace instead of String.replaceAll to avoid regex compilation
915-
String inny = Strings.replace(indexPattern, "*", ".*");
916+
String inny = globToRegex(indexPattern);
916917
return sb.append("/(").append(inny).append(")&~(").append(inny).append("::failures)/").toString();
917918
} else if (Automatons.isLuceneRegex(indexPattern)) {
918919
String inny = indexPattern.substring(1, indexPattern.length() - 1);
@@ -922,6 +923,43 @@ static String convertToExcludeFailures(String indexPattern) {
922923
}
923924
}
924925

926+
private static String globToRegex(String glob) {
927+
StringBuilder sb = new StringBuilder();
928+
for (int i = 0; i < glob.length(); i++) {
929+
char c = glob.charAt(i);
930+
switch (c) {
931+
case '*':
932+
sb.append(".*");
933+
break;
934+
case '?':
935+
sb.append('.');
936+
break;
937+
case '.':
938+
case '(':
939+
case ')':
940+
case '[':
941+
case ']':
942+
case '{':
943+
case '}':
944+
case '\\':
945+
case '\"':
946+
case '|':
947+
case '+':
948+
case '#':
949+
case '@':
950+
case '<':
951+
case '>':
952+
case '~':
953+
sb.append('\\').append(c);
954+
break;
955+
default:
956+
sb.append(c);
957+
break;
958+
}
959+
}
960+
return sb.toString();
961+
}
962+
925963
public IndexPrivilege privilege() {
926964
return privilege;
927965
}

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -875,14 +875,22 @@ static AuthorizedIndices resolveAuthorizedIndicesFromRole(
875875
// TODO: can this be done smarter? I think there are usually more indices/aliases in the cluster then indices defined a roles?
876876
if (includeDataStreams) {
877877
for (IndexAbstraction indexAbstraction : lookup.values()) {
878-
if (predicate.test(indexAbstraction)) {
878+
// the index abstraction here is from cluster state which will never have the ::failure data selector
879+
// the first check is to see if the index/alias/data stream with no selector is authorized
880+
// the second check is to see if the data stream with the ::failures appended to the name is authorized
881+
boolean authorizedForDataAccess = predicate.test(indexAbstraction);
882+
boolean authorizedForFailureAccess = indexAbstraction.getType() == IndexAbstraction.Type.DATA_STREAM
883+
&& predicate.testDataStreamForFailureAccess(indexAbstraction);
884+
if (authorizedForDataAccess || authorizedForFailureAccess) {
879885
indicesAndAliases.add(indexAbstraction.getName());
886+
// add data stream and its backing indices for any authorized data streams
880887
if (indexAbstraction.getType() == IndexAbstraction.Type.DATA_STREAM) {
881-
// add data stream and its backing indices for any authorized data streams
882-
for (Index index : indexAbstraction.getIndices()) {
883-
indicesAndAliases.add(index.getName());
888+
if (authorizedForDataAccess) {
889+
for (Index index : indexAbstraction.getIndices()) {
890+
indicesAndAliases.add(index.getName());
891+
}
884892
}
885-
if (predicate.testDataStreamForFailureAccess(indexAbstraction)) {
893+
if (authorizedForFailureAccess) {
886894
for (Index index : ((DataStream) indexAbstraction).getFailureIndices()) {
887895
indicesAndAliases.add(index.getName());
888896
}

0 commit comments

Comments
 (0)