Building DevSecOps solutions using AWS, Terraform and Kubernetes

AWS - Understanding IMDSv2

  • 26th March 2022

What is IMDSv2

The instance metadata service (IMDS) is an on-instance component that code on the instance uses to securely access instance metadata.

In November 2019, AWS made IMDSv2 available. They consider this the belt and braces approach to instance metadata security.

Let's look at an example retrieving the AMI ID using IMDS:

The old approach
    curl http://169.254.169.254/latest/meta-data/ami-id
The new approach
    TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" \
                -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
    
    curl http://169.254.169.254/latest/meta-data/ami-id -H "X-aws-ec2-metadata-token: $TOKEN"

Important side note: Sessions can last a maximum of 6 hours (21600 seconds).

As you can see, there are two key differences.

  • We first use a PUT call to retrieve a time sensitive session token
  • We then pass this token through to each request to authorise them

Protecting against SSRF vulnerabilities

IMDSv2 helps protect against SSRF vulnerabilities (server side request forgery).

There is at least one high profile breach linked to IMDSv1 usage in a well known bank. This highlights the need for a defense in depth approach while securing your cloud access.

It is thought that the credentials for the IAM Role were pulled from the instance metadata. Unfortunately, the role attached may have had excessive privileges allowing access to S3 storage. Once the hacker has access to credentials like this then it is game over.

A key difference in IMDSv2 is utilising PUT rather than GET.

GET requests are notorious for leaking credentials, so using a PUT request in combination with a session token helps mitigate a lot of the risk.

Is my application still using IMDSv1?

AWS have a cloudwatch metric for this called MetadataNoToken.

  • The number of times the instance metadata service was successfully accessed using a method that does not use a token.

How to require IMDSv2 on EC2

When launching an EC2 using terraform this can be specified using metadata_options:

    resource "aws_instance" "example" {
        // ...
        metadata_options {
            http_endpoint = "enabled"
            http_tokens = "required"
        }
    }

Otherwise the default value will be "optional"

How to enforce the use of IMDSv2

Here is an example policy to enforce IMDSv2 as per this guide:

    {
        "Version": "2012-10-17",
        "Statement": [
                {
                "Sid": "RequireImdsV2",
                "Effect": "Deny",
                "Action": "ec2:RunInstances",
                "Resource": "arn:aws:ec2:*:*:instance/*",
                "Condition": {
                    "StringNotEquals": {
                        "ec2:MetadataHttpTokens": "required"
                    }
                }
            }
        ]
    }

Summary

In a nutshell, every request in IMDSv2 is now protected by session authentication. Updated AWS SDKs and CLIs use this by default, but when writing our scripts we need to make sure we are also using the new format.

This is a cheap and effective way to help mitigate SSRF attacks.

Rhuaridh

Please get in touch through my socials if you would like to ask any questions - I am always happy to speak tech!