3

我正在使用 Java、使用 Java 而不是 Scala、MongoDB 和 Jongo 的 Play 框架作为基本 Web CRUD 应用程序的组合。即使我的字符串不包含任何非法字符,我也会不断收到 JSON 解析异常。它实际上在语句末尾关闭大括号时失败了。以下是我的错误和代码。查询字符串只是一个字符串构建器,搜索对象是否为空或有值,如果有值则附加到字符串中。

钟戈法:

public static Iterable<OneDomain> findWithQueryString(String queryString){
    return domains().find("{#}", queryString).as(OneDomain.class);
}

控制器方法:字符串生成器示例:

        if(queryStringBuilder.toString().equalsIgnoreCase("")){
            queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
        }else{
            queryStringBuilder.append(" , ");
            queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
        }

        String queryString = queryStringBuilder.toString();

        Iterable<OneDomain> filteredIterable = OneDomain.findWithQueryString(queryString);

给我这个错误:

   Caused by: com.mongodb.util.JSONParseException:
   {"source : Online Lists , blacklist : true , vetted : true , is : false , isNot : true"}
                                                                                          ^

以“}”上的错误结束它。

除此之外,如果我尝试通过输入 \" 来转义字符,使其变为 \"date\",它将解析并出错,如下所示:

   Caused by: com.mongodb.util.JSONParseException:
   {"\"source\" : \"Online Lists\" , \"blacklist\" : true , \"vetted\" : true , \"is\" : false , \"isNot\" : true"}

我真的可以这样做吗,或者因为它插入了 Java,引号将围绕整个字符串,因此它试图将它作为单个 JSON 字段读取而不是整个查询?

4

2 回答 2

4

首先,确保不要让自己容易受到注入攻击。阅读一般的注入攻击,更具体地说,阅读 MongoDB,例如关于 NoSQL 注入测试的 OWASP 页面


虽然您确实可以将生成的查询字符串传递给 find 方法,但我不建议这样做。当我们生成包含 jongo 替换参数#的查询时,我做了同样的事情并且遇到了大问题,即

// This will throw an exception:
// java.lang.IllegalArgumentException: Not enough parameters passed to query: {"value":"#"}
...find("{" + "\"value\":\"#\"" + "}")

我的解决方案是传递一个 DBObject:

import com.mongodb.BasicDBObject
...find("#", new BasicDBObject().append("value", "#"))

它也可以使用 QueryBuilder 构建:

import com.mongodb.QueryBuilder
...find("#", QueryBuilder.start("value").is("#").get())

最好在 Jongo API 中直接支持查询生成器:https ://github.com/bguerout/jongo/issues/173

于 2015-09-23T08:49:41.503 回答
0

找到了答案。需要放弃替换,而是我的方法看起来像

domains().find("{"+queryString+"}").as(OneDomain.class);
于 2014-08-22T12:56:46.660 回答