Log SHA1 hash of X-Auth-Token value
Remove logging of sensitive information like the token value from X-Auth-Token. Instead, log the sha1 hash of the token value, prefixed by '{SHA1}'. Closes-bug: #1429701 Change-Id: If0536ce2d4f71d61c272427cefec7a4dbbdcdefa
This commit is contained in:
parent
db175f917c
commit
9c3641317e
@ -16,6 +16,7 @@
|
||||
import copy
|
||||
from distutils.version import StrictVersion
|
||||
import functools
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
@ -54,6 +55,7 @@ API_VERSION_SELECTED_STATES = ('user', 'negotiated', 'cached', 'default')
|
||||
|
||||
DEFAULT_MAX_RETRIES = 5
|
||||
DEFAULT_RETRY_INTERVAL = 2
|
||||
SENSITIVE_HEADERS = ('X-Auth-Token',)
|
||||
|
||||
|
||||
def _trim_endpoint_api_version(url):
|
||||
@ -245,11 +247,33 @@ class HTTPClient(VersionNegotiationMixin):
|
||||
except six.moves.http_client.InvalidURL:
|
||||
raise exc.EndpointException()
|
||||
|
||||
def _process_header(self, name, value):
|
||||
"""Redacts any sensitive header
|
||||
|
||||
Redact a header that contains sensitive information, by returning an
|
||||
updated header with the sha1 hash of that value. The redacted value is
|
||||
prefixed by '{SHA1}' because that's the convention used within
|
||||
OpenStack.
|
||||
|
||||
:returns: A tuple of (name, value)
|
||||
name: the safe encoding format of name
|
||||
value: the redacted value if name is x-auth-token,
|
||||
or the safe encoding format of name
|
||||
|
||||
"""
|
||||
if name in SENSITIVE_HEADERS:
|
||||
v = value.encode('utf-8')
|
||||
h = hashlib.sha1(v)
|
||||
d = h.hexdigest()
|
||||
return (name, "{SHA1}%s" % d)
|
||||
else:
|
||||
return (name, value)
|
||||
|
||||
def log_curl_request(self, method, url, kwargs):
|
||||
curl = ['curl -i -X %s' % method]
|
||||
|
||||
for (key, value) in kwargs['headers'].items():
|
||||
header = '-H \'%s: %s\'' % (key, value)
|
||||
header = '-H \'%s: %s\'' % self._process_header(key, value)
|
||||
curl.append(header)
|
||||
|
||||
conn_params_fmt = [
|
||||
|
@ -16,6 +16,7 @@ import mock
|
||||
import ironicclient
|
||||
from ironicclient.client import get_client
|
||||
from ironicclient.common import filecache
|
||||
from ironicclient.common import http
|
||||
from ironicclient import exc
|
||||
from ironicclient.tests.unit import utils
|
||||
from ironicclient.v1 import client as v1
|
||||
@ -210,3 +211,18 @@ class ClientTest(utils.BaseTestCase):
|
||||
port=mock.ANY)
|
||||
self.assertEqual(version, client.http_client.os_ironic_api_version)
|
||||
self.assertEqual('cached', client.http_client.api_version_select_state)
|
||||
|
||||
def test_safe_header_with_auth_token(self):
|
||||
(name, value) = ('X-Auth-Token', u'3b640e2e64d946ac8f55615aff221dc1')
|
||||
expected_header = (u'X-Auth-Token',
|
||||
'{SHA1}6de9fb3b0b89099030a54abfeb468e7b1b1f0f2b')
|
||||
client = http.HTTPClient('http://localhost/')
|
||||
header_redact = client._process_header(name, value)
|
||||
self.assertEqual(expected_header, header_redact)
|
||||
|
||||
def test_safe_header_with_no_auth_token(self):
|
||||
name, value = ('Accept', 'application/json')
|
||||
header = ('Accept', 'application/json')
|
||||
client = http.HTTPClient('http://localhost/')
|
||||
header_redact = client._process_header(name, value)
|
||||
self.assertEqual(header, header_redact)
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
other:
|
||||
- Log the SHA1 hash of X-Auth-Token value prefixed
|
||||
by '{SHA}'.
|
Loading…
Reference in New Issue
Block a user