Consistently prevent using exclusion prefix on its own#139337
Consistently prevent using exclusion prefix on its own#139337elasticsearchmachine merged 14 commits intoelastic:mainfrom
Conversation
The dash character is used as a prefix to signify index exclusion. It should not be used on its own. For example, an expression like `*,-` should be invalid. However, today this is handled differently depending on whether security is enabled or disabled. When security is enabled, the standalone exclusion char is ignored and the expression is handled as just `*`. But when security is disabled, the expression encounters an IndexNotFoundException. This PR fixes the inconsistency by always throwing IllegalArgumentException.
|
Pinging @elastic/es-security (Team:Security) |
|
Hi @ywangd, I've created a changelog YAML for you. |
🔍 Preview links for changed docs |
ℹ️ Important: Docs version tagging👋 Thanks for updating the docs! Just a friendly reminder that our docs are now cumulative. This means all 9.x versions are documented on the same page and published off of the main branch, instead of creating separate pages for each minor version. We use applies_to tags to mark version-specific features and changes. Expand for a quick overviewWhen to use applies_to tags:✅ At the page level to indicate which products/deployments the content applies to (mandatory) What NOT to do:❌ Don't remove or replace information that applies to an older version 🤔 Need help?
|
| if (localIndexExpression.isEmpty()) { | ||
| throw invalidExpression(false); | ||
| } |
There was a problem hiding this comment.
Currently, an empty expression encounters an IndexOutOfBoundsException because we call localIndexExpression.charAt(0) a few lines below. With security disabled, the error is IndexNotFoundException. I think it's better for them to both throw IllegalArgumentException. Strictly speaking, this change is not about exclusion. But since it's an issue of similar nature, I decide to include it as well.
There was a problem hiding this comment.
Nice, I think this effectively fixes long-standing #45504 👍 Could you add a note to the PR description to close the issue once merged?
There was a problem hiding this comment.
Ah good find. Updated the PR description as well as adding the issue to the changelog.
|
In addition to index exclusion, there is also remote cluster exclusion. Currently, an expression such as |
| final var e = expectThrows(ElasticsearchSecurityException.class, () -> trySearch(expressions).get()); | ||
| assertThat(e.getCause(), instanceOf(IllegalArgumentException.class)); |
There was a problem hiding this comment.
IllegalArgumentException is always wrapped with ElasticsearchSecurityException. I think we could argue whether such wrapping is necessary. But I don't want to go down that path for now. Alternatively, if we want to avoid the wrapping, we could throw either InvalidIndexNameException or IndexNotFoundException instead. Please let me know if you prefer either of these.
There was a problem hiding this comment.
On second thought, I decided to use InvalidIndexNameException which seems more specific for the particular issue. eb9498b
There was a problem hiding this comment.
InvalidIndexNameException makes sense to me
| if (localIndexExpression.isEmpty()) { | ||
| throw invalidExpression(false); | ||
| } |
There was a problem hiding this comment.
Nice, I think this effectively fixes long-standing #45504 👍 Could you add a note to the PR description to close the issue once merged?
| final Set<String> remoteExpressions | ||
| ) { | ||
| if (localIndexExpression.isEmpty()) { | ||
| throw invalidExpression(false); |
There was a problem hiding this comment.
Nit: I'd add invalidExclusion() and invalidExpression() methods to make the call more self-explanatory (as opposed to the raw boolean arg)
| new String[] { "-" }, | ||
| new String[] { "*", "-" }, | ||
| new String[] { "testXXX", "-" }, | ||
| new String[] { "*", "-", "testXXX" } |
There was a problem hiding this comment.
I'd also add:
new String[] { "-", "-" },
new String[] { "-testXXX", "-" },
new String[] { "*", "-testXXX", "-" }| createIndicesWithRandomAliases("test1"); | ||
|
|
||
| final List<String[]> expressionsList = List.of( | ||
| new String[] { "-" }, |
There was a problem hiding this comment.
I'd also add:
new String[] { "_all", "-" }, // interestingly this doesn't work in server/src/test/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolverTests.java since we don't allow `_` at that validation stage
new String[] { "-", "-" },
new String[] { "-testXXX", "-" },
new String[] { "*", "-testXXX", "-" }There was a problem hiding this comment.
I think we should make IndexAbstractionResolver behave the same as IndexNameExpressionResolver for handling _all. It's inconsistent right now. The expression _all is a special match-all only when it is used on its own. Otherwise, it is just a normal name. As a normal name, it is invalid because index cannot begin with _. But with security enabled, an expression like foo*,_all ends up being just _all and expands to match all if foo* matches nothing. But if foo* matches anything, it then encounters InvalidIndexNameException. This is not a sensible behaviour and I think we should instead throw InvalidIndexNameException in both cases.
I added a test for { "_all", "-" } on the core side and assert it throws index name "must. not start with '_'". See 3468c92 along with your suggestion.
| createIndicesWithRandomAliases("test1"); | ||
|
|
||
| final List<String[]> expressionsList = List.of( | ||
| new String[] { "" }, |
There was a problem hiding this comment.
Let's also cover:
new String[] { "", "_all" },| final var e = expectThrows(ElasticsearchSecurityException.class, () -> trySearch(expressions).get()); | ||
| assertThat(e.getCause(), instanceOf(IllegalArgumentException.class)); |
There was a problem hiding this comment.
InvalidIndexNameException makes sense to me
|
Hi @ywangd, I've updated the changelog YAML for you. |
|
Hi @ywangd, I've updated the changelog YAML for you. |
|
CI Failure is irrelevant but reproducible. I raised #139576 |
The dash character is used as a prefix to signify index exclusion. It should not be used on its own. For example, an expression like
*,-should be invalid. However, today this is handled differently depending on whether security is enabled or disabled. When security is enabled, the standalone exclusion char is ignored and the expression is handled as just*. But when security is disabled, the expression encounters an IndexNotFoundException.This PR fixes the inconsistency by always throwing InvalidIndexNameException. In addition, this PR also fixes #45504 by ensuring InvalidIndexNameException is thrown for empty index name instead of IndexOutOfBoundsException.
Resolves: #45504