diff --git a/scripts/crabbox-untrusted-bootstrap.sh b/scripts/crabbox-untrusted-bootstrap.sh index c2baf4676030..6736ce2eb19d 100755 --- a/scripts/crabbox-untrusted-bootstrap.sh +++ b/scripts/crabbox-untrusted-bootstrap.sh @@ -13,12 +13,12 @@ shift unset NODE_OPTIONS imds_token="$( - /usr/bin/curl -fsS -X PUT \ + /usr/bin/curl -fsS --connect-timeout 2 --max-time 5 -X PUT \ -H "X-aws-ec2-metadata-token-ttl-seconds: 60" \ http://169.254.169.254/latest/api/token )" iam_status="$( - /usr/bin/curl -sS -o /dev/null -w "%{http_code}" \ + /usr/bin/curl -sS --connect-timeout 2 --max-time 5 -o /dev/null -w "%{http_code}" \ -H "X-aws-ec2-metadata-token: ${imds_token}" \ http://169.254.169.254/latest/meta-data/iam/security-credentials/ )" diff --git a/test/scripts/crabbox-untrusted-bootstrap.test.ts b/test/scripts/crabbox-untrusted-bootstrap.test.ts new file mode 100644 index 000000000000..49e582a4f6e9 --- /dev/null +++ b/test/scripts/crabbox-untrusted-bootstrap.test.ts @@ -0,0 +1,18 @@ +// Crabbox untrusted bootstrap tests cover the pre-execution identity boundary. +import { readFileSync } from "node:fs"; +import { describe, expect, it } from "vitest"; + +describe("scripts/crabbox-untrusted-bootstrap.sh", () => { + it("bounds both IMDSv2 identity requests", () => { + const script = readFileSync("scripts/crabbox-untrusted-bootstrap.sh", "utf8"); + const imdsRequests = script.match( + /\/usr\/bin\/curl[\s\S]*?http:\/\/169\.254\.169\.254[^\n]*/gu, + ); + + expect(imdsRequests).toHaveLength(2); + for (const request of imdsRequests ?? []) { + expect(request).toContain("--connect-timeout 2"); + expect(request).toContain("--max-time 5"); + } + }); +});