Project search not filtering by type leading to incorrect results
After doing some testing I notice the global search query used for Projects is:
Elastic Query
{
"from": 0,
"size": 20,
"query": {
"bool": {
"must": [
{
"simple_query_string": {
"query": "*",
"fields": [
"name^10.0",
"path^9.0",
"description^1.0",
"name_with_namespace^2.0",
"path_with_namespace^1.0"
],
"flags": -1,
"default_operator": "and",
"analyze_wildcard": false,
"auto_generate_synonyms_phrase_query": true,
"fuzzy_prefix_length": 0,
"fuzzy_max_expansions": 50,
"fuzzy_transpositions": true,
"boost": 1
}
}
],
"filter": [
{
"bool": {
"should": [
{
"term": {
"visibility_level": {
"value": 0,
"boost": 1
}
}
},
{
"term": {
"visibility_level": {
"value": 10,
"boost": 1
}
}
},
{
"term": {
"visibility_level": {
"value": 20,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"sort": [
{
"_score": {
"order": "desc"
}
}
],
"highlight": {
"fields": {
"name": {},
"name_with_namespace": {},
"path_with_namespace": {},
"path": {},
"description": {}
}
}
}
This causes problems because it is not filtering by type
. In my local testing I can see that it's fetching snippets from Elasticsearch and reading their id
and assuming they are projects. This could lead to situations where a user is getting access to projects that they shouldn't.
Right now from what I can tell any such leak would end up being redacted but I do wonder if there ends up being something weird going on here where combining this bug with a similar oracle approach like #35631 (closed) might end up leaking the existence of snippets.
I'm not 100% sure but at least we know we should fix this project query to include type: 'project'
to avoid any risks and to stop producing garbage search results.
Steps to reproduce
I haven't reproduced this on staging yet but in my local GDK this was easy. I started with a fresh GDK, enabled Elasticsearch, and indexed all the seeded snippets with bin/rake gitlab:elastic:index
. Then I just performed a search for *
in the projects page and I get back exactly 50
projects. But this is wrong in fact because there aren't even 50 projects seeded initially in my GDK. But there are exactly 50 snippets:
[1] pry(main)> Snippet.count
(7.1ms) SELECT COUNT(*) FROM "snippets"
=> 50
[2] pry(main)> Project.count
(10.4ms) SELECT COUNT(*) FROM "projects"
=> 15