From 4638cd713dcdd007cd7f49b9a95fa62ac7823e7c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 15 Nov 2022 14:41:55 +0100 Subject: Don't inject untrusted input Even if it's already checked in middlewares It's better to have safe modals too --- server/controllers/api/users/my-history.ts | 3 ++- server/controllers/api/users/my-video-playlists.ts | 5 +++-- server/controllers/api/video-playlist.ts | 5 +++-- server/controllers/api/videos/update.ts | 3 ++- server/controllers/download.ts | 4 ++-- server/controllers/services.ts | 5 +++-- 6 files changed, 15 insertions(+), 10 deletions(-) (limited to 'server/controllers') diff --git a/server/controllers/api/users/my-history.ts b/server/controllers/api/users/my-history.ts index bc5b40f59..e6d3e86ac 100644 --- a/server/controllers/api/users/my-history.ts +++ b/server/controllers/api/users/my-history.ts @@ -1,3 +1,4 @@ +import { forceNumber } from '@shared/core-utils' import express from 'express' import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes' import { getFormattedObjects } from '../../../helpers/utils' @@ -55,7 +56,7 @@ async function listMyVideosHistory (req: express.Request, res: express.Response) async function removeUserHistoryElement (req: express.Request, res: express.Response) { const user = res.locals.oauth.token.User - await UserVideoHistoryModel.removeUserHistoryElement(user, parseInt(req.params.videoId + '')) + await UserVideoHistoryModel.removeUserHistoryElement(user, forceNumber(req.params.videoId)) return res.sendStatus(HttpStatusCode.NO_CONTENT_204) } diff --git a/server/controllers/api/users/my-video-playlists.ts b/server/controllers/api/users/my-video-playlists.ts index 715717610..fbdbb7e50 100644 --- a/server/controllers/api/users/my-video-playlists.ts +++ b/server/controllers/api/users/my-video-playlists.ts @@ -1,5 +1,6 @@ -import { uuidToShort } from '@shared/extra-utils' import express from 'express' +import { forceNumber } from '@shared/core-utils' +import { uuidToShort } from '@shared/extra-utils' import { VideosExistInPlaylists } from '../../../../shared/models/videos/playlist/video-exist-in-playlist.model' import { asyncMiddleware, authenticate } from '../../../middlewares' import { doVideosInPlaylistExistValidator } from '../../../middlewares/validators/videos/video-playlists' @@ -22,7 +23,7 @@ export { // --------------------------------------------------------------------------- async function doVideosInPlaylistExist (req: express.Request, res: express.Response) { - const videoIds = req.query.videoIds.map(i => parseInt(i + '', 10)) + const videoIds = req.query.videoIds.map(i => forceNumber(i)) const user = res.locals.oauth.token.User const results = await VideoPlaylistModel.listPlaylistSummariesOf(user.Account.id, videoIds) diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts index 1255d14c6..67fac3751 100644 --- a/server/controllers/api/video-playlist.ts +++ b/server/controllers/api/video-playlist.ts @@ -46,6 +46,7 @@ import { import { AccountModel } from '../../models/account/account' import { VideoPlaylistModel } from '../../models/video/video-playlist' import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element' +import { forceNumber } from '@shared/core-utils' const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT) @@ -245,7 +246,7 @@ async function updateVideoPlaylist (req: express.Request, res: express.Response) if (videoPlaylistInfoToUpdate.description !== undefined) videoPlaylistInstance.description = videoPlaylistInfoToUpdate.description if (videoPlaylistInfoToUpdate.privacy !== undefined) { - videoPlaylistInstance.privacy = parseInt(videoPlaylistInfoToUpdate.privacy.toString(), 10) + videoPlaylistInstance.privacy = forceNumber(videoPlaylistInfoToUpdate.privacy) if (wasNotPrivatePlaylist === true && videoPlaylistInstance.privacy === VideoPlaylistPrivacy.PRIVATE) { await sendDeleteVideoPlaylist(videoPlaylistInstance, t) @@ -424,7 +425,7 @@ async function reorderVideosPlaylist (req: express.Request, res: express.Respons const endOldPosition = oldPosition + reorderLength - 1 // Insert our reordered elements in their place (update) - await VideoPlaylistElementModel.reassignPositionOf(videoPlaylist.id, oldPosition, endOldPosition, newPosition, t) + await VideoPlaylistElementModel.reassignPositionOf({ videoPlaylistId: videoPlaylist.id, firstPosition: oldPosition, endPosition: endOldPosition, newPosition, transaction: t }) // Decrease positions of elements after the old position of our ordered elements (decrease) await VideoPlaylistElementModel.increasePositionOf(videoPlaylist.id, oldPosition, -reorderLength, t) diff --git a/server/controllers/api/videos/update.ts b/server/controllers/api/videos/update.ts index 0a910379a..260dee2b9 100644 --- a/server/controllers/api/videos/update.ts +++ b/server/controllers/api/videos/update.ts @@ -19,6 +19,7 @@ import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videosU import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update' import { VideoModel } from '../../../models/video/video' import { VideoPathManager } from '@server/lib/video-path-manager' +import { forceNumber } from '@shared/core-utils' const lTags = loggerTagsFactory('api', 'video') const auditLogger = auditLoggerFactory('videos') @@ -174,7 +175,7 @@ async function updateVideoPrivacy (options: { const { videoInstance, videoInfoToUpdate, hadPrivacyForFederation, transaction } = options const isNewVideo = videoInstance.isNewVideo(videoInfoToUpdate.privacy) - const newPrivacy = parseInt(videoInfoToUpdate.privacy.toString(), 10) + const newPrivacy = forceNumber(videoInfoToUpdate.privacy) setVideoPrivacy(videoInstance, newPrivacy) // Unfederate the video if the new privacy is not compatible with federation diff --git a/server/controllers/download.ts b/server/controllers/download.ts index d9f34109f..65b9a1d1b 100644 --- a/server/controllers/download.ts +++ b/server/controllers/download.ts @@ -5,7 +5,7 @@ import { VideosTorrentCache } from '@server/lib/files-cache/videos-torrent-cache import { Hooks } from '@server/lib/plugins/hooks' import { VideoPathManager } from '@server/lib/video-path-manager' import { MStreamingPlaylist, MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' -import { addQueryParams } from '@shared/core-utils' +import { addQueryParams, forceNumber } from '@shared/core-utils' import { HttpStatusCode, VideoStorage, VideoStreamingPlaylistType } from '@shared/models' import { STATIC_DOWNLOAD_PATHS } from '../initializers/constants' import { asyncMiddleware, optionalAuthenticate, videosDownloadValidator } from '../middlewares' @@ -132,7 +132,7 @@ async function downloadHLSVideoFile (req: express.Request, res: express.Response } function getVideoFile (req: express.Request, files: MVideoFile[]) { - const resolution = parseInt(req.params.resolution, 10) + const resolution = forceNumber(req.params.resolution) return files.find(f => f.resolution === resolution) } diff --git a/server/controllers/services.ts b/server/controllers/services.ts index cabcbc00b..7c7ca1ff3 100644 --- a/server/controllers/services.ts +++ b/server/controllers/services.ts @@ -4,6 +4,7 @@ import { escapeHTML } from '@shared/core-utils/renderer' import { EMBED_SIZE, PREVIEWS_SIZE, THUMBNAILS_SIZE, WEBSERVER } from '../initializers/constants' import { asyncMiddleware, oembedValidator } from '../middlewares' import { accountNameWithHostGetValidator } from '../middlewares/validators' +import { forceNumber } from '@shared/core-utils' const servicesRouter = express.Router() @@ -108,8 +109,8 @@ function buildOEmbed (options: { const { req, previewSize, previewPath, title, channel, embedPath } = options const webserverUrl = WEBSERVER.URL - const maxHeight = parseInt(req.query.maxheight, 10) - const maxWidth = parseInt(req.query.maxwidth, 10) + const maxHeight = forceNumber(req.query.maxheight) + const maxWidth = forceNumber(req.query.maxwidth) const embedUrl = webserverUrl + embedPath const embedTitle = escapeHTML(title) -- cgit v1.2.3