1
0
Fork 0

Prevent video import on non unicast ips

This commit is contained in:
Chocobozzz 2022-01-06 11:16:35 +01:00
parent 37a5d6318b
commit 7b54a81ccc
No known key found for this signature in database
GPG key ID: 583A612D890159BE
2 changed files with 46 additions and 0 deletions

View file

@ -13,6 +13,7 @@ import { CONFIG } from '../../../initializers/config'
import { CONSTRAINTS_FIELDS } from '../../../initializers/constants' import { CONSTRAINTS_FIELDS } from '../../../initializers/constants'
import { areValidationErrors, doesVideoChannelOfAccountExist } from '../shared' import { areValidationErrors, doesVideoChannelOfAccountExist } from '../shared'
import { getCommonVideoEditAttributes } from './videos' import { getCommonVideoEditAttributes } from './videos'
import { isValid as isIPValid, parse as parseIP } from 'ipaddr.js'
const videoImportAddValidator = getCommonVideoEditAttributes().concat([ const videoImportAddValidator = getCommonVideoEditAttributes().concat([
body('channelId') body('channelId')
@ -71,6 +72,23 @@ const videoImportAddValidator = getCommonVideoEditAttributes().concat([
return res.fail({ message: 'Should have a magnetUri or a targetUrl or a torrent file.' }) return res.fail({ message: 'Should have a magnetUri or a targetUrl or a torrent file.' })
} }
if (req.body.targetUrl) {
const hostname = new URL(req.body.targetUrl).hostname
if (isIPValid(hostname)) {
const parsed = parseIP(hostname)
if (parsed.range() !== 'unicast') {
cleanUpReqFiles(req)
return res.fail({
status: HttpStatusCode.FORBIDDEN_403,
message: 'Cannot use non unicast IP as targetUrl.'
})
}
}
}
if (!await isImportAccepted(req, res)) return cleanUpReqFiles(req) if (!await isImportAccepted(req, res)) return cleanUpReqFiles(req)
return next() return next()

View file

@ -108,6 +108,34 @@ describe('Test video imports API validator', function () {
await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
}) })
it('Should fail with localhost', async function () {
const fields = { ...baseCorrectParams, targetUrl: 'http://localhost:8000' }
await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
})
it('Should fail with a private IP target urls', async function () {
const targetUrls = [
'http://127.0.0.1:8000',
'http://127.0.0.1',
'http://127.0.0.1/hello',
'https://192.168.1.42',
'http://192.168.1.42'
]
for (const targetUrl of targetUrls) {
const fields = { ...baseCorrectParams, targetUrl }
await makePostBodyRequest({
url: server.url,
path,
token: server.accessToken,
fields,
expectedStatus: HttpStatusCode.FORBIDDEN_403
})
}
})
it('Should fail with a long name', async function () { it('Should fail with a long name', async function () {
const fields = { ...baseCorrectParams, name: 'super'.repeat(65) } const fields = { ...baseCorrectParams, name: 'super'.repeat(65) }