Skip to content
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

Fix Document GET with DLS terms query due to Lucene upgrade #3136

Merged
merged 3 commits into from
Aug 14, 2023

Conversation

cwperks
Copy link
Member

@cwperks cwperks commented Aug 9, 2023

Description

Fixes an error on document retrieval for users that are mapped to roles with DLS rules including a terms query. The bug was introduced by a change in Lucene and reported on Slack here. This fix adds a test to catch an error like this at build time and assert the intended behavior.

  • Category (Enhancement, New feature, Bug fix, Test fix, Refactoring, Maintenance, Documentation)

Bug fix

Issues Resolved

#3088

Check List

  • New functionality includes testing
  • New functionality has been documented
  • Commits are signed per the DCO using --signoff

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@cwperks
Copy link
Member Author

cwperks commented Aug 9, 2023

This PR adds a test, but I also verified the change locally by creating a local distribution with the demo security config and executing the following API requests:

curl -XPUT https://admin:admin@localhost:9200/examples --insecure

curl -XPOST https://admin:admin@localhost:9200/examples/_doc/1 --insecure -H "Content-Type: application/json" --data '
{ "foo": "bar" }
'

curl -XPOST https://admin:admin@localhost:9200/examples/_doc/2 --insecure -H "Content-Type: application/json" --data '
{ "foo": "baz" }
'

curl -XGET https://admin:admin@localhost:9200/examples/_search --insecure


curl -XGET https://admin:admin@localhost:9200/examples/_search --insecure -H "Content-Type: application/json" --data '
{ "query": {"terms": { "foo" : ["bar"] } } }
'


curl -XPUT https://admin:admin@localhost:9200/_plugins/_security/api/internalusers/craig --insecure -H "Content-Type: application/json" --data '
{  
  "password": "TestPassword123_"
}
'

curl -XPUT https://admin:admin@localhost:9200/_plugins/_security/api/roles/example_role --insecure -H "Content-Type: application/json" --data '
{
    "cluster_permissions":
    [
        "cluster_composite_ops",
        "indices_monitor"
    ],
    "index_permissions":
    [
        {
            "index_patterns":
            [
                "examples*"
            ],
            "allowed_actions":
            [
                "read"
            ],
            "dls": "{ \"terms\": { \"foo\" : [\"bar\"] } }"
        }
    ]
}
'

curl -XPUT https://admin:admin@localhost:9200/_plugins/_security/api/rolesmapping/example_role --insecure -H "Content-Type: application/json" --data '
{  
  "users" : [ "craig" ]
}
'

curl -XGET https://craig:TestPassword123_@localhost:9200/examples/_search --insecure

curl -XGET https://craig:TestPassword123_@localhost:9200/examples/_doc/1 --insecure

curl -XGET https://admin:admin@localhost:9200/examples/_doc/1 --insecure

@codecov
Copy link

codecov bot commented Aug 9, 2023

Codecov Report

Merging #3136 (a6be927) into main (4593be7) will decrease coverage by 27.07%.
The diff coverage is 100.00%.

@@              Coverage Diff              @@
##               main    #3136       +/-   ##
=============================================
- Coverage     62.42%   35.36%   -27.07%     
+ Complexity     3353     1826     -1527     
=============================================
  Files           254      254               
  Lines         19749    19749               
  Branches       3334     3334               
=============================================
- Hits          12329     6984     -5345     
- Misses         5788    11701     +5913     
+ Partials       1632     1064      -568     
Files Changed Coverage Δ
...security/configuration/DlsFlsFilterLeafReader.java 61.52% <100.00%> (ø)

... and 156 files with indirect coverage changes

@@ -232,7 +232,7 @@ public DlsGetEvaluator(final Query dlsQuery, final LeafReader in, boolean applyD
// https://github.com/apache/lucene-solr/blob/branch_6_3/lucene/misc/src/java/org/apache/lucene/index/PKIndexSplitter.java
final IndexSearcher searcher = new IndexSearcher(DlsFlsFilterLeafReader.this);
searcher.setQueryCache(null);
final Weight preserveWeight = searcher.createWeight(dlsQuery, ScoreMode.COMPLETE_NO_SCORES, 1f);
final Weight preserveWeight = searcher.rewrite(dlsQuery).createWeight(searcher, ScoreMode.COMPLETE_NO_SCORES, 1f);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yikes! What a terrible side effect. It doesn't seem clear how we can identify issues like this if we have them elsewhere other than having had a functional test case fail. How confident are you in this fix, and our coverage on these scenarios?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was not caught with CI because there is no instance of a document GET request from a user mapped to a role with a DLS terms query associated with it. The test added in this PR would ensure that this would be caught at build time.

We could probably enhance this test suite by running different kinds of requests in addition to search requests and aggregations.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you create a follow up task to analyze what test we should have / are missing?

Copy link
Collaborator

@willyborankin willyborankin Aug 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it work for indices that were created prior to 2.9 or 2.10 with the shard version, e.g., 7.10.x?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peternied I filed an issue to asses the current state of FLS, DLS and Field Masking tests and determine what other scenarios should be tested: #3139

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @willyborankin , I plan to test this out today. Thank you for pointing out potential issues with backward compatibility depending on the version of Lucene the shards are created with.

Copy link
Member Author

@cwperks cwperks Aug 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@willyborankin I tested this by creating an index with ES 7, doing a full cluster upgrade to 2.8 w/ this change included and verified that it works.

Comment on lines 51 to 52
System.out.println("q");
System.out.println(Strings.toString(XContentType.JSON, tc.search(new SearchRequest().indices(".opendistro_security")).actionGet()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of scope of this PR; but we can get rid of these sysouts to boost test performance.

Signed-off-by: Craig Perkins <[email protected]>
return getJsonNodeAt(jsonPointer).asText();
}

private JsonNode getJsonNodeAt(String jsonPointer) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qq: If the method getJsonNodeAt(jsonPointer) does not find the specified node, what is returned? Is it null? If it's a possible scenario, we might want to handle it or at least document the expected behavior.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran into this when testing to figure out the correct JSON path. It returns an empty string.

This method is used in assertion statements like this:

Assert.assertEquals(res.getTextFromJsonBody("/hits/total/value"), "1");

so the assertion will fail.

@cwperks cwperks merged commit 88b6d23 into opensearch-project:main Aug 14, 2023
@opensearch-trigger-bot
Copy link
Contributor

The backport to 2.x failed:

The process '/usr/bin/git' failed with exit code 128

To backport manually, run these commands in your terminal:

# Navigate to the root of your repository
cd $(git rev-parse --show-toplevel)
# Fetch latest updates from GitHub
git fetch
# Create a new working tree
git worktree add ../.worktrees/security/backport-2.x 2.x
# Navigate to the new working tree
pushd ../.worktrees/security/backport-2.x
# Create a new branch
git switch --create backport/backport-3136-to-2.x
# Cherry-pick the merged commit of this pull request and resolve the conflicts
git cherry-pick -x --mainline 1 88b6d23f0c84d83f138cf1a61bbe0145d8dd007e
# Push it to GitHub
git push --set-upstream origin backport/backport-3136-to-2.x
# Go back to the original working tree
popd
# Delete the working tree
git worktree remove ../.worktrees/security/backport-2.x

Then, create a pull request where the base branch is 2.x and the compare/head branch is backport/backport-3136-to-2.x.

@cwperks
Copy link
Member Author

cwperks commented Aug 14, 2023

I will create a manual backport for this

cwperks added a commit to cwperks/security that referenced this pull request Aug 14, 2023
Fixes an error on document retrieval for users that are mapped to roles
with DLS rules including a terms query. The bug was introduced by a
change in Lucene and reported on Slack
[here](https://opensearch.slack.com/archives/C0539F41Z5X/p1690714779140659).
This fix adds a test to catch an error like this at build time and
assert the intended behavior.

* Category (Enhancement, New feature, Bug fix, Test fix, Refactoring,
Maintenance, Documentation)

Bug fix

opensearch-project#3088

- [ ] New functionality includes testing
- [ ] New functionality has been documented
- [ ] Commits are signed per the DCO using --signoff

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and
signing off your commits, please check
[here](https://github.com/opensearch-project/OpenSearch/blob/main/CONTRIBUTING.md#developer-certificate-of-origin).

---------

Signed-off-by: Craig Perkins <[email protected]>
(cherry picked from commit 88b6d23)
cwperks added a commit that referenced this pull request Aug 15, 2023
@peternied peternied changed the title Fix Document GET with DLS terms query Fix Document GET with DLS terms query due to Lucene upgrade Aug 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport 2.x backport to 2.x branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants