Skip to content

[Filtered alias] Alias filters are not applied when accessing to the doc by _id #68555

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
MKCG opened this issue Feb 4, 2021 · 2 comments
Closed
Labels
>bug needs:triage Requires assignment of a team area label

Comments

@MKCG
Copy link

MKCG commented Feb 4, 2021

The environment is basically the following Dockerfile :

FROM elasticsearch:7.6.1

RUN /usr/share/elasticsearch/bin/elasticsearch-plugin install --batch repository-s3
RUN /usr/share/elasticsearch/bin/elasticsearch-keystore create

Elasticsearch version (bin/elasticsearch --version): 7.6.1

Plugins installed: [ repository-s3 ]

JVM version (java -version): OpenJDK 64-Bit Server VM AdoptOpenJDK (build 13.0.2+8, mixed mode, sharing)

OS version (uname -a if on a Unix-like system): Linux 97d63e675866 5.8.0-41-generic #46~20.04.1-Ubuntu SMP Mon Jan 18 17:52:23 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Description of the problem including expected versus actual behavior:

When a filtered alias is associated to an index then it is still possible to access to any document by their _id but only when using the GET <index>/_doc/<_id> API.

This is a major security issue for SAAS application for which the _id field is generated by the application.

Steps to reproduce:

  1. Create an index with an alias defining some filter to apply
PUT example-filtered
{
  "aliases": {
    "customer-foo": {
      "filter": {
        "bool": {
          "filter": {
            "term": {
              "acl.customer_name": "foo"
            }
          }
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "acl": {
        "properties": {
          "customer_name": {
            "type": "keyword"
          }
        }
      }
    }
  }
}
  1. Create some documents, the first one should be matched by the query, the second one must not
PUT example-filtered/_doc/hello
{
  "acl": {
    "customer_name": "foo"
  }
}


PUT example-filtered/_doc/world
{
  "acl": {
    "customer_name": "bar"
  }
}
  1. Use the alias customer-foo to retrieve the matching documents
GET customer-foo/_search

This returns only one entry which is what was expected :

{
 "took" : 0,
 "timed_out" : false,
 "_shards" : {
   "total" : 1,
   "successful" : 1,
   "skipped" : 0,
   "failed" : 0
 },
 "hits" : {
   "total" : {
     "value" : 1,
     "relation" : "eq"
   },
   "max_score" : 1.0,
   "hits" : [
     {
       "_index" : "example-filtered",
       "_type" : "_doc",
       "_id" : "hello",
       "_score" : 1.0,
       "_source" : {
         "acl" : {
           "customer_name" : "foo"
         }
       }
     }
   ]
 }
}

  1. Use the alias customer-foo to count the matching documents
GET customer-foo/_count

Only one document match, this is what was expected

{
 "count" : 1,
 "_shards" : {
   "total" : 1,
   "successful" : 1,
   "skipped" : 0,
   "failed" : 0
 }
}
  1. Use the alias customer-foo to search by the _id world
GET customer-foo/_search
{
  "query": {
    "term": {
      "_id": "world"
    }
  }
}

This does not match any document which is correct

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

  1. Use the GET <index>/_doc/<id> to access to the document using the alias name :
GET customer-foo/_doc/world 

This returns the document even though it does not match the filter associated to the defined alias :

{
 "_index" : "example-filtered",
 "_type" : "_doc",
 "_id" : "world",
 "_version" : 7,
 "_seq_no" : 8,
 "_primary_term" : 1,
 "found" : true,
 "_source" : {
   "acl" : {
     "customer_name" : "bar"
   }
 }
}
  1. It is also possible to DELETE the document using an alias that must not match

This should not be possible

DELETE customer-foo/_doc/world

And yet the document can be removed

{
  "_index" : "example-filtered",
  "_type" : "_doc",
  "_id" : "world",
  "_version" : 8,
  "result" : "deleted",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 9,
  "_primary_term" : 1
}
@MKCG MKCG added >bug needs:triage Requires assignment of a team area label labels Feb 4, 2021
@mounirrquiba
Copy link

Ooops, thank you @MKCG !

@MKCG MKCG closed this as completed Feb 5, 2021
@joshbressers
Copy link

This filtered alias behavior is expected. Filtered aliases in Elasticsearch are not robust enough to act as a security control.

There are a number of ways to bypass filtered alias restrictions with Elasticsearch. We note this limitation on this page:
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-limitations.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>bug needs:triage Requires assignment of a team area label
Projects
None yet
Development

No branches or pull requests

3 participants