-
-
Notifications
You must be signed in to change notification settings - Fork 782
Fix for #4139 - Secrets not being masked in pack config #4140
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 for #4139 - Secrets not being masked in pack config #4140
Conversation
…in pack configs
|
@Kami Here's an initial workup of a fix. Initial testing looks good (used the email pack schema as a reference https://github.com/StackStorm-Exchange/stackstorm-email/blob/master/config.schema.yaml). I still need to develop test cases, but would appreciate comments early if you have time. |
|
Thanks, I will have a look tomorrow. And yeah, I agree - we need a good and thorough test coverage for that. Another thing we need to keep in mind is to try to make this function as performance efficient as possible (bail early if there are no secret params, only iterate over items which could contain secret params based on the schema, etc.). If we don't do that and just blindly recursively iterate over nested objects, it has a potential to significantly slow API responses for all the endpoints with deeply nested objects (executions, etc.). |
|
An idea of how to speed this up (theoretically) we will need to measure to determine if it's actually faster: In the current implementation we call To potentially speed this up, we could potentially skip traversing parts of the JSON schema if the input data is missing those properties. Example: if we have a schema with a nested dictionary And we pass in data: Then we can skip traversing down into the To accomplish this we would need to combine the two functions |
|
Additional thing to look at is the |
|
As far as deep copy goes - yeah, ideally we would create a deep copy of the original object just once and then modify it in subsequent recursive calls (instead of creating a copy during each recursion which as you have said, is problematic). And in general, I like to avoid recursion where possible because of issues like that, but here it should be fine, if we only create a deep copy once and manipulate that original object in place in subsequent recursive calls. |
…to bugfix/config-secret-masking
|
@Kami Think this is ready for a review, all unit tests are passing on my local box and with the fix detailed below they should pass in travis. FYI i ran into a "random failure" in the |
| # when inspecting the inquiry list output for test: | ||
| # test_list_inquiries_limit() | ||
| while '1440' in newinquiry['id']: | ||
| newinquiry['id'] = str(uuid.uuid4()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing this intermediate test failure 👍
| elif is_list: | ||
| iterator = enumerate(secret_parameters) | ||
| else: | ||
| return MASKED_ATTRIBUTE_VALUE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine or we could also throw because an unsupported type was passed it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried that and we run into a couple weird scenarios where we might pass in an OrderedDict or a MongoEngineDict. As long as the the behavior of the type is compatible, then we should be OK.
Not entirely sure how we can verify that. If you have any ideas i will happily implement them!
st2common/st2common/util/secrets.py
Outdated
| # only create a deep copy of parameters on the first call | ||
| # all other recursive calls pass back referneces to this result object | ||
| # so we can reuse it, saving memory and CPU cycles | ||
| if not result: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's safer to do a more explicit check if result is None? Is there a possible scenario where empty dict / array could be returned during recursion?
| } | ||
| ] | ||
| } | ||
| self.assertEqual(expected, result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work on the extensive tests 👍
|
Can you please add a corresponding changelog entry (and please try to be explicit and describe scenario where this could occur)? Besides that, LGTM 👍 |
|
The fix for PY3 test failure is in my PR - #4134. I hope to finish and merge it today. |
|
OK, i've updated the changelog and converted that one line to |
| Fixed | ||
| ~~~~~ | ||
|
|
||
| * Fixed a bug where secrets in pack configs weren't being masked. Recently we |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor thing - we use 100 characters wide lines. Not a big deal and this can be changed in a subsequent PR.
Fix for #4139
This adds recursion into the secret masking process so that configs with nested
dictsandlistswill also have their secrets masked out for API calls.TODO