Check TooComplex exception for HasPrivileges body (#128870)
The index pattern provided in the body of `_has_privileges` can trigger a `TooComplexToDeterminizeException` which is then bubbled up (badly). This change catches that exception and provides a better message
This commit is contained in:
parent
46e5f1c46f
commit
fb874848ef
|
@ -0,0 +1,5 @@
|
|||
pr: 128870
|
||||
summary: Check `TooComplex` exception for `HasPrivileges` body
|
||||
area: Authorization
|
||||
type: enhancement
|
||||
issues: []
|
|
@ -6,8 +6,11 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.core.security.authz.permission;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.lucene.util.automaton.Automaton;
|
||||
import org.apache.lucene.util.automaton.Operations;
|
||||
import org.apache.lucene.util.automaton.TooComplexToDeterminizeException;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.TransportAutoPutMappingAction;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.TransportPutMappingAction;
|
||||
import org.elasticsearch.action.support.IndexComponentSelector;
|
||||
|
@ -43,8 +46,10 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
|
||||
|
@ -54,6 +59,8 @@ import static java.util.Collections.unmodifiableMap;
|
|||
*/
|
||||
public final class IndicesPermission {
|
||||
|
||||
private final Logger logger = LogManager.getLogger(getClass());
|
||||
|
||||
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(IndicesPermission.class);
|
||||
|
||||
public static final IndicesPermission NONE = new IndicesPermission(new RestrictedIndices(Automatons.EMPTY), Group.EMPTY_ARRAY);
|
||||
|
@ -330,11 +337,23 @@ public final class IndicesPermission {
|
|||
combineIndexGroups && checkForIndexPatterns.stream().anyMatch(Automatons::isLuceneRegex),
|
||||
IndexComponentSelector.FAILURES
|
||||
);
|
||||
for (String forIndexPattern : checkForIndexPatterns) {
|
||||
Automaton checkIndexAutomaton = Automatons.patterns(forIndexPattern);
|
||||
if (false == allowRestrictedIndices && false == isConcreteRestrictedIndex(forIndexPattern)) {
|
||||
checkIndexAutomaton = Automatons.minusAndMinimize(checkIndexAutomaton, restrictedIndices.getAutomaton());
|
||||
}
|
||||
Map<String, Automaton> checkIndexPatterns = checkForIndexPatterns.stream()
|
||||
.collect(Collectors.toMap(Function.identity(), pattern -> {
|
||||
try {
|
||||
Automaton automaton = Automatons.patterns(pattern);
|
||||
if (false == allowRestrictedIndices && false == isConcreteRestrictedIndex(pattern)) {
|
||||
automaton = Automatons.minusAndMinimize(automaton, restrictedIndices.getAutomaton());
|
||||
}
|
||||
return automaton;
|
||||
} catch (TooComplexToDeterminizeException e) {
|
||||
final String text = pattern.length() > 260 ? Strings.cleanTruncate(pattern, 256) + "..." : pattern;
|
||||
logger.info("refusing to check privileges against complex index pattern [{}]", text);
|
||||
throw new IllegalArgumentException("the provided index pattern [" + text + "] is too complex to be evaluated", e);
|
||||
}
|
||||
}));
|
||||
for (var entry : checkIndexPatterns.entrySet()) {
|
||||
final String forIndexPattern = entry.getKey();
|
||||
final Automaton checkIndexAutomaton = entry.getValue();
|
||||
if (false == Operations.isEmpty(checkIndexAutomaton)) {
|
||||
Automaton allowedPrivilegesAutomatonForDataSelector = getIndexPrivilegesAutomaton(
|
||||
indexGroupAutomatonsForDataSelector,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.security.authz.accesscontrol;
|
||||
|
||||
import org.apache.lucene.util.automaton.TooComplexToDeterminizeException;
|
||||
import org.elasticsearch.ElasticsearchSecurityException;
|
||||
import org.elasticsearch.TransportVersion;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.TransportAutoPutMappingAction;
|
||||
|
@ -55,6 +56,7 @@ import static org.elasticsearch.xpack.core.security.test.TestRestrictedIndices.R
|
|||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
@ -1090,6 +1092,23 @@ public class IndicesPermissionTests extends ESTestCase {
|
|||
assertThat(predicate.test(concreteIndexF, IndexComponentSelector.FAILURES), is(true));
|
||||
}
|
||||
|
||||
public void testCheckResourcePrivilegesWithTooComplexAutomaton() {
|
||||
IndicesPermission permission = new IndicesPermission.Builder(RESTRICTED_INDICES).addGroup(
|
||||
IndexPrivilege.ALL,
|
||||
FieldPermissions.DEFAULT,
|
||||
null,
|
||||
false,
|
||||
"my-index"
|
||||
).build();
|
||||
|
||||
var ex = expectThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> permission.checkResourcePrivileges(Set.of("****a*b?c**d**e*f??*g**h???i??*j*k*l*m*n???o*"), false, Set.of("read"), null)
|
||||
);
|
||||
assertThat(ex.getMessage(), containsString("index pattern [****a*b?c**d**e*f??*g**h???i??*j*k*l*m*n???o*]"));
|
||||
assertThat(ex.getCause(), instanceOf(TooComplexToDeterminizeException.class));
|
||||
}
|
||||
|
||||
private static IndexAbstraction concreteIndexAbstraction(String name) {
|
||||
return new IndexAbstraction.ConcreteIndex(
|
||||
IndexMetadata.builder(name).settings(indexSettings(IndexVersion.current(), 1, 0)).build()
|
||||
|
|
Loading…
Reference in New Issue