Ensure we mask sensitive data from Mistral Action logs
Mistral didn't make use of the oslo_utils "mask_password" methods, leading in sensitive data leakage in its logs. This patch corrects this security issue. Note that it depends on oslo_utils patch adding new patterns, and ensuring it's case-insensitive. Change-Id: I544d3c172f2dea02c62c49c311c4b5954413ae15 Related-Bug: #1850843 Co-Authored-By: Dougal Matthews <dougal@redhat.com> Signed-off-by: Cédric Jeanneret <cjeanner@redhat.com>
This commit is contained in:
parent
b9dc3603a7
commit
4bac2b282e
|
@ -32,8 +32,11 @@ class Result(serialization.MistralSerializable):
|
||||||
)
|
)
|
||||||
|
|
||||||
def cut_repr(self):
|
def cut_repr(self):
|
||||||
|
_data = utils.mask_data(self.data)
|
||||||
|
_error = utils.mask_data(self.error)
|
||||||
|
_cancel = utils.mask_data(self.cancel)
|
||||||
return 'Result [data=%s, error=%s, cancel=%s]' % (
|
return 'Result [data=%s, error=%s, cancel=%s]' % (
|
||||||
utils.cut(self.data), utils.cut(self.error), str(self.cancel)
|
utils.cut(_data), utils.cut(_error), str(_cancel)
|
||||||
)
|
)
|
||||||
|
|
||||||
def is_cancel(self):
|
def is_cancel(self):
|
||||||
|
|
|
@ -250,3 +250,20 @@ class TestUtils(tests_base.TestCase):
|
||||||
d[i] = {'value': 'This is a string that exceeds 35 characters'}
|
d[i] = {'value': 'This is a string that exceeds 35 characters'}
|
||||||
s = utils.cut(d, 65500)
|
s = utils.cut(d, 65500)
|
||||||
self.assertThat(len(s), ttm.Not(ttm.GreaterThan(65500)))
|
self.assertThat(len(s), ttm.Not(ttm.GreaterThan(65500)))
|
||||||
|
|
||||||
|
def test_mask_data(self):
|
||||||
|
payload = {'adminPass': 'fooBarBaz'}
|
||||||
|
expected = {'adminPass': '***'}
|
||||||
|
self.assertEqual(expected, utils.mask_data(payload))
|
||||||
|
|
||||||
|
payload = """adminPass='fooBarBaz'"""
|
||||||
|
expected = """adminPass='***'"""
|
||||||
|
self.assertEqual(expected, utils.mask_data(payload))
|
||||||
|
|
||||||
|
payload = [{'adminPass': 'fooBarBaz'}, {"new_pass": "blah"}]
|
||||||
|
expected = [{'adminPass': '***'}, {"new_pass": "***"}]
|
||||||
|
self.assertEqual(expected, utils.mask_data(payload))
|
||||||
|
|
||||||
|
payload = ["adminPass", 'fooBarBaz']
|
||||||
|
expected = ["adminPass", 'fooBarBaz']
|
||||||
|
self.assertEqual(expected, utils.mask_data(payload))
|
||||||
|
|
|
@ -28,6 +28,8 @@ import threading
|
||||||
import eventlet
|
import eventlet
|
||||||
from eventlet import corolocal
|
from eventlet import corolocal
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
from oslo_utils.strutils import mask_dict_password
|
||||||
|
from oslo_utils.strutils import mask_password
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
import pkg_resources as pkg
|
import pkg_resources as pkg
|
||||||
|
@ -484,3 +486,12 @@ def generate_string(length):
|
||||||
string.ascii_uppercase + string.digits)
|
string.ascii_uppercase + string.digits)
|
||||||
for _ in range(length)
|
for _ in range(length)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def mask_data(obj):
|
||||||
|
if isinstance(obj, dict):
|
||||||
|
return mask_dict_password(obj)
|
||||||
|
elif isinstance(obj, list):
|
||||||
|
return [mask_data(i) for i in obj]
|
||||||
|
else:
|
||||||
|
return mask_password(obj)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
security:
|
||||||
|
- Ensure we mask sensitive data before logging Action return values
|
||||||
|
fixes:
|
||||||
|
- https://bugs.launchpad.net/tripleo/+bug/1850843
|
Loading…
Reference in New Issue