acl: Escape special characters during ACL rule serialization#3604
Open
murphyjacob4 wants to merge 4 commits into
Open
acl: Escape special characters during ACL rule serialization#3604murphyjacob4 wants to merge 4 commits into
murphyjacob4 wants to merge 4 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## unstable #3604 +/- ##
============================================
- Coverage 76.65% 76.48% -0.18%
============================================
Files 162 162
Lines 80612 80633 +21
============================================
- Hits 61795 61669 -126
- Misses 18817 18964 +147
🚀 New features to boost your workflow:
|
9b3be5e to
bdfcd45
Compare
…ntheses in selectors Signed-off-by: Jacob Murphy <jkmurphy@google.com>
Signed-off-by: Jacob Murphy <jkmurphy@google.com>
Signed-off-by: Jacob Murphy <jkmurphy@google.com>
4ff748a to
15dbe8f
Compare
Signed-off-by: Jacob Murphy <jkmurphy@google.com>
15dbe8f to
9adabc0
Compare
Member
The original point of this was so that we could verbatim reproduce what the end user gave us. Before this we were trying to regenerate it. I'm just trying to think if anyone would depend on this behavior now. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes several critical bugs in ACL serialization and deserialization regarding command rules, selectors, and usernames containing special characters (like spaces, quotes, and parentheses).
Problem
(~key) +get), was serialized without quotes. On reload,ACL LOADused a simple space-splitter (sdssplitlen) and a simple paren-merging logic (ACLMergeSelectorArguments) that got confused if a rule inside the selector contained a parenthesis (like~key)), leading to loading failures.+get|text") were not escaped on save, leading to assertion failures or loading failures.ACLLoadFromFileusedsdssplitlen(splitting strictly by spaces), which could not handle quoted arguments, preventing simple fixes. This is different than the behavior of ACL SETUSER and prevents control planes from working around the problems above by directly editing the ACL file.Solution
sdsneedsrepr) and escaped and wrapped, if needed, duringACL LISTandACL SAVE.aclSelector->command_rulessuffered from the "stringly typed" anti-pattern. The in memory representation were rules separated by spaces. To properly support things like keys/command-arguments with spaces in them, it would have needed to be stored escaped in memory. To simplify this, we store it as a list of rules now, also simplifying things like rule removal.Backwards comaptibility
ACLLoadFromFileto use a static heuristicACLLineNeedsQuotedParser."(indicating new quoted format), it usessdssplitargsto parse it correctly respecting quotes and escapes.sdssplitlento maintain backward compatibility with old unquoted files (preserving the fix Antirez made in Creating usernames with quotes can break ACL LOAD command after executing ACL SAVE redis/redis#7329).Forwards compatibility
alldbsis added by default starting in 9.1).Clients
ACL LISToutput and ACL file format is changing to properly escape in the ambiguous scenarios. These situations were not working as expected before, and in some cases caused crashes on serialization, so I think changing the format is reasonable for 10.0Serialized Output Comparison
With this fix, rules and selectors containing special characters are properly quoted when saved (e.g., via
ACL SAVEorACL LIST).ACL SETUSER tester on nopass -@all "(~key) +get)"GETon keys matching~key)user tester on ... (~key) resetchannels ... +get)user tester on ... "(~key) resetchannels ... +get)"ACL SETUSER quoter on nopass "+get|text\""get text"(first-arg rule)=== ASSERTION FAILED ===user quoter on ... "+get|text\""ACL SETUSER "test\"user" on nopass +@alltest"useruser test"user on ...user "test\"user" on ...ACL SETUSER keyquoter on nopass "~key\"name"key"nameuser keyquoter on ... ~key"nameuser keyquoter on ... "~key\"name"ACL SETUSER chanquoter on nopass "&chan\"name"chan"nameuser chanquoter on ... &chan"nameuser chanquoter on ... "&chan\"name"Tradeoffs/discussion points
ACL LISTandACL SAVEtake a few more CPU cycles and involves more small memory allocations during the command execution. I still believe it is worth it since this is much less prone to bugs and will be easier to maintain. Alternatively, we can keep it a string and store the rules escaped in memory, at the cost of complexity.ACL LOAD- we do a O(n) pass to check if we should split with the quoted parser or the simple space parser. It also is a heuristic that adds some complexity. An alternative could have been to version the ACL rules in the file (e.g.user default on ver:2 ...). I chose the easier option for now, but curious what others think.)(this is the scenario thatACLMergeSelectorArgumentsfails in).