Conversation
… e correção de erro de import no pdf export
…DTOs correspondentes
…ica de inscrições e respostas
| * Se é só um filename legado, reconstrói com userId. | ||
| */ | ||
| private resolveObjectKey(key: string, userId?: string): string { | ||
| if (key.includes('/')) { |
Check failure
Code scanning / CodeQL
Type confusion through parameter tampering Critical
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 month ago
In general, to fix this class of problem you must validate the runtime type of any user-controlled value before calling string methods or using it in string concatenation, and reject or sanitize unexpected types (like arrays or objects). For query parameters in Express/NestJS this usually means: if the value is not a string, return a 400 Bad Request.
Here, the best fix with minimal behavioral change is:
- In
MinioClientController, ensure thatobjectKeyfrom@Query('key')is a single string and not an array or other type. If it is not a string or is empty, throwBadRequestException. Because all existing service methods already assume a string, doing this at the controller boundary centralizes validation and avoids needing extra checks deeper in the service. - Optionally, we can keep
MinioClientService.resolveObjectKeyas-is, because after the controller fixes, it will only receive strings. However, for extra safety, we can makeresolveObjectKeyrobust by guarding itsincludescall with a simple string check and throwing aBadRequestExceptionfor unexpected types. This ensures future callers within the service cannot accidentally pass a non-string.
Concretely:
- In
src/minio/minio.controller.ts, updateviewDocumentto:- Check
typeof objectKey !== 'string'and reject withBadRequestException. - Keep the existing “empty” check, but now it runs only for valid strings.
- Check
- Add a similar runtime type check to
getPresignedUrl. - In
src/minio/minio.service.ts, updateresolveObjectKeyto:- Throw
BadRequestExceptioniftypeof key !== 'string'orkeyis empty-ish. - Only then call
key.includes('/')and build paths.
- Throw
No new methods are strictly required beyond using the already imported BadRequestException. There are no new imports needed.
| @@ -175,6 +175,9 @@ | ||
| * Se é só um filename legado, reconstrói com userId. | ||
| */ | ||
| private resolveObjectKey(key: string, userId?: string): string { | ||
| if (typeof key !== 'string' || !key) { | ||
| throw new BadRequestException('Parâmetro "key" inválido'); | ||
| } | ||
| if (key.includes('/')) { | ||
| return key; | ||
| } |
| @@ -47,10 +47,15 @@ | ||
| */ | ||
| @Get('view') | ||
| async viewDocument( | ||
| @Query('key') objectKey: string, | ||
| @Query('key') objectKey: string | string[], | ||
| @Req() request: AuthenticatedRequest, | ||
| @Res() res: Response, | ||
| ) { | ||
| if (typeof objectKey !== 'string') { | ||
| throw new BadRequestException( | ||
| 'Parâmetro "key" deve ser uma string única', | ||
| ); | ||
| } | ||
| if (!objectKey) { | ||
| throw new BadRequestException('Parâmetro "key" é obrigatório'); | ||
| } | ||
| @@ -72,7 +74,12 @@ | ||
| * Ex: GET /documents/presigned?key=userId/documentos/1234_abc123.pdf | ||
| */ | ||
| @Get('presigned') | ||
| async getPresignedUrl(@Query('key') objectKey: string) { | ||
| async getPresignedUrl(@Query('key') objectKey: string | string[]) { | ||
| if (typeof objectKey !== 'string') { | ||
| throw new BadRequestException( | ||
| 'Parâmetro "key" deve ser uma string única', | ||
| ); | ||
| } | ||
| if (!objectKey) { | ||
| throw new BadRequestException('Parâmetro "key" é obrigatório'); | ||
| } |
No description provided.