Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make .async-search-* a restricted namespace #50294

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,13 @@ public FieldValue(Object value) {
private static CharacterRunAutomaton buildAutomaton(Object value) {
if (value instanceof String) {
final String str = (String) value;
if (Regex.isSimpleMatchPattern(str) || isLuceneRegex(str)) {
if (Regex.isSimpleMatchPattern(str) || Automatons.isLuceneRegex(str)) {
return new CharacterRunAutomaton(Automatons.patterns(str));
}
}
return null;
}

private static boolean isLuceneRegex(String str) {
return str.length() > 1 && str.charAt(0) == '/' && str.charAt(str.length() - 1) == '/';
}

public Object getValue() {
return value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.xpack.core.security.authz.accesscontrol.IndicesAccessControl;
import org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege;
import org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames;
Expand Down Expand Up @@ -139,7 +140,7 @@ public ResourcePrivilegesMap checkResourcePrivileges(Set<String> checkForIndexPa
final Map<IndicesPermission.Group, Automaton> predicateCache = new HashMap<>();
for (String forIndexPattern : checkForIndexPatterns) {
Automaton checkIndexAutomaton = Automatons.patterns(forIndexPattern);
if (false == allowRestrictedIndices && false == RestrictedIndicesNames.RESTRICTED_NAMES.contains(forIndexPattern)) {
if (false == allowRestrictedIndices && false == isConcreteRestrictedIndex(forIndexPattern)) {
checkIndexAutomaton = Automatons.minusAndMinimize(checkIndexAutomaton, RestrictedIndicesNames.NAMES_AUTOMATON);
}
if (false == Operations.isEmpty(checkIndexAutomaton)) {
Expand Down Expand Up @@ -268,6 +269,13 @@ public Map<String, IndicesAccessControl.IndexAccessControl> authorize(String act
return unmodifiableMap(indexPermissions);
}

private boolean isConcreteRestrictedIndex(String indexPattern) {
if (Regex.isSimpleMatchPattern(indexPattern) || Automatons.isLuceneRegex(indexPattern)) {
return false;
}
return RestrictedIndicesNames.isRestricted(indexPattern);
}

public static class Group {
private final IndexPrivilege privilege;
private final Predicate<String> actionMatcher;
Expand Down Expand Up @@ -316,7 +324,7 @@ private boolean check(String action) {
private boolean check(String action, String index) {
assert index != null;
return check(action) && indexNameMatcher.test(index)
&& (allowRestrictedIndices || (false == RestrictedIndicesNames.RESTRICTED_NAMES.contains(index)));
&& (allowRestrictedIndices || (false == RestrictedIndicesNames.isRestricted(index)));
}

boolean hasQuery() {
Expand Down Expand Up @@ -351,13 +359,13 @@ private static Predicate<String> buildIndexMatcherPredicateForAction(String acti
final Predicate<String> predicate;
if (restrictedIndices.isEmpty()) {
predicate = indexMatcher(ordinaryIndices)
.and(index -> false == RestrictedIndicesNames.RESTRICTED_NAMES.contains(index));
.and(index -> false == RestrictedIndicesNames.isRestricted(index));
} else if (ordinaryIndices.isEmpty()) {
predicate = indexMatcher(restrictedIndices);
} else {
predicate = indexMatcher(restrictedIndices)
.or(indexMatcher(ordinaryIndices)
.and(index -> false == RestrictedIndicesNames.RESTRICTED_NAMES.contains(index)));
.and(index -> false == RestrictedIndicesNames.isRestricted(index)));
}
return predicate;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.xpack.core.security.support.Automatons;

import java.util.Arrays;
import java.util.Collections;
import java.util.Set;

Expand All @@ -21,10 +22,20 @@ public final class RestrictedIndicesNames {
public static final String INTERNAL_SECURITY_TOKENS_INDEX_7 = ".security-tokens-7";
public static final String SECURITY_TOKENS_ALIAS = ".security-tokens";

// public for tests
public static final String ASYNC_SEARCH_PREFIX = ".async-search-";
private static final Automaton ASYNC_SEARCH_AUTOMATON = Automatons.patterns(ASYNC_SEARCH_PREFIX + "*");

// public for tests
public static final Set<String> RESTRICTED_NAMES = Collections.unmodifiableSet(Sets.newHashSet(SECURITY_MAIN_ALIAS,
INTERNAL_SECURITY_MAIN_INDEX_6, INTERNAL_SECURITY_MAIN_INDEX_7, INTERNAL_SECURITY_TOKENS_INDEX_7, SECURITY_TOKENS_ALIAS));

public static final Automaton NAMES_AUTOMATON = Automatons.patterns(RESTRICTED_NAMES);
public static boolean isRestricted(String concreteIndexName) {
return RESTRICTED_NAMES.contains(concreteIndexName) || concreteIndexName.startsWith(ASYNC_SEARCH_PREFIX);
}

public static final Automaton NAMES_AUTOMATON = Automatons.unionAndMinimize(Arrays.asList(Automatons.patterns(RESTRICTED_NAMES),
ASYNC_SEARCH_AUTOMATON));

private RestrictedIndicesNames() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ static Automaton pattern(String pattern) {
}
}

/**
* Is the str a lucene type of pattern
*/
public static boolean isLuceneRegex(String str) {
return str.length() > 1 && str.charAt(0) == '/' && str.charAt(str.length() - 1) == '/';
}

private static Automaton buildAutomaton(String pattern) {
if (pattern.startsWith("/")) { // it's a lucene regexp
if (pattern.length() == 1 || !pattern.endsWith("/")) {
Expand Down
Loading