将 Lucene 查询字符串直接从用户传递到 QueryParser 是否安全?

Is it safe to pass a Lucene Query String directly from a user into a QueryParser?

tldr: 我可以 安全地 将原始查询字符串(作为 URL 参数检索)传递到 Lucene QueryParser没有任何额外的输入清理?

我不是安全专家,但我需要一些建议。如标题所述,使用此控制器方法是否安全:

    @CrossOrigin(origins = "${allowed-origin}")
    @GetMapping(value = "/search/{query_string}", produces = MediaType.APPLICATION_JSON_VALUE)
    public List doSearch(@PathVariable("query_string") String queryString) {
        return searchQueryHandlerService.doSearch(queryString);
    }

配合本服务方式(错误处理仅供测试):

    public List doSearch(String queryString) {
        LOGGER.debug("Parsing query string: " + queryString);
        try {
            Query q = new QueryParser(null, standardAnalyzer).parse(queryString);
            FullTextEntityManager manager = Search.getFullTextEntityManager(entityManager);
            FullTextQuery fullTextQuery = manager.createFullTextQuery(q, Poem.class, Book.class, Section.class);
            return fullTextQuery.getResultList();
        } catch (ParseException e) {
            LOGGER.error(e);
            return Collections.emptyList();
        }
    }

只有基本的输入清理?如果这不安全,我可以采取措施使其安全吗?

非常感谢任何帮助。

过去几周我一直断断续续地研究这个问题,但我找不到任何理由说明它 不会 安全,但这是一个如此晦涩的问题(在我不熟悉的领域)我可能遗漏了一些明显的、基本的问题,任何在该领域工作的人都会立即看到。

A FullTextQuery 始终是只读的,因此您不必担心人们删除表格或处理 [=42 时可能需要考虑的类似问题=]注入.

但是如果您对用户可以看到哪些数据有安全限制,您可能需要小心。

API 还将操作限制在一组特定的索引上——在你的例子中是那些包含 Poem 实体的索引——所以也不可能突破所选的索引。

但你需要考虑:

  • 如果用户能够以某种方式找到与您预期他们寻找的不同的诗歌,是否可以
  • 如果您与其他实体共享相同的索引,可能有一些方法可以推断有关这些其他实体的数据

因此,为了具有安全意识,您可能需要:

  • 每个实体类型都被索引到自己的索引中(这是默认设置)。
  • 启用某些 FullTextFilter 以根据您的自定义规则限制用户查询。
  • 在呈现之前实际检查每个结果的内容,以便删除其他过滤器未捕获的内容。

如果您极度偏执,请考虑任何全文索引实际上都可以揭示出某些术语在整个索引中的出现频率。人们通常不太关心这一点,因为它极难利用,而且只有极少的关于数据分布的线索被揭示。

所以回到你的例子,如果这个索引只包含诗歌并且你同意允许任何用户看到你存储的任何诗歌,那么泄露关于你正在提供哪些诗歌的线索通常不是安全问题而是您服务的重点。