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:
Lokesh S 2016-02-11 09:36:39 +00:00
parent db175f917c
commit 9c3641317e
3 changed files with 45 additions and 1 deletions

View File

@ -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 = [

View File

@ -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)

View File

@ -0,0 +1,4 @@
---
other:
- Log the SHA1 hash of X-Auth-Token value prefixed
by '{SHA}'.