T05 · Unauthorized Access and Privilege Escalation
- Location
index.js:118- Finding
Undocumented Authenticated Pull-Request Creation Capability
- Content
View full analysis
Vulnerability Details
File Location:
index.js:118-133; implementation inapi.js:270-299
Vulnerability Type: Undeclared authenticated repository mutation
Risk Level: MediumVulnerable Code
index.js:118-133exposes the undocumented action:js create_pull_request: { description: 'Create a pull request', parameters: { type: 'object', properties: { owner: { type: 'string', description: 'Repository owner' }, repo: { type: 'string', description: 'Repository name' }, title: { type: 'string', description: 'PR title' }, body: { type: 'string', description: 'PR description' }, head: { type: 'string', description: 'Source branch' }, base: { type: 'string', description: 'Target branch', default: 'main' } }, required: ['owner', 'repo', 'title', 'head'] }, handler: createPullRequestHandler },api.js:270-299implements the authenticated mutation:js async function createPullRequest(args, context) { const username = await getUsername(context); const { owner, repo, title, body, head, base = 'main' } = args; // Use username if owner not specified const prOwner = owner || username; if (!prOwner || !repo || !title || !head) { throw new Error('owner, repo, title, and head are required'); } const url = `${GITHUB_API}/repos/${prOwner}/${repo}/pulls`; const response = await fetch(url, { method: 'POST', headers: getAuthHeaders(context), body: JSON.stringify({ title, body: body || '', head, base }) }); if (!response.ok) { const error = await response.json(); throw new Error(`Failed to create PR: ${error.message || response.status}`); } const pr = await response.json(); return { ...[truncated 2334 chars]- Remediation
View remediation
Remediation Suggestions
- Remove
create_pull_requestfrom the exported action map if pull-request creation is not intended to be part of the Skill. - If the capability is intentional, document it prominently in
SKILL.mdandREADME.md, including its state-changing nature and required GitHub permissions. - Require explicit, action-specific user confirmation immediately before sending the authenticated
POSTrequest. The confirmation should identify the repository, source branch, target branch, and title. - Recommend fine-grained GitHub tokens restricted to selected repositories and only the permissions needed by enabled actions. Avoid recommending a broad classic
repotoken where narrower access is sufficient. - Separate read-only and write-capable actions so deployments can disable repository mutations independently.
- Validate repository and branch identifiers and impose reasonable length limits on pull-request titles and bodies.
- Add audit logging for state-changing actions without logging authorization headers or token values.
- Add tests that verify undocumented mutation actions cannot be exported and that all write operations require confirmation.
- Remove
