T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/todolist_agent_entrypoint.mjs:150
- Finding
- Managed OAuth Requests Unrestricted Google Drive Access<![CDATA[ ## Vulnerability Details **File Location**: `scripts/todolist_agent_entrypoint.mjs:150-177`; `scripts/todolist_drive_folder_agent.mjs:101-129` **Vulnerability Type**: Excessive OAuth permissions **Risk Level**: High ### Vulnerable Code ```javascript // scripts/todolist_agent_entrypoint.mjs async function ensureManagedOAuth({ refreshTokenFile, clientId, clientSecret, authCode }) { // Returns { refresh_token } when available. if (fs.existsSync(refreshTokenFile)) { const existing = JSON.parse(fs.readFileSync(refreshTokenFile, 'utf8')); if (existing?.refresh_token) return existing; } const scopes = ['https://www.googleapis.com/auth/drive']; if (!authCode) { const url = buildAuthUrl({ clientId, scopes }); return { needsAuth: true, authUrl: url, refreshTokenFile, scope: scopes, howTo: `Open the URL, approve, then rerun with: --authCode <CODE>` }; } const tokens = await exchangeAuthCodeForTokens({ clientId, clientSecret, code: authCode }); if (!tokens.refresh_token) { throw new Error('No refresh_token returned. Try again with prompt=consent and ensure you approved access.'); } const toSave = { created_at: new Date().toISOString(), scopes, refresh_token: tokens.refresh_token, }; ``` ```javascript // scripts/todolist_drive_folder_agent.mjs async function ensureManagedOAuth({ refreshTokenFile, clientId, clientSecret, authCode }) { if (fs.existsSync(refreshTokenFile)) { const existing = JSON.parse(fs.readFileSync(refreshTokenFile, 'utf8')); if (existing?.refresh_token) return existing; } const scopes = ['https://www.googleapis.com/auth/drive']; if (!authCode) { const url = buildAuthUrl({ clientId, scopes }); return { needsAuth: true, authUrl: url, refreshTokenFile, scope: scopes, howTo: `Open the URL, approve, then rerun with: --authCode <CODE>` }; } const tokens = await exchangeAuthCodeForTokens({ clientId ...[truncated 2281 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace the unrestricted `drive` scope with `https://www.googleapis.com/auth/drive.file` wherever the workflow can operate on files explicitly selected or created through the application. 2. Use an explicit file-selection or consent workflow so users grant access only to intended todo files. 3. Separate preparation and write-back permissions. Read-only operations should not automatically receive write access. 4. Bind each write operation to a previously selected and validated file. 5. Clearly display the requested scope and affected resources before authorization. 6. Invalidate existing refresh tokens issued with the unrestricted scope after deploying the reduced-scope implementation. 7. Continue storing refresh tokens with restrictive permissions, and avoid returning token values in logs or error messages. ]]>
