HexBrain

AWS VDP · Report #3630605

Kiro IDE Stores Auth Tokens with World-Readable Permissions (0644)

Validstatus
mediumseverity
54upvotes
9 Jul 2026disclosed

How it was found

NOTE! Thanks for submitting a report to Amazon Web Services! Please replace all the [square] sections below with the pertinent details. Remember, the more detail you provide, the easier it is for us to triage and respond quickly, so be sure to take your time filling out the report!

Description: Kiro IDE (v0.11.107) writes authentication tokens (access token + refresh token) to ~/.aws/sso/cache/kiro-auth-token.json with file permissions 0644 (world-readable). Any local process or user can read the file and steal the bearer tokens, which grant full access to the CodeWhisperer/Q Developer API (agentic chat, code generation, account operations).

This is inconsistent with AWS's own behavior: the AWS CLI stores its SSO tokens in the same directory with 0600 permissions. Kiro itself uses the macOS Keychain (via VS Code secretStorage) for MCP OAuth credentials, proving the secure pattern is known and available in the codebase.

This is one of six vulnerabilities I am reporting in Kiro IDE. Related submissions cover: extension-to-agent privilege escalation (CWE-862), hook command injection (CWE-78), askAgent forced Autopilot bypass (CWE-862), MCP workspace config override (CWE-78/CWE-862), and symlink token redirect (CWE-59). Line numbers reference the minified extension.js in Kiro v0.11.107 (build 672afb51e5336b149eb9fc381dd6db6908edbc61).

Steps To Reproduce:

  1. Authenticate to Kiro normally (sign in via GitHub or AWS Builder ID).

  2. Check the token file permissions:

stat -f "%Op %Sp %N" ~/.aws/sso/cache/*.json

Output:

100600 -rw------- ~/.aws/sso/cache/REDACTED_HASH_1.json  (AWS CLI - correct)
100600 -rw------- ~/.aws/sso/cache/REDACTED_HASH_2.json  (AWS CLI - correct)
100644 -rw-r--r-- ~/.aws/sso/cache/kiro-auth-token.json  (Kiro - world-readable)
  1. Confirm the file contains plaintext credentials:
cat ~/.aws/sso/cache/kiro-auth-token.json

{
  "accessToken": "aoaAAAAAGnFf...",
  "refreshToken": "aorAAAAAGo8F...",
  "profileArn": "arn:aws:codewhisperer:us-east-1:REDACTED:profile/REDACTED",
  "expiresAt": "2026-03-26T18:44:44.275Z",
  "authMethod": "social",
  "provider": "Github"
}
  1. Confirm Node.js default creates 0644:
node -e "const fs=require('fs'); const p='/tmp/test.json'; fs.writeFileSync(p,'test'); console.log((fs.statSync(p).mode & 0o777).toString(8)); fs.unlinkSync(p);"
# Output: 644

Impact

Summary:

The stolen token grants access to CodeWhispererRuntimeClient operations: CreateSession, SendMessage (full agentic chat), GenerateCompletions, ListAvailableModels, GetUsageLimits, CreateSubscriptionToken, CreateArtifactUploadUrl. An attacker can impersonate the victim, consume their credits, exhaust free tier limits, and access code context from the victim's sessions.

Most realistic attack vector: A malicious or typosquatted Kiro/VS Code extension reads the world-readable token file and exfiltrates it. Kiro's extension host runs with allow-unsigned-executable-memory and disable-library-validation entitlements, and extensions run with the user's full permissions.

Root Cause: The TokenStorage class (extension.js, line 504375) uses fs.writeFileSync() without a mode parameter, defaults to 0666, masked by umask 022 = 0644. No post-write chmod is applied.

Recommended Fix: Add { mode: 0o600 } to writeFileSync, or migrate to VS Code secretStorage (OS Keychain) consistent with the existing MCP OAuth credential storage path.

For awareness, we plan to publish a blog post detailing these findings after remediation. We are happy to share a draft ahead of publication and coordinate on timing. We would appreciate coordination on public disclosure timing, including whether AWS plans to publish a Security Bulletin consistent with the handling of CVE-2026-0830 and CVE-2026-4295.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original