0

I am using the javascript-elasticsearch API for searching data. However, I need to limit access to a certain group based upon their studio. For example:

obj1
title = Titanic
studio = Fox

obj2
title = Lion King
studio = Disney

I can do the query: ?q=&studio=disney, but this can be adjusted in the javascript by a malicious user to do q=&studio=. Is there a way to set this limitation (&studio=X) in the API key I am using or in elasticsearch itself? How would this be done, and if it cannot be done, what would be the best solution for the above issue?

David542
  • 104,438
  • 178
  • 489
  • 842

1 Answers1

1

This could be done with a filtered alias. The idea is that instead of searching via the index name you instead search via a filtered alias on that index. Here is an example. Let's say you have an index movies with a type movie. The most basic way of searching would be:

curl -XPOST localhost:9200/movies/movie/_search?q=...

When searching this way, you're basically giving access to the whole movie index. If you want to restrict access to only certain documents of that index to certain types of users, you can create an alias which will only query documents that match a certain filter, like this:

curl -XPOST localhost:9200/_aliases -d '{
    "actions" : [
        {
            "add" : {
                 "index" : "movies",
                 "alias" : "disney_movies",
                 "filter" : { "term" : { "studio" : "disney" } }
            }
        }
    ]
}'

Then you can force the searches on that alias instead of on the index. Doing so will transparently only search movies with studio: disney and you don't need to explicitely specify that in the query itself anymore.

curl -XPOST localhost:9200/disney_movies/movie/_search?q=...

If someone tries to tamper with the studio variable, there will be no matching alias and hence no results coming back, which is what you want.

Val
  • 207,596
  • 13
  • 358
  • 360
  • Thanks for this. That is exactly what I'm looking for. So, just to make sure I'm clear, in the above case, when the user is created, we'd create the alias which adds the prerequisite filter (using our admin API key), and then when we later perform a search for that user we search via the alias endpoint. Is that a correct understanding of the above? – David542 Oct 25 '15 at 05:29
  • Also, I imagine we'd want to use something like a `uuid` for the alias in the url? So it's not easy to guess what one of the other urls might be? – David542 Oct 25 '15 at 05:31
  • Your understanding is correct. Of course you can use whatever you want as the alias name. Also worth noting that this solution doesn't scale too well if you have thousands of users, but for a few dozens that's perfectly ok. – Val Oct 25 '15 at 05:35
  • Doesn't Shield do exactly what I'm looking for here? In the intro it says "Shield is a plugin for Elasticsearch that enables you to easily secure a cluster. With Shield, you can password-protect your data as well as implement more advanced security measures such as encrypting communications, role-based access control, IP filtering, and auditing.". But I've never used that before: https://www.elastic.co/guide/en/shield/current/introduction.html. – David542 Oct 25 '15 at 08:08
  • As Shield is a commercial product, I was going to suggest that in the case you needed something much more fine-grained for your use cases. But of course, with Shield you can do much more advanced that requires real security instead of just "information hiding". – Val Oct 25 '15 at 08:32