Correctly check import target URL IP
This commit is contained in:
parent
4afec73571
commit
f33e515991
|
@ -9,7 +9,7 @@ import { genericUploadErrorHandler, scrollToTop } from '@app/helpers'
|
||||||
import { FormValidatorService } from '@app/shared/shared-forms'
|
import { FormValidatorService } from '@app/shared/shared-forms'
|
||||||
import { BytesPipe, Video, VideoCaptionService, VideoEdit, VideoService } from '@app/shared/shared-main'
|
import { BytesPipe, Video, VideoCaptionService, VideoEdit, VideoService } from '@app/shared/shared-main'
|
||||||
import { LoadingBarService } from '@ngx-loading-bar/core'
|
import { LoadingBarService } from '@ngx-loading-bar/core'
|
||||||
import { HttpStatusCode, VideoCreateResult, VideoPrivacy } from '@shared/models'
|
import { HttpStatusCode, VideoCreateResult } from '@shared/models'
|
||||||
import { UploaderXFormData } from './uploaderx-form-data'
|
import { UploaderXFormData } from './uploaderx-form-data'
|
||||||
import { VideoSend } from './video-send'
|
import { VideoSend } from './video-send'
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { lookup } from 'dns'
|
||||||
|
import { parse as parseIP } from 'ipaddr.js'
|
||||||
|
|
||||||
|
function dnsLookupAll (hostname: string) {
|
||||||
|
return new Promise<string[]>((res, rej) => {
|
||||||
|
lookup(hostname, { family: 0, all: true }, (err, adresses) => {
|
||||||
|
if (err) return rej(err)
|
||||||
|
|
||||||
|
return res(adresses.map(a => a.address))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function isResolvingToUnicastOnly (hostname: string) {
|
||||||
|
const addresses = await dnsLookupAll(hostname)
|
||||||
|
|
||||||
|
for (const address of addresses) {
|
||||||
|
const parsed = parseIP(address)
|
||||||
|
|
||||||
|
if (parsed.range() !== 'unicast') return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
dnsLookupAll,
|
||||||
|
isResolvingToUnicastOnly
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import { body, param } from 'express-validator'
|
import { body, param } from 'express-validator'
|
||||||
import { isValid as isIPValid, parse as parseIP } from 'ipaddr.js'
|
import { isResolvingToUnicastOnly } from '@server/helpers/dns'
|
||||||
import { isPreImportVideoAccepted } from '@server/lib/moderation'
|
import { isPreImportVideoAccepted } from '@server/lib/moderation'
|
||||||
import { Hooks } from '@server/lib/plugins/hooks'
|
import { Hooks } from '@server/lib/plugins/hooks'
|
||||||
import { MUserAccountId, MVideoImport } from '@server/types/models'
|
import { MUserAccountId, MVideoImport } from '@server/types/models'
|
||||||
|
@ -76,10 +76,7 @@ const videoImportAddValidator = getCommonVideoEditAttributes().concat([
|
||||||
if (req.body.targetUrl) {
|
if (req.body.targetUrl) {
|
||||||
const hostname = new URL(req.body.targetUrl).hostname
|
const hostname = new URL(req.body.targetUrl).hostname
|
||||||
|
|
||||||
if (isIPValid(hostname)) {
|
if (await isResolvingToUnicastOnly(hostname) !== true) {
|
||||||
const parsed = parseIP(hostname)
|
|
||||||
|
|
||||||
if (parsed.range() !== 'unicast') {
|
|
||||||
cleanUpReqFiles(req)
|
cleanUpReqFiles(req)
|
||||||
|
|
||||||
return res.fail({
|
return res.fail({
|
||||||
|
@ -88,7 +85,6 @@ const videoImportAddValidator = getCommonVideoEditAttributes().concat([
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!await isImportAccepted(req, res)) return cleanUpReqFiles(req)
|
if (!await isImportAccepted(req, res)) return cleanUpReqFiles(req)
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,8 @@ describe('Test video imports API validator', function () {
|
||||||
'http://127.0.0.1',
|
'http://127.0.0.1',
|
||||||
'http://127.0.0.1/hello',
|
'http://127.0.0.1/hello',
|
||||||
'https://192.168.1.42',
|
'https://192.168.1.42',
|
||||||
'http://192.168.1.42'
|
'http://192.168.1.42',
|
||||||
|
'http://127.0.0.1.cpy.re'
|
||||||
]
|
]
|
||||||
|
|
||||||
for (const targetUrl of targetUrls) {
|
for (const targetUrl of targetUrls) {
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||||
|
|
||||||
|
import 'mocha'
|
||||||
|
import { expect } from 'chai'
|
||||||
|
import { isResolvingToUnicastOnly } from '@server/helpers/dns'
|
||||||
|
|
||||||
|
describe('DNS helpers', function () {
|
||||||
|
|
||||||
|
it('Should correctly check unicast IPs', async function () {
|
||||||
|
expect(await isResolvingToUnicastOnly('cpy.re')).to.be.true
|
||||||
|
expect(await isResolvingToUnicastOnly('framasoft.org')).to.be.true
|
||||||
|
expect(await isResolvingToUnicastOnly('8.8.8.8')).to.be.true
|
||||||
|
|
||||||
|
expect(await isResolvingToUnicastOnly('127.0.0.1')).to.be.false
|
||||||
|
expect(await isResolvingToUnicastOnly('127.0.0.1.cpy.re')).to.be.false
|
||||||
|
})
|
||||||
|
})
|
|
@ -1,5 +1,6 @@
|
||||||
import './image'
|
import './image'
|
||||||
import './core-utils'
|
import './core-utils'
|
||||||
|
import './dns'
|
||||||
import './comment-model'
|
import './comment-model'
|
||||||
import './markdown'
|
import './markdown'
|
||||||
import './request'
|
import './request'
|
||||||
|
|
Loading…
Reference in New Issue