Skip to content

Commit

Permalink
Redact access tokens from extension's output (#2811)
Browse files Browse the repository at this point in the history
* Redact access tokens from extension's output

* python 2.6

---------

Co-authored-by: narrieta <narrieta>
  • Loading branch information
narrieta authored Apr 25, 2023
1 parent 4ba20de commit f02b31f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
10 changes: 9 additions & 1 deletion azurelinuxagent/common/utils/extensionprocessutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#

import os
import re
import signal
import time

Expand Down Expand Up @@ -87,6 +88,9 @@ def handle_process_completion(process, command, timeout, stdout, stderr, error_c
return process_output


SAS_TOKEN_RE = re.compile(r'(https://\S+\?)((sv|st|se|sr|sp|sip|spr|sig)=\S+)+', flags=re.IGNORECASE)


def read_output(stdout, stderr):
"""
Read the output of the process sent to stdout and stderr and trim them to the max appropriate length.
Expand All @@ -103,7 +107,11 @@ def read_output(stdout, stderr):
stderr = ustr(stderr.read(TELEMETRY_MESSAGE_MAX_LEN), encoding='utf-8',
errors='backslashreplace')

return format_stdout_stderr(stdout, stderr)
def redact(s):
# redact query strings that look like SAS tokens
return SAS_TOKEN_RE.sub(r'\1<redacted>', s)

return format_stdout_stderr(redact(stdout), redact(stderr))
except Exception as e:
return format_stdout_stderr("", "Cannot read stdout/stderr: {0}".format(ustr(e)))

Expand Down
27 changes: 27 additions & 0 deletions tests/ga/test_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -3418,6 +3418,33 @@ def http_get_handler(url, *_, **kwargs):
self._assert_handler_status(protocol.report_vm_status, "Ready", 1, "1.0.0")
self.assertEqual("1", protocol.report_vm_status.call_args[0][0].vmAgent.vm_artifacts_aggregate_status.goal_state_aggregate_status.in_svd_seq_no, "SVD sequence number mismatch")

def test_it_should_redact_access_tokens_in_extension_output(self):
original = r'''ONE https://foo.blob.core.windows.net/bar?sv=2000&ss=bfqt&srt=sco&sp=rw&se=2025&st=2022&spr=https&sig=SI%3D
TWO:HTTPS://bar.blob.core.com/foo/bar/foo.txt?sv=2018&sr=b&sig=Yx%3D&st=2023%3A52Z&se=9999%3A59%3A59Z&sp=r TWO
https://bar.com/foo?uid=2018&sr=b THREE'''
expected = r'''ONE https://foo.blob.core.windows.net/bar?<redacted>
TWO:HTTPS://bar.blob.core.com/foo/bar/foo.txt?<redacted> TWO
https://bar.com/foo?uid=2018&sr=b THREE'''

with mock_wire_protocol(mockwiredata.DATA_FILE) as protocol:
exthandlers_handler = get_exthandlers_handler(protocol)

original_popen = subprocess.Popen

def mock_popen(cmd, *args, **kwargs):
if cmd.endswith("sample.py -enable"):
cmd = "echo '{0}'; >&2 echo '{0}'; exit 1".format(original)
return original_popen(cmd, *args, **kwargs)

with patch.object(subprocess, 'Popen', side_effect=mock_popen):
exthandlers_handler.run()

status = exthandlers_handler.report_ext_handlers_status()
self.assertEqual(1, len(status.vmAgent.extensionHandlers), 'Expected exactly 1 extension status')
message = status.vmAgent.extensionHandlers[0].message
self.assertIn('[stdout]\n{0}'.format(expected), message, "The extension's stdout was not redacted correctly")
self.assertIn('[stderr]\n{0}'.format(expected), message, "The extension's stderr was not redacted correctly")


if __name__ == '__main__':
unittest.main()

0 comments on commit f02b31f

Please sign in to comment.