Skip to content

Commit

Permalink
Change ruleId if it exists (#628)
Browse files Browse the repository at this point in the history
Signed-off-by: Ashish Agrawal <[email protected]>
(cherry picked from commit 03573e9)
  • Loading branch information
lezzago authored and github-actions[bot] committed Oct 4, 2023
1 parent 639b072 commit 263b37b
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,16 @@ private String getRuleCategory(Path folderPath) {
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

0 comments on commit 263b37b

Please sign in to comment.