Fix pagination bypass and fail-open bugs in .mcp.json change detection

- Use octokit.rest.paginate() to fetch all pages of PR changed files,
  preventing attackers from padding PRs with 100+ files to push .mcp.json
  off the first page
- Change catch block to fail closed (mcpJsonChanged=true) so MCP servers
  are not auto-approved when the API call fails
This commit is contained in:
Ashwin Bhat 2026-02-15 12:44:24 -08:00
parent 19a4f34b17
commit f4ac33b9a4
No known key found for this signature in database

View File

@ -223,12 +223,15 @@ async function run() {
let mcpJsonChanged = false; let mcpJsonChanged = false;
if (isEntityContext(context) && context.isPR) { if (isEntityContext(context) && context.isPR) {
try { try {
const { data: changedFiles } = await octokit.rest.pulls.listFiles({ const changedFiles = await octokit.rest.paginate(
owner: context.repository.owner, octokit.rest.pulls.listFiles,
repo: context.repository.repo, {
pull_number: context.entityNumber, owner: context.repository.owner,
per_page: 100, repo: context.repository.repo,
}); pull_number: context.entityNumber,
per_page: 100,
},
);
mcpJsonChanged = changedFiles.some( mcpJsonChanged = changedFiles.some(
(f) => (f) =>
f.filename === ".mcp.json" || f.filename.endsWith("/.mcp.json"), f.filename === ".mcp.json" || f.filename.endsWith("/.mcp.json"),
@ -240,8 +243,9 @@ async function run() {
} }
} catch (e) { } catch (e) {
console.log( console.log(
`Could not check PR changed files: ${e}. Defaulting to mcpJsonChanged=false.`, `Could not check PR changed files: ${e}. Defaulting to mcpJsonChanged=true (fail-closed).`,
); );
mcpJsonChanged = true;
} }
} }