Skip to content

Blog 22 September 2026 3 min read

IMDSv1: how an ordinary web bug becomes a cloud account takeover

In short

Every cloud instance can ask a local address for the temporary credentials of its role. In version 1, a plain GET request is enough; an SSRF flaw in a web application therefore lets an attacker fetch them and act with the machine’s permissions. IMDSv2 requires a session token and a hop limit that block this scenario. Disabling version 1 is a one-setting fix.

In 2019, an attacker extracted more than a hundred million customer records from a large US bank. No malware, no stolen password. A misconfigured web application firewall, a request to a local address, and the credentials of an over-broad role. That scenario is still one of the most frequent on cloud accounts today, and one of the simplest to close.

What the metadata service is

Every instance in a cloud can query a local address (169.254.169.254 at AWS, with equivalents at the other providers) to learn its identity, its configuration and, above all, the temporary credentials of the role attached to it. That is how an application reads a bucket or a database without a hard-coded password: it asks the metadata service for its credentials.

The mechanism is indispensable. The problem is whom it answers.

IMDSv1: a GET request is enough

In its first version, the service answers any GET request coming from the instance. Anything able to make an HTTP request from the machine gets the credentials: the application, but also an attacker who controls the URL it calls.

That is the role of SSRF (Server-Side Request Forgery), an ordinary web flaw: the application accepts an address supplied by the user and fetches it itself. An “avatar URL” field, an image proxy, a test webhook, a document converter. The attacker supplies the local address of the metadata service, the application visits it, and returns the credentials in its response.

With those credentials, the attacker acts as the machine, from anywhere, until they expire. If the machine’s role can list and read buckets, they read the buckets. If it can assume other roles, they climb.

IMDSv2: a token and a hop limit

The second version of the service fixes precisely this. You must first obtain a session token with a PUT request carrying a dedicated header, then present that token with every request. Two details make SSRF inoperative.

  • A classic SSRF can only make GETs with the application’s headers: it cannot obtain the token.
  • The PUT response carries a network hop limit of 1 by default: it does not cross a container, a proxy or an intermediate routing layer.

Enforcing IMDSv2 on an instance is a single setting: “metadata tokens: required”. Other clouds have their equivalents, and most modern agents and libraries use version 2 on their own.

Why it is still everywhere

Because the option defaults to “optional” on many older images, because migrating means checking that nothing old still calls version 1, and because an instance setting appears in no application-security dashboard. The web team does not see it, the infrastructure team does not know which application runs on it.

How to check

  1. List the instances whose metadata tokens are “optional”.
  2. Cross with exposure: which ones have a public address, or sit behind a public load balancer.
  3. Cross with the attached role: which ones can reach data, keys, other roles.
  4. Start with those that combine all three. Enforce version 2 on everything else as you redeploy.

That is exactly a toxic combination: a public instance, IMDSv1, a role that reads sensitive data. Each element is a routine setting; together, it is the 2019 case. In Ctadel, this chain is part of the attack-path catalogue, with the three possible fixes in order of least effort. The Attack paths page describes how it is evaluated.

See it on your accounts

The online demonstration is open to all, on fictitious data. For an instance on your own accounts, request a demonstration.