Skip to content

Commit cb0d2a2

Browse files
authored
fix(core): Add rate limiting to mcp-oauth endpoints (n8n-io#24734)
1 parent 60cd62c commit cb0d2a2

1 file changed

Lines changed: 17 additions & 2 deletions

File tree

packages/cli/src/modules/mcp/mcp.oauth.controller.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { authorizationHandler } from '@modelcontextprotocol/sdk/server/auth/hand
22
import { clientRegistrationHandler } from '@modelcontextprotocol/sdk/server/auth/handlers/register.js';
33
import { revocationHandler } from '@modelcontextprotocol/sdk/server/auth/handlers/revoke.js';
44
import { tokenHandler } from '@modelcontextprotocol/sdk/server/auth/handlers/token.js';
5+
import { Time } from '@n8n/constants';
56
import { Get, Options, RootLevelController, StaticRouterMetadata } from '@n8n/decorators';
67
import { Container } from '@n8n/di';
78
import type { Response, Request, Router } from 'express';
@@ -29,31 +30,43 @@ export class McpOAuthController {
2930
path: '/mcp-oauth/register',
3031
router: clientRegistrationHandler({ clientsStore: mcpOAuthService.clientsStore }) as Router,
3132
skipAuth: true,
33+
ipRateLimit: { limit: 10, windowMs: 5 * Time.minutes.toMilliseconds },
3234
},
3335
{
3436
path: '/mcp-oauth/authorize',
3537
router: authorizationHandler({ provider: mcpOAuthService }) as Router,
3638
skipAuth: true,
39+
ipRateLimit: { limit: 50, windowMs: 5 * Time.minutes.toMilliseconds },
3740
},
3841
{
3942
path: '/mcp-oauth/token',
4043
router: tokenHandler({ provider: mcpOAuthService }) as Router,
4144
skipAuth: true,
45+
ipRateLimit: { limit: 20, windowMs: 5 * Time.minutes.toMilliseconds },
4246
},
4347
{
4448
path: '/mcp-oauth/revoke',
4549
router: revocationHandler({ provider: mcpOAuthService }) as Router,
4650
skipAuth: true,
51+
ipRateLimit: { limit: 30, windowMs: 5 * Time.minutes.toMilliseconds },
4752
},
4853
];
4954

50-
@Options('/.well-known/oauth-authorization-server', { skipAuth: true, usesTemplates: true })
55+
@Options('/.well-known/oauth-authorization-server', {
56+
skipAuth: true,
57+
usesTemplates: true,
58+
ipRateLimit: { limit: 100, windowMs: 5 * Time.minutes.toMilliseconds },
59+
})
5160
metadataOptions(_req: Request, res: Response) {
5261
this.setCorsHeaders(res);
5362
res.status(204).end();
5463
}
5564

56-
@Get('/.well-known/oauth-authorization-server', { skipAuth: true, usesTemplates: true })
65+
@Get('/.well-known/oauth-authorization-server', {
66+
skipAuth: true,
67+
usesTemplates: true,
68+
ipRateLimit: { limit: 100, windowMs: 5 * Time.minutes.toMilliseconds },
69+
})
5770
metadata(_req: Request, res: Response) {
5871
this.setCorsHeaders(res);
5972

@@ -77,6 +90,7 @@ export class McpOAuthController {
7790
@Options('/.well-known/oauth-protected-resource/mcp-server/http', {
7891
skipAuth: true,
7992
usesTemplates: true,
93+
ipRateLimit: { limit: 100, windowMs: 5 * Time.minutes.toMilliseconds },
8094
})
8195
protectedResourceMetadataOptions(_req: Request, res: Response) {
8296
this.setCorsHeaders(res);
@@ -86,6 +100,7 @@ export class McpOAuthController {
86100
@Get('/.well-known/oauth-protected-resource/mcp-server/http', {
87101
skipAuth: true,
88102
usesTemplates: true,
103+
ipRateLimit: { limit: 100, windowMs: 5 * Time.minutes.toMilliseconds },
89104
})
90105
protectedResourceMetadata(_req: Request, res: Response) {
91106
this.setCorsHeaders(res);

0 commit comments

Comments
 (0)