java.mongodb.security.injection.audit.mongodb-nosqli.mongodb-nosqli

profile photo of semgrepsemgrep
Author
unknown
Download Count*

Detected non-constant data passed into a NoSQL query using the 'where' evaluation operator. If this data can be controlled by an external user, this is a NoSQL injection. Ensure data passed to the NoSQL query is not user controllable, or properly sanitize the data. Ideally, avoid using the 'where' operator at all and instead use the helper methods provided by com.mongodb.client.model.Filters with comparative operators such as eq, ne, lt, gt, etc.

Run Locally

Run in CI

Defintion

rules:
  - id: mongodb-nosqli
    message: Detected non-constant data passed into a NoSQL query using the 'where'
      evaluation operator. If this data can be controlled by an external user,
      this is a NoSQL injection. Ensure data passed to the NoSQL query is not
      user controllable, or properly sanitize the data. Ideally, avoid using the
      'where' operator at all and instead use the helper methods provided by
      com.mongodb.client.model.Filters with comparative operators such as eq,
      ne, lt, gt, etc.
    languages:
      - java
    severity: WARNING
    patterns:
      - pattern-either:
          - pattern: (com.mongodb.BasicDBObject $QUERY).put("$where", $INPUT);
          - pattern: |
              (HashMap<String, String> $MAP).put("$where", $INPUT);
              ...
              (com.mongodb.BasicDBObject $QUERY).putAll($MAP);
          - pattern: (com.mongodb.BasicDBObject $QUERY).append("$where", $INPUT);
          - pattern: new com.mongodb.BasicDBObject("$where", $INPUT);
          - pattern: |
              (HashMap<String, String> $MAP).put("$where", $INPUT);
              ...
              new com.mongodb.BasicDBObject($MAP);
          - pattern: |
              (HashMap<String, String> $MAP).put("$where", $INPUT);
              ...
              String json = new JSONObject($MAP).toString();
              ...
              (com.mongodb.BasicDBObject $QUERY).parse((String $JSON));
          - pattern: com.mongodb.BasicDBObjectBuilder.start().add("$where", $INPUT);
          - pattern: com.mongodb.BasicDBObjectBuilder.start().append("$where", $INPUT);
          - pattern: com.mongodb.BasicDBObjectBuilder.start("$where", $INPUT);
          - pattern: |
              (HashMap<String, String> $MAP).put("$where", $INPUT);
              ...
              com.mongodb.BasicDBObjectBuilder.start($MAP);
      - metavariable-pattern:
          metavariable: $INPUT
          patterns:
            - pattern: |
                ...
            - pattern-not: |
                "..."
    metadata:
      category: security
      technology:
        - nosql
        - mongodb
      cwe:
        - "CWE-943: Improper Neutralization of Special Elements in Data Query
          Logic"
      owasp:
        - A01:2017 - Injection
        - A03:2021 - Injection
      asvs:
        section: "V5: Validation, Sanitization and Encoding Verification Requirements"
        control_id: 5.3.4 Injection Prevention
        control_url: https://github.com/OWASP/ASVS/blob/master/5.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention
        version: "5"
      references:
        - https://owasp.org/Top10/A03_2021-Injection
        - https://www.mongodb.com/docs/manual/tutorial/query-documents/
        - https://www.mongodb.com/docs/manual/reference/operator/query/where/
      subcategory:
        - audit
      likelihood: LOW
      impact: HIGH
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Improper Validation

Examples

mongodb-nosqli.java

package testcode.sqli;

import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;

public class ContactsService {

  private MongoDatabase db = MongoClientUtil.mongoClient.getDatabase("test");
  private MongoCollection<Document> collection = db.getCollection("contacts");

  public InsecureContactsService() {
    }

  public ArrayList<Document> basicDBObjectPut(String userName, String email) {
    BasicDBObject query = new BasicDBObject();
    // ruleid: mongodb-nosqli
    query.put("$where", "this.sharedWith == \"" + userName + "\" && this.email == \"" + email + "\"");

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectPut(String userName, String email) {
    BasicDBObject query = new BasicDBObject();
    // ok: mongodb-nosqli
    query.put("$where", "this.sharedWith == \"CONSTANT\" && this.email == \"CONSTANT\"");

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectPut(String userName, String email) {
    BasicDBObject query = new BasicDBObject();
    // ok: mongodb-nosqli
    query.put("sharedWith", userName);
    query.put("email", email);

    MongoCursor<Document> cursor = collection.find(query).iterator();
    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectPutAll(String userName, String email) {
    BasicDBObject query = new BasicDBObject();
    HashMap<String, String> paramMap = new HashMap<>();
    // ruleid: mongodb-nosqli
    paramMap.put("$where", "this.sharedWith == \"" + userName + "\" && this.email == \"" + email + "\"");
    query.putAll(paramMap);

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectPutAll(String userName, String email) {
    BasicDBObject query = new BasicDBObject();
    HashMap<String, String> paramMap = new HashMap<>();
    // ok: mongodb-nosqli
    paramMap.put("$where", "this.sharedWith == \"CONSTANT\" && this.email == \"CONSTANT\"");
    query.putAll(paramMap);

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectPutAll(String userName, String email) {
    BasicDBObject query = new BasicDBObject();
    HashMap<String, String> paramMap = new HashMap<>();
    // ok: mongodb-nosqli
    paramMap.put("sharedWith", userName);
    paramMap.put("email", email);
    query.putAll(paramMap);

    MongoCursor<Document> cursor = collection.find(query).iterator();
    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectAppend(String userName, String email) {
    BasicDBObject query = new BasicDBObject();
    // ruleid: mongodb-nosqli
    query.append("$where", "this.sharedWith == \"" + userName + "\" && this.email == \"" + email + "\"");

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectAppend(String userName, String email) {
    BasicDBObject query = new BasicDBObject();
    // ok: mongodb-nosqli
    query.append("$where", "this.sharedWith == \"CONSTANT\" && this.email == \"CONSTANT\"");

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectAppend(String userName, String email) {
    BasicDBObject query = new BasicDBObject();
    // ok: mongodb-nosqli
    query.append("sharedWith", userName);
    query.append("email", email);

    MongoCursor<Document> cursor = collection.find(query).iterator();
    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectConstructorKv(String userName, String email) {
    // ruleid: mongodb-nosqli
    BasicDBObject query = new BasicDBObject("$where",
        "this.sharedWith == \"" + userName + "\" && this.email == \"" + email + "\"");

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectConstructorKv(String userName, String email) {
    // ok: mongodb-nosqli
    BasicDBObject query = new BasicDBObject("$where", "this.sharedWith == \"CONSTANT\" && this.email == \"CONSTANT\"");

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectConstructorKv(String userName, String email) {
    BasicDBObject query = new BasicDBObject("sharedWith", userName);
    // ok: mongodb-nosqli
    query.append("email", email);

    MongoCursor<Document> cursor = collection.find(query).iterator();
    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectConstructorMap(String userName, String email) {
    HashMap<String, String> paramMap = new HashMap<>();
    // ruleid: mongodb-nosqli
    paramMap.put("$where", "this.sharedWith == \"" + userName + "\" && this.email == \"" + email + "\"");
    BasicDBObject query = new BasicDBObject(paramMap);

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectConstructorMap(String userName, String email) {
    HashMap<String, String> paramMap = new HashMap<>();
    // ok: mongodb-nosqli
    paramMap.put("$where", "this.sharedWith == \"CONSTANT\" && this.email == \"CONSTANT\"");
    BasicDBObject query = new BasicDBObject(paramMap);

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectConstructorMap(String userName, String email) {
    HashMap<String, String> paramMap = new HashMap<>();
    // ok: mongodb-nosqli
    paramMap.put("sharedWith", userName);
    paramMap.put("email", email);
    BasicDBObject query = new BasicDBObject(paramMap);

    MongoCursor<Document> cursor = collection.find(query).iterator();
    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectParse(String userName, String email) {
    HashMap<String, String> paramMap = new HashMap<>();
    // ruleid: mongodb-nosqli
    paramMap.put("$where", "this.sharedWith == \"" + userName + "\" && this.email == \"" + email + "\"");
    String json = new JSONObject(paramMap).toString();
    BasicDBObject query = new BasicDBObject().parse(json);

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectParse(String userName, String email) {
    HashMap<String, String> paramMap = new HashMap<>();
    // ok: mongodb-nosqli
    paramMap.put("$where", "this.sharedWith == \"CONSTANT\" && this.email == \"CONSTANT\"");
    String json = new JSONObject(paramMap).toString();
    BasicDBObject query = new BasicDBObject().parse(json);

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectParse(String userName, String email) {
    HashMap<String, String> paramMap = new HashMap<>();
    // ok: mongodb-nosqli
    paramMap.put("sharedWith", userName);
    paramMap.put("email", email);
    String json = new JSONObject(paramMap).toString();
    BasicDBObject query = new BasicDBObject().parse(json);

    MongoCursor<Document> cursor = collection.find(query).iterator();
    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderAdd(String userName, String email) {
    // ruleid: mongodb-nosqli
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start()
        .add("$where", "this.sharedWith == \"" + userName + "\" && this.email == \"" + email + "\"")
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderAdd(String userName, String email) {
    // ok: mongodb-nosqli
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start()
        .add("$where", "this.sharedWith == \"CONSTANT\" && this.email == \"CONSTANT\"")
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderAdd(String userName, String email) {
    // ok: mongodb-nosqli
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start()
        .add("sharedWith", userName)
        .add("email", email)
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();
    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderAppend(String userName, String email) {
    // ruleid: mongodb-nosqli
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start()
        .append("$where", "this.sharedWith == \"" + userName + "\" && this.email == \"" + email + "\"")
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderAppend(String userName, String email) {
    // ok: mongodb-nosqli
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start()
        .append("$where", "this.sharedWith == \"CONSTANT\" && this.email == \"CONSTANT\"")
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderAppend(String userName, String email) {
    // ok: mongodb-nosqli
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start()
        .append("sharedWith", userName)
        .append("email", email)
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();
    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderStartKv(String userName, String email) {
    // ruleid: mongodb-nosqli
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start("$where", "this.sharedWith == \"" + userName + "\" && this.email == \"" + email + "\"")
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderStartKv(String userName, String email) {
    // ok: mongodb-nosqli
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start("$where", "this.sharedWith == \"CONSTANT\" && this.email == \"CONSTANT\"")
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderStartKv(String userName, String email) {
    // ok: mongodb-nosqli
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start("sharedWith", userName)
        .append("email", email)
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();
    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderStartMap(String userName, String email) {
    HashMap<String, String> paramMap = new HashMap<>();
    // ruleid: mongodb-nosqli
    paramMap.put("$where", "this.sharedWith == \"" + userName + "\" && this.email == \"" + email + "\"");
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start(paramMap)
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderStartMap(String userName, String email) {
    HashMap<String, String> paramMap = new HashMap<>();
    // ok: mongodb-nosqli
    paramMap.put("$where", "this.sharedWith == \"CONSTANT\" && this.email == \"CONSTANT\"");
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start(paramMap)
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();

    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }

  public ArrayList<Document> basicDBObjectBuilderStartMap(String userName, String email) {
    HashMap<String, String> paramMap = new HashMap<>();
    // ok: mongodb-nosqli
    paramMap.put("sharedWith", userName);
    paramMap.put("email", email);
    BasicDBObject query = (BasicDBObject) BasicDBObjectBuilder
        .start(paramMap)
        .get();

    MongoCursor<Document> cursor = collection.find(query).iterator();
    ArrayList<Document> results = new ArrayList<>();
    while (cursor.hasNext()) {
      Document doc = cursor.next();
      results.add(doc);
    }

    return results;
  }
}