fix(cursor): block cross-origin runtime probe requests (#1371)

This commit is contained in:
Kai (Tam Nhu) Tran
2026-05-23 21:44:50 -04:00
committed by GitHub
parent 37fdf90e30
commit e6f764c79b
2 changed files with 18 additions and 1 deletions
+7 -1
View File
@@ -18,6 +18,7 @@ import {
import cursorSettingsRoutes from './cursor-settings-routes'; import cursorSettingsRoutes from './cursor-settings-routes';
import { getCursorConfig } from '../../config/config-loader-facade'; import { getCursorConfig } from '../../config/config-loader-facade';
import { isDashboardWebSocketOriginAllowed } from '../middleware/auth-middleware';
const router = Router(); const router = Router();
@@ -192,7 +193,12 @@ router.get('/models', async (_req: Request, res: Response): Promise<void> => {
/** /**
* POST /api/cursor/probe - Run a live authenticated runtime probe * POST /api/cursor/probe - Run a live authenticated runtime probe
*/ */
router.post('/probe', async (_req: Request, res: Response): Promise<void> => { router.post('/probe', async (req: Request, res: Response): Promise<void> => {
if (!isDashboardWebSocketOriginAllowed(req)) {
res.status(403).json({ error: 'Cross-origin probe requests are not allowed.' });
return;
}
try { try {
const cursorConfig = getCursorConfig(); const cursorConfig = getCursorConfig();
const result = await probeCursorRuntime(cursorConfig); const result = await probeCursorRuntime(cursorConfig);
@@ -510,6 +510,17 @@ describe('Cursor Routes Logic', () => {
expect(json.current).toBe('gpt-5.3-codex'); expect(json.current).toBe('gpt-5.3-codex');
}); });
it('POST /api/cursor/probe rejects cross-origin requests', async () => {
const res = await fetch(`${baseUrl}/api/cursor/probe`, {
method: 'POST',
headers: { Origin: 'https://attacker.example' },
});
expect(res.status).toBe(403);
const json = (await res.json()) as { error?: string };
expect(json.error).toContain('Cross-origin probe requests are not allowed.');
});
it('POST /api/cursor/probe returns auth failure when credentials are missing', async () => { it('POST /api/cursor/probe returns auth failure when credentials are missing', async () => {
const res = await fetch(`${baseUrl}/api/cursor/probe`, { method: 'POST' }); const res = await fetch(`${baseUrl}/api/cursor/probe`, { method: 'POST' });
expect(res.status).toBe(401); expect(res.status).toBe(401);