security: ignore empty query value in roles
Users are allowed to create query objects with an empty string value as we do not currently validate the input against a query parser. In this case, we can ignore the empty value when parsing the role. If we pass an empty BytesReference in the role then trying to determine the XContentType will fail in the SecurityIndexSearcherWrapper. Closes elastic/elasticsearch#2997 Original commit: elastic/x-pack-elasticsearch@fc593943c4
This commit is contained in:
parent
196f74984c
commit
60cb867d47
|
@ -260,8 +260,14 @@ public class RoleDescriptor implements ToXContent {
|
||||||
XContentBuilder builder = JsonXContent.contentBuilder();
|
XContentBuilder builder = JsonXContent.contentBuilder();
|
||||||
XContentHelper.copyCurrentStructure(builder.generator(), parser);
|
XContentHelper.copyCurrentStructure(builder.generator(), parser);
|
||||||
query = builder.string();
|
query = builder.string();
|
||||||
} else {
|
} else if (token == XContentParser.Token.VALUE_STRING){
|
||||||
query = parser.textOrNull();
|
final String text = parser.text();
|
||||||
|
if (text.isEmpty() == false) {
|
||||||
|
query = text;
|
||||||
|
}
|
||||||
|
} else if (token != XContentParser.Token.VALUE_NULL) {
|
||||||
|
throw new ElasticsearchParseException("failed to parse indices privileges for role [{}]. expected field [{}] " +
|
||||||
|
"value to be null, a string, or an object, but found [{}] instead", roleName, currentFieldName, token);
|
||||||
}
|
}
|
||||||
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Fields.PRIVILEGES)) {
|
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, Fields.PRIVILEGES)) {
|
||||||
privileges = readStringArray(roleName, parser, true);
|
privileges = readStringArray(roleName, parser, true);
|
||||||
|
|
|
@ -96,6 +96,7 @@ public class RoleDescriptorTests extends ESTestCase {
|
||||||
assertEquals(1, rd.getIndicesPrivileges().length);
|
assertEquals(1, rd.getIndicesPrivileges().length);
|
||||||
assertArrayEquals(new String[] { "idx1", "idx2" }, rd.getIndicesPrivileges()[0].getIndices());
|
assertArrayEquals(new String[] { "idx1", "idx2" }, rd.getIndicesPrivileges()[0].getIndices());
|
||||||
assertArrayEquals(new String[] { "m", "n" }, rd.getRunAs());
|
assertArrayEquals(new String[] { "m", "n" }, rd.getRunAs());
|
||||||
|
assertNull(rd.getIndicesPrivileges()[0].getQuery());
|
||||||
|
|
||||||
q = "{\"cluster\":[\"a\", \"b\"], \"metadata\":{\"foo\":\"bar\"}}";
|
q = "{\"cluster\":[\"a\", \"b\"], \"metadata\":{\"foo\":\"bar\"}}";
|
||||||
rd = RoleDescriptor.parse("test", new BytesArray(q));
|
rd = RoleDescriptor.parse("test", new BytesArray(q));
|
||||||
|
@ -126,4 +127,16 @@ public class RoleDescriptorTests extends ESTestCase {
|
||||||
final RoleDescriptor serialized = RoleDescriptor.readFrom(streamInput);
|
final RoleDescriptor serialized = RoleDescriptor.readFrom(streamInput);
|
||||||
assertEquals(descriptor, serialized);
|
assertEquals(descriptor, serialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testParseEmptyQuery() throws Exception {
|
||||||
|
String json = "{\"cluster\":[\"a\", \"b\"], \"run_as\": [\"m\", \"n\"], \"indices\": [{\"names\": [\"idx1\",\"idx2\"], " +
|
||||||
|
"\"privileges\": [\"p1\", \"p2\"], \"query\": \"\"}]}";
|
||||||
|
RoleDescriptor rd = RoleDescriptor.parse("test", new BytesArray(json));
|
||||||
|
assertEquals("test", rd.getName());
|
||||||
|
assertArrayEquals(new String[] { "a", "b" }, rd.getClusterPrivileges());
|
||||||
|
assertEquals(1, rd.getIndicesPrivileges().length);
|
||||||
|
assertArrayEquals(new String[] { "idx1", "idx2" }, rd.getIndicesPrivileges()[0].getIndices());
|
||||||
|
assertArrayEquals(new String[] { "m", "n" }, rd.getRunAs());
|
||||||
|
assertNull(rd.getIndicesPrivileges()[0].getQuery());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue