T09 · Insecure Skill Coding Practices
Note
- Location
- references/cost.md:112
- Finding
- Unauthenticated AWS Instance Metadata Service Request<![CDATA[ ## Vulnerability Details **File Location**: `references/cost.md`, lines 112–115 **Vulnerability Type**: Unauthenticated IMDSv1-style metadata access **Risk Level**: Low ### Vulnerable Code ```python # Check for spot termination notice (AWS) import requests def check_spot_termination(): try: response = requests.get( "http://169.254.169.254/latest/meta-data/spot/termination-time", timeout=2 ) if response.status_code == 200: # 2-minute warning - gracefully shutdown graceful_shutdown() except requests.exceptions.RequestException: pass # Not being terminated ``` ### Technical Analysis The example directly queries the AWS Instance Metadata Service over HTTP without first acquiring and supplying an IMDSv2 session token. This is an IMDSv1-style access pattern. The fixed endpoint only returns an EC2 Spot interruption notice; it does not request IAM role credentials, identity documents, or access tokens. Access to this endpoint is relevant to the Skill's declared Spot-instance cost-optimization guidance and does not itself exceed the minimum functional scope. However, the example normalizes unauthenticated access to a security-sensitive metadata service and may encourage users to retain legacy IMDSv1 support. The endpoint is fixed rather than attacker-controlled, and the code does not proxy arbitrary requests. Therefore, this code does not independently create an SSRF vulnerability or directly expose cloud credentials. ### Attack Path 1. An operator copies the example into software running on an EC2 instance. 2. The instance permits unauthenticated IMDSv1 requests. 3. The application successfully uses the legacy metadata-access pattern, reducing pressure to enforce IMDSv2. 4. A separate vulnerable component on the instance—such as an SSRF-prone web application—or a compromised local process gains network access to `169.254.169.254`. 5. That separate weakness may t ...[truncated 914 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace the unauthenticated request with IMDSv2: - Send a `PUT` request to `/latest/api/token`. - Set a short token TTL. - Include the returned token in the `X-aws-ec2-metadata-token` header for the termination-notice request. 2. Configure EC2 launch templates and instances with `HttpTokens=required` to disable IMDSv1. 3. Set the metadata hop limit to the minimum required value, commonly `1`, where container networking requirements permit it. 4. Prefer an AWS-supported interruption-handling component or SDK abstraction where practical. 5. Document that the example is intended only for execution on EC2 Spot instances. 6. Retain strict connection and read timeouts and handle token-request failures safely. 7. Ensure any attached instance profile follows least privilege so that a separate metadata compromise has limited impact. Example hardened approach: ```python import requests IMDS = "http://169.254.169.254/latest" def check_spot_termination(): try: token_response = requests.put( f"{IMDS}/api/token", headers={"X-aws-ec2-metadata-token-ttl-seconds": "21600"}, timeout=2, ) token_response.raise_for_status() response = requests.get( f"{IMDS}/meta-data/spot/termination-time", headers={ "X-aws-ec2-metadata-token": token_response.text, }, timeout=2, ) if response.status_code == 200: graceful_shutdown() except requests.exceptions.RequestException: pass ``` ]]>
