Skip to content

Build1 publisher3 min readPublished

CVE-2026-89049 converts a port-forwarding permission into instance-role credentials

AWS fixed an SSRF in SSM Agent 3.3.4851.0. How much the bug actually gave an attacker depends on your IAM layout, and CloudTrail's StartSession records already show who called the vulnerable document.

The Engineer · Build desk

Illustration accompanying CVE-2026-89049 converts a port-forwarding permission into instance-role credentials

What happened

  • AWS disclosed CVE-2026-89049 on September 10, 2026, a server-side request forgery bug in the remote-host port forwarding functionality of the Systems Manager Agent.
  • The bug is rated CVSS 9.9 and is fixed in SSM Agent 3.3.4851.0, with every earlier agent version affected.
  • CloudTrail logs the StartSession call with its target instance, document name, remote host and ports, but not the tunnel traffic or whether the agent connected.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • decision How urgently to patch is an IAM question: the post says the incremental impact depends heavily on how Session Manager permissions are configured.
  • exposure The principals this reaches are the ones an organisation fenced off on purpose, such as a developer with tunnel rights to a database and no shell on the bastion whose role credentials were in range.
  • constraint An incident review cannot close on the log alone, because the record shows the destination requested and not whether credentials left the instance.
  • cost Anyone running the audit pays in manual review time, since a string filter on destination addresses is unsafe and every matching event has to be read.

The call tells the SSM Agent running on a managed instance to open a TCP connection to a host and port the caller names, then hands the caller a local port at the other end. The dev.to post names RDS as one possible destination and says the vulnerable functionality is not limited to RDS [7]. A denylist is supposed to keep that destination off the link-local range. Before agent version 3.3.4851.0, an authenticated principal holding AWS-StartPortForwardingSessionToRemoteHost could get past the denylist with an equivalent representation of a link-local address [3][4]. The tunnel then terminates on the EC2 instance metadata service, and what comes back can include the instance profile's temporary IAM credentials [5]. Those work from outside the instance until they expire, and what they can do is bounded by the permissions attached to the instance role [6].

If the principal who can open the tunnel can also open a Session Manager shell or use SSM Run Command on the same instance, that principal could already reach IMDS from inside the box, and the post says the CVE may then provide little additional access and the update may reasonably be assigned lower priority [9]. Where an organisation split those permissions on purpose, the reading changes. The post's example is a developer permitted to create a port-forwarding session to an internal database while being denied shell access and Run Command on the bastion instance itself [10]. In that environment, the author wrote, "this vulnerability crosses an intentional security boundary: permission to establish a TCP tunnel can potentially become access to the instance profile's IAM credentials" [11].

The deprioritisation advice therefore transfers only under one condition: every principal holding that document permission also holds shell or Run Command on every instance it can target [18]. Answering that means listing the principals whose policies allow StartSession with AWS-StartPortForwardingSessionToRemoteHost, then comparing that list against the principals with shell and Run Command on the same targets [17].

CloudTrail's StartSession events carry the target instance, the document name, the remote host, the remote port and the local port [12]. What they leave out is the tunnel traffic and whether the agent connected to the requested destination [13]. A matching event shows that someone asked for a tunnel to a particular string. What came back through it is bounded by the instance role's permissions [6].

Grepping for a literal IMDS address is the wrong query. Equivalent IP representations get past string matching, and the value CloudTrail stores is the original string the caller supplied, so the post recommends reviewing every matching event [14]. Where the document is rarely used at all, it says the clearest starting point is to search for all uses of AWS-StartPortForwardingSessionToRemoteHost [20].

In the console that path is Event History, Event name under Lookup attributes, then a search for StartSession, and with a long result list you open each event individually to inspect its request parameters [15]. One event per click is fine for five events. The post's own run used the CLI instead: aws cloudtrail lookup-events with AttributeKey=EventName,AttributeValue=StartSession against ap-northeast-1, output piped into jq, with the note that CloudTrail Lake could also be used but the author does not use it in a personal environment [16].

What to watch

  • Whether AWS publishes which address representations defeated the denylist; that would make log review cheaper than opening every StartSession event.
  • Whether fleets running with SSM Agent auto-update disabled actually reach 3.3.4851.0, and how long the rollout takes.
  • Whether any organisation reports a StartSession event whose recorded remote host is a link-local destination.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories