summaryrefslogtreecommitdiff
path: root/cloudinit/url_helper.py
diff options
context:
space:
mode:
authorRyan Harper <ryan.harper@canonical.com>2020-02-19 15:01:09 -0600
committerGitHub <noreply@github.com>2020-02-19 16:01:09 -0500
commit87cd040ed8fe7195cbb357ed3bbf53cd2a81436c (patch)
tree9d528f71d9c44c809092a126f926df497f255b54 /cloudinit/url_helper.py
parent3e2f7356effc9e9cccc5ae945846279804eedc46 (diff)
downloadcloud-init-git-87cd040ed8fe7195cbb357ed3bbf53cd2a81436c.tar.gz
ec2: Do not log IMDSv2 token values, instead use REDACTED (#219)
Instead of logging the token values used log the headers and replace the actual values with the string 'REDACTED'. This allows users to examine cloud-init.log and see that the IMDSv2 token header is being used but avoids leaving the value used in the log file itself. LP: #1863943
Diffstat (limited to 'cloudinit/url_helper.py')
-rw-r--r--cloudinit/url_helper.py27
1 files changed, 20 insertions, 7 deletions
diff --git a/cloudinit/url_helper.py b/cloudinit/url_helper.py
index f6d68436..eeb27aa8 100644
--- a/cloudinit/url_helper.py
+++ b/cloudinit/url_helper.py
@@ -8,6 +8,7 @@
#
# This file is part of cloud-init. See LICENSE file for license information.
+import copy
import json
import os
import time
@@ -31,6 +32,7 @@ LOG = logging.getLogger(__name__)
SSL_ENABLED = False
CONFIG_ENABLED = False # This was added in 0.7 (but taken out in >=1.0)
_REQ_VER = None
+REDACTED = 'REDACTED'
try:
from distutils.version import LooseVersion
import pkg_resources
@@ -189,9 +191,9 @@ def _get_ssl_args(url, ssl_details):
def readurl(url, data=None, timeout=None, retries=0, sec_between=1,
- headers=None, headers_cb=None, ssl_details=None,
- check_status=True, allow_redirects=True, exception_cb=None,
- session=None, infinite=False, log_req_resp=True,
+ headers=None, headers_cb=None, headers_redact=None,
+ ssl_details=None, check_status=True, allow_redirects=True,
+ exception_cb=None, session=None, infinite=False, log_req_resp=True,
request_method=None):
"""Wrapper around requests.Session to read the url and retry if necessary
@@ -207,6 +209,7 @@ def readurl(url, data=None, timeout=None, retries=0, sec_between=1,
:param headers: Optional dict of headers to send during request
:param headers_cb: Optional callable returning a dict of values to send as
headers during request
+ :param headers_redact: Optional list of header names to redact from the log
:param ssl_details: Optional dict providing key_file, ca_certs, and
cert_file keys for use on in ssl connections.
:param check_status: Optional boolean set True to raise when HTTPError
@@ -233,6 +236,8 @@ def readurl(url, data=None, timeout=None, retries=0, sec_between=1,
req_args['method'] = request_method
if timeout is not None:
req_args['timeout'] = max(float(timeout), 0)
+ if headers_redact is None:
+ headers_redact = []
# It doesn't seem like config
# was added in older library versions (or newer ones either), thus we
# need to manually do the retries if it wasn't...
@@ -277,6 +282,12 @@ def readurl(url, data=None, timeout=None, retries=0, sec_between=1,
if k == 'data':
continue
filtered_req_args[k] = v
+ if k == 'headers':
+ for hkey, _hval in v.items():
+ if hkey in headers_redact:
+ filtered_req_args[k][hkey] = (
+ copy.deepcopy(req_args[k][hkey]))
+ filtered_req_args[k][hkey] = REDACTED
try:
if log_req_resp:
@@ -329,8 +340,8 @@ def readurl(url, data=None, timeout=None, retries=0, sec_between=1,
return None # Should throw before this...
-def wait_for_url(urls, max_wait=None, timeout=None,
- status_cb=None, headers_cb=None, sleep_time=1,
+def wait_for_url(urls, max_wait=None, timeout=None, status_cb=None,
+ headers_cb=None, headers_redact=None, sleep_time=1,
exception_cb=None, sleep_time_cb=None, request_method=None):
"""
urls: a list of urls to try
@@ -342,6 +353,7 @@ def wait_for_url(urls, max_wait=None, timeout=None,
status_cb: call method with string message when a url is not available
headers_cb: call method with single argument of url to get headers
for request.
+ headers_redact: a list of header names to redact from the log
exception_cb: call method with 2 arguments 'msg' (per status_cb) and
'exception', the exception that occurred.
sleep_time_cb: call method with 2 arguments (response, loop_n) that
@@ -405,8 +417,9 @@ def wait_for_url(urls, max_wait=None, timeout=None,
headers = {}
response = readurl(
- url, headers=headers, timeout=timeout,
- check_status=False, request_method=request_method)
+ url, headers=headers, headers_redact=headers_redact,
+ timeout=timeout, check_status=False,
+ request_method=request_method)
if not response.contents:
reason = "empty response [%s]" % (response.code)
url_exc = UrlError(ValueError(reason), code=response.code,