fix: add input validation constraints for service names, file paths, uploads, and settings keys

- system.ts: Add maxLength(100) and alphanumeric/hyphen/underscore regex to service_name fields
- system.ts: Add maxLength(50) and semver/Docker tag regex to target_version field
- rag.ts: Add maxLength(500) to filePath field
- rag_controller.ts: Add 50MB file upload size limit and validation error handling
- settings_controller.ts: Validate getSetting() key parameter against KV_STORE_SCHEMA at runtime

https://claude.ai/code/session_01JFvpTYgm8GiE4vJ4cJKsFx
This commit is contained in:
Claude 2026-03-24 09:28:06 +00:00
parent b5f41e4ed5
commit 6058fd31a0
No known key found for this signature in database
4 changed files with 15 additions and 7 deletions

View File

@ -12,11 +12,15 @@ export default class RagController {
constructor(private ragService: RagService) { }
public async upload({ request, response }: HttpContext) {
const uploadedFile = request.file('file')
const uploadedFile = request.file('file', { size: '50mb' })
if (!uploadedFile) {
return response.status(400).json({ error: 'No file uploaded' })
}
if (!uploadedFile.isValid) {
return response.status(422).json({ errors: uploadedFile.errors })
}
const randomSuffix = randomBytes(6).toString('hex')
const sanitizedName = sanitizeFilename(uploadedFile.clientName)

View File

@ -6,7 +6,7 @@ import { SystemService } from '#services/system_service';
import { updateSettingSchema } from '#validators/settings';
import { inject } from '@adonisjs/core';
import type { HttpContext } from '@adonisjs/core/http'
import type { KVStoreKey } from '../../types/kv_store.js';
import { KV_STORE_SCHEMA, type KVStoreKey } from '../../types/kv_store.js';
@inject()
export default class SettingsController {
@ -104,6 +104,10 @@ export default class SettingsController {
async getSetting({ request, response }: HttpContext) {
const key = request.qs().key;
const validKeys = Object.keys(KV_STORE_SCHEMA);
if (!key || !validKeys.includes(key)) {
return response.status(400).send({ error: `Invalid setting key. Valid keys: ${validKeys.join(', ')}` });
}
const value = await KVStore.getValue(key as KVStoreKey);
return response.status(200).send({ key, value });
}

View File

@ -2,7 +2,7 @@ import vine from '@vinejs/vine'
export const getJobStatusSchema = vine.compile(
vine.object({
filePath: vine.string(),
filePath: vine.string().maxLength(500),
})
)

View File

@ -2,13 +2,13 @@ import vine from '@vinejs/vine'
export const installServiceValidator = vine.compile(
vine.object({
service_name: vine.string().trim(),
service_name: vine.string().trim().maxLength(100).regex(/^[a-zA-Z0-9_-]+$/),
})
)
export const affectServiceValidator = vine.compile(
vine.object({
service_name: vine.string().trim(),
service_name: vine.string().trim().maxLength(100).regex(/^[a-zA-Z0-9_-]+$/),
action: vine.enum(['start', 'stop', 'restart']),
})
)
@ -27,7 +27,7 @@ export const checkLatestVersionValidator = vine.compile(
export const updateServiceValidator = vine.compile(
vine.object({
service_name: vine.string().trim(),
target_version: vine.string().trim(),
service_name: vine.string().trim().maxLength(100).regex(/^[a-zA-Z0-9_-]+$/),
target_version: vine.string().trim().maxLength(50).regex(/^[a-zA-Z0-9._-]+$/),
})
)