From 60cb867d47ec9a85bf9b1eb5a7ce41c69d6c18a6 Mon Sep 17 00:00:00 2001 From: jaymode Date: Wed, 3 Aug 2016 11:06:02 -0400 Subject: [PATCH] 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@fc593943c4a0101651c7544c29076509f67b1244 --- .../xpack/security/authz/RoleDescriptor.java | 10 ++++++++-- .../xpack/security/authz/RoleDescriptorTests.java | 13 +++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/RoleDescriptor.java b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/RoleDescriptor.java index 99806c119ea..06aa4edf4a2 100644 --- a/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/RoleDescriptor.java +++ b/elasticsearch/x-pack/security/src/main/java/org/elasticsearch/xpack/security/authz/RoleDescriptor.java @@ -260,8 +260,14 @@ public class RoleDescriptor implements ToXContent { XContentBuilder builder = JsonXContent.contentBuilder(); XContentHelper.copyCurrentStructure(builder.generator(), parser); query = builder.string(); - } else { - query = parser.textOrNull(); + } else if (token == XContentParser.Token.VALUE_STRING){ + 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)) { privileges = readStringArray(roleName, parser, true); diff --git a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/RoleDescriptorTests.java b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/RoleDescriptorTests.java index f2bbba529a7..94734cf77c4 100644 --- a/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/RoleDescriptorTests.java +++ b/elasticsearch/x-pack/security/src/test/java/org/elasticsearch/xpack/security/authz/RoleDescriptorTests.java @@ -96,6 +96,7 @@ public class RoleDescriptorTests extends ESTestCase { 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()); q = "{\"cluster\":[\"a\", \"b\"], \"metadata\":{\"foo\":\"bar\"}}"; rd = RoleDescriptor.parse("test", new BytesArray(q)); @@ -126,4 +127,16 @@ public class RoleDescriptorTests extends ESTestCase { final RoleDescriptor serialized = RoleDescriptor.readFrom(streamInput); 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()); + } }