diff --git a/rules/java/third_parties/elasticsearch.yml b/rules/java/third_parties/elasticsearch.yml new file mode 100644 index 000000000..794228794 --- /dev/null +++ b/rules/java/third_parties/elasticsearch.yml @@ -0,0 +1,64 @@ +imports: + - java_shared_lang_datatype + - java_shared_lang_instance +patterns: + - pattern: | + $.index($<_> -> $<_>.index().id().$document($)); + filters: + - variable: ES_CLIENT + values: + - esClient + - variable: OBJECT_WITH_DATATYPES + detection: java_third_parties_elasticsearch_object_with_datatypes + - pattern: | + $.update($<_> -> $<_>.index().id().$upsert($)$<...>); + filters: + - variable: ES_CLIENT + values: + - esClient + - variable: OBJECT_WITH_DATATYPES + detection: java_third_parties_elasticsearch_object_with_datatypes + - pattern: | + $.document($); + filters: + - variable: BUILDER + detection: java_third_parties_elasticsearch_index_request_builder + - variable: OBJECT_WITH_DATATYPES + detection: java_third_parties_elasticsearch_object_with_datatypes +auxiliary: + - id: java_third_parties_elasticsearch_object_with_datatypes + patterns: + - pattern: $<_> $ = new $<_>($<...>$$<...>); + focus: OBJ + filters: + - variable: DATA_TYPE + detection: java_shared_lang_datatype + - id: java_third_parties_elasticsearch_index_request_builder + patterns: + - pattern: $.Builder<$<_>> $ = new $.Builder<>(); + focus: BUILDER + filters: + - variable: INDEX_REQUEST + regex: \A(org\.elasticsearch\.action\.index\.)?IndexRequest\z +languages: + - java +skip_data_types: + - "Unique Identifier" +metadata: + description: Leakage of sensitive data to ElasticSearch + remediation_message: | + ## Description + Leaking sensitive data to third-party data tools is a common cause of data + leaks and can lead to data breaches. This rule looks for instances of + sensitive data sent to Elasticsearch. + + ## Remediations + When sending data to third-party services, ensure all sensitive data is removed. + + ## Resources + - [Elasticsearch docs](https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/index.html) + cwe_id: + - 201 + associated_recipe: Elasticsearch + id: java_third_parties_elasticsearch + documentation_url: https://docs.bearer.com/reference/rules/java_third_parties_elasticsearch diff --git a/tests/java/third_parties/elasticsearch/test.js b/tests/java/third_parties/elasticsearch/test.js new file mode 100644 index 000000000..638329425 --- /dev/null +++ b/tests/java/third_parties/elasticsearch/test.js @@ -0,0 +1,18 @@ +const { + createNewInvoker, + getEnvironment, +} = require("../../../helper.js") +const { ruleId, ruleFile, testBase } = getEnvironment(__dirname) + +describe(ruleId, () => { + const invoke = createNewInvoker(ruleId, ruleFile, testBase) + + test("elasticsearch", () => { + const testCase = "main.java" + + const results = invoke(testCase) + + expect(results.Missing).toEqual([]) + expect(results.Extra).toEqual([]) + }) +}) \ No newline at end of file diff --git a/tests/java/third_parties/elasticsearch/testdata/main.java b/tests/java/third_parties/elasticsearch/testdata/main.java new file mode 100644 index 000000000..2cf890ddd --- /dev/null +++ b/tests/java/third_parties/elasticsearch/testdata/main.java @@ -0,0 +1,59 @@ +// Use bearer:expected java_third_parties_elasticsearch to flag expected findings + +public class Foo { + public void bad(User user) { + // ... + ElasticsearchClient esClient = new ElasticsearchClient(transport); + // bearer:expected java_third_parties_elasticsearch + Customer customer = new Customer("cust-1", user.email, user.name); + + esClient.indices().create(c -> c + .index("customers") + ); + IndexResponse response = esClient.index(i -> i + .index("customers") + .id(customer.getSku()) + .document(customer) + ); + } + + public void bad2(User user) { + // ... + ElasticsearchClient esClient = new ElasticsearchClient(transport); + // bearer:expected java_third_parties_elasticsearch + User esUser = new User("usr-1", user.email, user.name); + + esClient.update(u -> u + .index("users") + .id("usr-1") + .upsert(esUser), + User.class + ); + } + + public void bad3(User user) { + // bearer:expected java_third_parties_elasticsearch + Customer customer = new Customer("cust-1", user.email, user.name); + + IndexRequest.Builder indexReqBuilder = new IndexRequest.Builder<>(); + indexReqBuilder.index("cust-1"); + indexReqBuilder.id(customer.getSku()); + indexReqBuilder.document(customer); + + IndexResponse response = esClient.index(indexReqBuilder.build()); + } + + public void good() { + // ... + ElasticsearchClient esClient = new ElasticsearchClient(transport); + Product product = new Product("prod-1", "item", 256); + + esClient.update(u -> u + .index("products") + .id("prod-1") + .upsert(product), + Product.class + ); + } + +} \ No newline at end of file