commit 72d5cf0aa90d20435aba95e7361666c96b4b0de6 (HEAD -> bug/1638312-ec2-no-disk-creds.txt) Author: Andrew Jorgensen Date: Tue Nov 1 10:54:31 2016 -0400 EC2: Do not cache security credentials on disk On EC2, instance metadata can include credentials that remain valid for as much as 6 hours. Reading these and allowing them to be pickled represents a potential vulnerability if a snapshot of the disk is taken and shared as part of an AMI. This skips security-credentials when walking the meta-data tree. LP: #1638312 Reviewed-by: Ian Weller Reviewed-by: Ben Cressey Reported-by: Kyle Barnes diff --git a/cloudinit/ec2_utils.py b/cloudinit/ec2_utils.py index 76dda04..0a5c874 100644 --- a/cloudinit/ec2_utils.py +++ b/cloudinit/ec2_utils.py @@ -94,6 +94,9 @@ class MetadataMaterializer(object): field_name = get_name(field) if not field or not field_name: continue + # Don't materialize credentials + if field_name == 'security-credentials': + continue if has_children(field): if field_name not in children: children.append(field_name) diff --git a/tests/unittests/test_ec2_util.py b/tests/unittests/test_ec2_util.py index d6cf17f..72faee2 100644 --- a/tests/unittests/test_ec2_util.py +++ b/tests/unittests/test_ec2_util.py @@ -137,3 +137,50 @@ class TestEc2Util(helpers.HttprettyTestCase): self.assertEqual(2, len(bdm)) self.assertEqual(bdm['ami'], 'sdb') self.assertEqual(bdm['ephemeral0'], 'sdc') + + @hp.activate + def test_metadata_no_security_credentials(self): + base_url = 'http://169.254.169.254/%s/meta-data/' % (self.VERSION) + hp.register_uri(hp.GET, base_url, status=200, + body="\n".join(['instance-id', + 'iam/'])) + hp.register_uri(hp.GET, uh.combine_url(base_url, 'instance-id'), + status=200, body='i-0123451689abcdef0') + hp.register_uri(hp.GET, + uh.combine_url(base_url, 'iam/'), + status=200, + body="\n".join(['info/', 'security-credentials/'])) + hp.register_uri(hp.GET, + uh.combine_url(base_url, 'iam/info/'), + status=200, + body='LastUpdated') + hp.register_uri(hp.GET, + uh.combine_url(base_url, 'iam/info/LastUpdated'), + status=200, body='2016-10-27T17:29:39Z') + hp.register_uri(hp.GET, + uh.combine_url(base_url, 'iam/security-credentials/'), + status=200, + body='ReadOnly/') + hp.register_uri(hp.GET, + uh.combine_url(base_url, + 'iam/security-credentials/ReadOnly/'), + status=200, + body="\n".join(['LastUpdated', 'Expiration'])) + hp.register_uri(hp.GET, + uh.combine_url( + base_url, + 'iam/security-credentials/ReadOnly/LastUpdated'), + status=200, body='2016-10-27T17:28:17Z') + hp.register_uri(hp.GET, + uh.combine_url( + base_url, + 'iam/security-credentials/ReadOnly/Expiration'), + status=200, body='2016-10-28T00:00:34Z') + md = eu.get_instance_metadata(self.VERSION, retries=0, timeout=0.1) + self.assertEqual(md['instance-id'], 'i-0123451689abcdef0') + iam = md['iam'] + self.assertEqual(1, len(iam)) + self.assertEqual(iam['info']['LastUpdated'], '2016-10-27T17:29:39Z') + self.assertNotIn('security-credentials', iam) + +# vi: ts=4 expandtab