Skip to content

Commit 65308e4

Browse files
committed
fix(microsoft-excel): use centralized input validation
Replace inline regex validation with platform validators from @/lib/core/security/input-validation: - validateSharePointSiteId for siteId in drives route - validateAlphanumericId for driveId in drives, sheets, files routes and getItemBasePath utility
1 parent f18af3c commit 65308e4

5 files changed

Lines changed: 27 additions & 11 deletions

File tree

apps/sim/app/api/auth/oauth/microsoft/files/route.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createLogger } from '@sim/logger'
22
import { type NextRequest, NextResponse } from 'next/server'
33
import { authorizeCredentialUse } from '@/lib/auth/credential-access'
4+
import { validateAlphanumericId } from '@/lib/core/security/input-validation'
45
import { generateRequestId } from '@/lib/core/utils/request'
56
import { getCredential, refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils'
67

@@ -75,8 +76,11 @@ export async function GET(request: NextRequest) {
7576

7677
// When driveId is provided (SharePoint), search within that specific drive.
7778
// Otherwise, search the user's personal OneDrive.
78-
if (driveId && !/^[\w-]+$/.test(driveId)) {
79-
return NextResponse.json({ error: 'Invalid drive ID format' }, { status: 400 })
79+
if (driveId) {
80+
const driveIdValidation = validateAlphanumericId(driveId, 'driveId')
81+
if (!driveIdValidation.isValid) {
82+
return NextResponse.json({ error: driveIdValidation.error }, { status: 400 })
83+
}
8084
}
8185
const drivePath = driveId ? `drives/${driveId}` : 'me/drive'
8286

apps/sim/app/api/tools/microsoft_excel/drives/route.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { createLogger } from '@sim/logger'
22
import { type NextRequest, NextResponse } from 'next/server'
33
import { authorizeCredentialUse } from '@/lib/auth/credential-access'
4+
import {
5+
validateAlphanumericId,
6+
validateSharePointSiteId,
7+
} from '@/lib/core/security/input-validation'
48
import { generateRequestId } from '@/lib/core/utils/request'
59
import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils'
610

@@ -37,9 +41,10 @@ export async function POST(request: NextRequest) {
3741
return NextResponse.json({ error: 'Site ID is required' }, { status: 400 })
3842
}
3943

40-
if (!/^[\w.,;:-]+$/.test(siteId)) {
44+
const siteIdValidation = validateSharePointSiteId(siteId, 'siteId')
45+
if (!siteIdValidation.isValid) {
4146
logger.warn(`[${requestId}] Invalid siteId format`)
42-
return NextResponse.json({ error: 'Invalid site ID format' }, { status: 400 })
47+
return NextResponse.json({ error: siteIdValidation.error }, { status: 400 })
4348
}
4449

4550
const authz = await authorizeCredentialUse(request, {
@@ -65,8 +70,9 @@ export async function POST(request: NextRequest) {
6570

6671
// Single-drive lookup when driveId is provided (used by fetchById)
6772
if (driveId) {
68-
if (!/^[\w-]+$/.test(driveId)) {
69-
return NextResponse.json({ error: 'Invalid drive ID format' }, { status: 400 })
73+
const driveIdValidation = validateAlphanumericId(driveId, 'driveId')
74+
if (!driveIdValidation.isValid) {
75+
return NextResponse.json({ error: driveIdValidation.error }, { status: 400 })
7076
}
7177

7278
const url = `https://graph.microsoft.com/v1.0/sites/${siteId}/drives/${driveId}?$select=id,name,driveType,webUrl`

apps/sim/app/api/tools/microsoft_excel/sheets/route.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createLogger } from '@sim/logger'
22
import { type NextRequest, NextResponse } from 'next/server'
33
import { authorizeCredentialUse } from '@/lib/auth/credential-access'
4+
import { validateAlphanumericId } from '@/lib/core/security/input-validation'
45
import { generateRequestId } from '@/lib/core/utils/request'
56
import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils'
67

@@ -62,8 +63,11 @@ export async function GET(request: NextRequest) {
6263
`[${requestId}] Fetching worksheets from Microsoft Graph API for workbook ${spreadsheetId}`
6364
)
6465

65-
if (driveId && !/^[\w-]+$/.test(driveId)) {
66-
return NextResponse.json({ error: 'Invalid drive ID format' }, { status: 400 })
66+
if (driveId) {
67+
const driveIdValidation = validateAlphanumericId(driveId, 'driveId')
68+
if (!driveIdValidation.isValid) {
69+
return NextResponse.json({ error: driveIdValidation.error }, { status: 400 })
70+
}
6771
}
6872

6973
const basePath = driveId

apps/sim/blocks/blocks/microsoft_excel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ export const MicrosoftExcelV2Block: BlockConfig<MicrosoftExcelV2Response> = {
407407
dependsOn: ['credential'],
408408
mode: 'basic',
409409
},
410-
// SharePoint Drive Selector (basic mode, depends on site)
410+
// SharePoint Drive Selector (basic mode, only visible when a site is selected)
411411
{
412412
id: 'driveSelector',
413413
title: 'Document Library',

apps/sim/tools/microsoft_excel/utils.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createLogger } from '@sim/logger'
22
import type { ExcelCellValue } from '@/tools/microsoft_excel/types'
3+
import { validateAlphanumericId } from '@/lib/core/security/input-validation'
34

45
const logger = createLogger('MicrosoftExcelUtils')
56

@@ -10,8 +11,9 @@ const logger = createLogger('MicrosoftExcelUtils')
1011
*/
1112
export function getItemBasePath(spreadsheetId: string, driveId?: string): string {
1213
if (driveId) {
13-
if (!/^[\w-]+$/.test(driveId)) {
14-
throw new Error('Invalid drive ID format')
14+
const validation = validateAlphanumericId(driveId, 'driveId')
15+
if (!validation.isValid) {
16+
throw new Error(validation.error)
1517
}
1618
return `https://graph.microsoft.com/v1.0/drives/${driveId}/items/${spreadsheetId}`
1719
}

0 commit comments

Comments
 (0)