Skip to content
Draft
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
5 changes: 3 additions & 2 deletions integ-test/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ ext {
'plugins.security.enable_snapshot_restore_privilege' : 'true',
'plugins.security.check_snapshot_restore_write_privileges' : 'true',
'plugins.security.restapi.roles_enabled' : '["all_access", "security_rest_api_access"]',
'plugins.security.system_indices.enabled' : 'true'
'plugins.security.system_indices.enabled' : 'true',
'cluster.pluggable.dataformat' : 'composite'
].forEach { name, value ->
cluster.setting name, value
}
Expand Down Expand Up @@ -502,11 +503,11 @@ testClusters.analyticsEngineSecurityIT {
plugin(getJobSchedulerPlugin())
plugin(getArrowBasePlugin())
plugin(getArrowFlightRpcPlugin())
plugin(getCompositeEnginePlugin())
plugin(getAnalyticsEnginePlugin())
plugin(getAnalyticsBackendLucenePlugin())
plugin(getAnalyticsBackendDatafusionPlugin())
plugin(getParquetDataFormatPlugin())
plugin(getCompositeEnginePlugin())
plugin ":opensearch-sql-plugin"
// Arrow Flight / streaming transport requirements
jvmArgs '--add-opens=java.base/java.nio=ALL-UNNAMED'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,7 @@ private void createCompositeIndex(String index) throws IOException {
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"index.pluggable.dataformat.enabled": true,
"index.pluggable.dataformat": "composite"
"number_of_replicas": 0
}
}
""");
Expand Down Expand Up @@ -393,6 +391,68 @@ public void testPPLQueryWithWildcardIndexPartialAccessDenied() throws IOExceptio
assertEquals(403, e.getResponse().getStatusLine().getStatusCode());
}

// --- Multi-index comma-separated source tests (CVE: authorization bypass) ---

@Test
public void testPPLMultiIndexDeniedWhenSecondIndexUnauthorized() throws IOException {
// ALLOWED_USER has access to TEST_INDEX but NOT FORBIDDEN_INDEX.
// A comma-separated source listing an authorized index first followed by an unauthorized
// index must be denied. Regression: previously only the first index was checked.
ResponseException e =
assertThrows(
ResponseException.class,
() ->
executePPLAsUser(
"source = " + TEST_INDEX + ", " + FORBIDDEN_INDEX + " | fields name, age",
ALLOWED_USER));
assertEquals(403, e.getResponse().getStatusLine().getStatusCode());
}

@Test
public void testPPLMultiIndexDeniedWithBackticksAuthorizedFirst() throws IOException {
// Same bypass vector using backtick-quoted index names.
ResponseException e =
assertThrows(
ResponseException.class,
() ->
executePPLAsUser(
"source = `" + TEST_INDEX + "`, `" + FORBIDDEN_INDEX + "` | fields name, age",
ALLOWED_USER));
assertEquals(403, e.getResponse().getStatusLine().getStatusCode());
}

@Test
public void testPPLMultiIndexDeniedWithUnauthorizedFirst() throws IOException {
// Unauthorized index listed first — should also be denied.
ResponseException e =
assertThrows(
ResponseException.class,
() ->
executePPLAsUser(
"source = " + FORBIDDEN_INDEX + ", " + TEST_INDEX + " | fields name, age",
ALLOWED_USER));
assertEquals(403, e.getResponse().getStatusLine().getStatusCode());
}

@Test
public void testPPLMultiIndexAllowedWhenAllAuthorized() throws IOException {
// ALLOWED_USER has access to TEST_INDEX. TEST_INDEX_2 is also covered by the
// wildcard user's pattern but let's use allowed_user with both permitted indices.
// Use WILDCARD_USER who has "analytics_security*" covering both TEST_INDEX and TEST_INDEX_2.
try {
JSONObject result =
executePPLAsUser(
"source = " + TEST_INDEX + ", " + TEST_INDEX_2 + " | fields name, age",
WILDCARD_USER);
assertTrue("Expected datarows in response", result.has("datarows"));
} catch (ResponseException e) {
assertNotEquals(
"Expected auth to pass (not 403) when all indices are authorized",
403,
e.getResponse().getStatusLine().getStatusCode());
}
}

@Test
public void testSQLQueryAllowedForAuthorizedUser() throws IOException {
try {
Expand Down
Loading