Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 2.11] Change ruleId if it exists #636

Merged
merged 1 commit into from
Oct 4, 2023
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,16 @@
private void ingestQueries(Map<String, List<String>> logIndexToRules, WriteRequest.RefreshPolicy refreshPolicy, TimeValue indexTimeout, ActionListener<BulkResponse> listener) throws SigmaError, IOException {
List<Rule> queries = new ArrayList<>();

for (Map.Entry<String, List<String>> logIndexToRule: logIndexToRules.entrySet()) {
Map<String, String> fieldMappings = logTypeService.getRuleFieldMappingsForBuiltinLogType(logIndexToRule.getKey());
// Moving others_cloud to the top so those queries are indexed first and can be overwritten if other categories
// contain the same rules. Tracking issue: https://github.com/opensearch-project/security-analytics/issues/630
List<String> categories = new ArrayList<>(logIndexToRules.keySet());

Check warning on line 276 in src/main/java/org/opensearch/securityanalytics/util/RuleIndices.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/util/RuleIndices.java#L276

Added line #L276 was not covered by tests
if (categories.remove("others_cloud")) {
categories.add(0, "others_cloud");

Check warning on line 278 in src/main/java/org/opensearch/securityanalytics/util/RuleIndices.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/util/RuleIndices.java#L278

Added line #L278 was not covered by tests
}
for (String category: categories) {
Map<String, String> fieldMappings = logTypeService.getRuleFieldMappingsForBuiltinLogType(category);

Check warning on line 281 in src/main/java/org/opensearch/securityanalytics/util/RuleIndices.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/util/RuleIndices.java#L281

Added line #L281 was not covered by tests
final QueryBackend backend = new OSQueryBackend(fieldMappings, true, true);
queries.addAll(getQueries(backend, logIndexToRule.getKey(), logIndexToRule.getValue()));
queries.addAll(getQueries(backend, category, logIndexToRules.get(category)));

Check warning on line 283 in src/main/java/org/opensearch/securityanalytics/util/RuleIndices.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearch/securityanalytics/util/RuleIndices.java#L283

Added line #L283 was not covered by tests
}
loadRules(queries, refreshPolicy, indexTimeout, listener, true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,17 @@
import org.opensearch.securityanalytics.SecurityAnalyticsPlugin;
import org.opensearch.securityanalytics.SecurityAnalyticsRestTestCase;
import org.opensearch.securityanalytics.config.monitors.DetectorMonitorConfig;
import org.opensearch.securityanalytics.logtype.BuiltinLogTypeLoader;
import org.opensearch.securityanalytics.model.Detector;
import org.opensearch.securityanalytics.model.DetectorInput;
import org.opensearch.securityanalytics.model.DetectorRule;
import org.opensearch.securityanalytics.model.Rule;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
Expand Down Expand Up @@ -191,6 +196,57 @@ public void testSearchingPrepackagedRules() throws IOException {
Assert.assertEquals(5, ((Map<String, Object>) ((Map<String, Object>) responseBody.get("hits")).get("total")).get("value"));
}

public void testSearchingForDuplicatedPrepackagedRules() throws IOException {
String gworkspaceRequest = "{\n" +
" \"query\": {\n" +
" \"nested\": {\n" +
" \"path\": \"rule\",\n" +
" \"query\": {\n" +
" \"bool\": {\n" +
" \"must\": [\n" +
" { \"match\": {\"rule.category\": \"gworkspace\"}}\n" +
" ]\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}";

Response gworkSpaceSearchResponse = makeRequest(client(), "POST", String.format(Locale.getDefault(), "%s/_search", SecurityAnalyticsPlugin.RULE_BASE_URI), Collections.singletonMap("pre_packaged", "true"),
new StringEntity(gworkspaceRequest), new BasicHeader("Content-Type", "application/json"));
Assert.assertEquals("Searching rules failed", RestStatus.OK, restStatus(gworkSpaceSearchResponse));

String azureRequest = "{\n" +
" \"query\": {\n" +
" \"nested\": {\n" +
" \"path\": \"rule\",\n" +
" \"query\": {\n" +
" \"bool\": {\n" +
" \"must\": [\n" +
" { \"match\": {\"rule.category\": \"azure\"}}\n" +
" ]\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}";

Response azureSearchResponse = makeRequest(client(), "POST", String.format(Locale.getDefault(), "%s/_search", SecurityAnalyticsPlugin.RULE_BASE_URI), Collections.singletonMap("pre_packaged", "true"),
new StringEntity(azureRequest), new BasicHeader("Content-Type", "application/json"));
Assert.assertEquals("Searching rules failed", RestStatus.OK, restStatus(azureSearchResponse));

ClassLoader classLoader = getClass().getClassLoader();
int gworkspaceFileCount = new File(classLoader.getResource("rules/gworkspace").getFile()).listFiles().length;
int azureFileCount = new File(classLoader.getResource("rules/azure").getFile()).listFiles().length;

// Verify azure and gworkspace categories have the right number of rules even though they
// conflict with others_cloud category
Map<String, Object> gworkspaceResponseBody = asMap(gworkSpaceSearchResponse);
Assert.assertEquals(gworkspaceFileCount, ((Map<String, Object>) ((Map<String, Object>) gworkspaceResponseBody.get("hits")).get("total")).get("value"));
Map<String, Object> azureResponseBody = asMap(azureSearchResponse);
Assert.assertEquals(azureFileCount, ((Map<String, Object>) ((Map<String, Object>) azureResponseBody.get("hits")).get("total")).get("value"));
}

@SuppressWarnings("unchecked")
public void testSearchingPrepackagedRulesByMitreAttackID() throws IOException {
String request = "{\n" +
Expand Down
Loading