Last active
August 29, 2019 22:55
-
-
Save sqqqrly/d8275510c79fd5bfd6b66c335a54c77e to your computer and use it in GitHub Desktop.
Filter away sensitive strings in py3 from stdout and other stream-like objects. Here we are filtering stdout, stderr and file stream.
This file contains 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
[I] ➜ ./redactor.py | |
data out: ******** | |
data err: ******** | |
data out: ******** | |
data err: ******** | |
[I] ➜ cat test.txt | |
data: ******** | |
data: ******** |
This file contains 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
#!/usr/bin/env python3 | |
import sys | |
import base64 | |
class RedactFilter(object): | |
""" | |
A helper class to replace sensitive strings, i.e. redacts, | |
with 8 * redact_char. Also replace base64 encoded versions of redacts. | |
To use, | |
redacts = ['secret1','(s)ensitive2'] | |
sys.stdout = RedactFilter(redacts, sys.stdout) | |
sys.stderr = RedactFilter(redacts, sys.stderr) | |
If using a logger, create the logger after the above. | |
""" | |
def __init__(self, redacts, stream, redact_char='*'): | |
redacts = list(set(redacts)) # unique members only | |
self.stream = stream | |
redacts_64 = [base64.b64encode(bytes(redact, 'utf-8')).decode() \ | |
for redact in redacts] | |
self.redacts = redacts + redacts_64 | |
# print(f'{self.redacts}\n') | |
self.redact_char = redact_char | |
def __getattr__(self, attr_name): | |
return getattr(self.stream, attr_name) | |
def write(self, data): | |
for string in self.redacts: | |
new_string = 8 * self.redact_char # Do not leak length, use 8. | |
data = data.replace(string, new_string) | |
self.stream.write(data) | |
self.stream.flush() | |
def flush(self): | |
self.stream.flush() | |
if __name__ == "__main__": | |
# Filter out sensitive strings from stdout/err. | |
redacts = ['sensi(tive)_', 'pass**&word1',] | |
sys.stdout = RedactFilter(redacts, sys.stdout) | |
sys.stderr = RedactFilter(redacts, sys.stderr) | |
with open("test.txt", 'w') as out: | |
out = RedactFilter(redacts, out) | |
for redact in redacts: | |
out.write(f'data: {redact}\n') | |
print(f'data out: {redact}') | |
print(f'data err: {redact}', file=sys.stderr) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment