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

时间:2019-02-14 19:07:41

标签: spring-boot security lucene hibernate-search

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();
        }
    }

仅对基本输入进行消毒?如果这样做不安全,我可以采取一些措施使其变得安全吗?

任何帮助将不胜感激。

在过去的几周里,我一直在研究这个问题,但我找不到任何理由不会是安全的,但这是一个晦涩的问题(在我所在的地区我不熟悉),我可能会错过一些明显的,根本性的问题,任何在该地区工作的人都会立即看到。

1 个答案:

答案 0 :(得分:2)

FullTextQuery 始终是只读的,因此您不必担心人们删除表或处理SQL注入时可能要考虑的类似问题。

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

API还将操作限制为一组特定的索引-在您的情况下,包含Poem实体-因此也不可能脱离所选索引。

但是您需要考虑:

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

因此,出于安全意识,您可能需要:

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

如果您极度偏执,请考虑任何全文索引实际上可以揭示某些术语在整个索引中的频率如何。人们通常对此不太担心,因为很难利用它,并且只揭示了有关数据分布的极少线索。

因此,以您的示例为例,如果该索引仅包含诗歌,并且您可以允许任何用户看到您存储的任何诗歌,则通常不提供有关您提供哪些诗歌的线索,这不是安全问题,而是而不是整个服务重点。