mirror of
https://git.sr.ht/~cadence/bibliogram
synced 2025-12-14 10:35:07 +00:00
Fix exploit and add tests for proxy URL validator
This commit is contained in:
@@ -1,3 +1,31 @@
|
||||
/**
|
||||
* Check that a host is part of Instagram's CDN.
|
||||
* @param {string} host
|
||||
*/
|
||||
function verifyHost(host) {
|
||||
const domains = ["fbcdn.net", "cdninstagram.com"]
|
||||
return domains.some(against => host === against || host.endsWith("." + against))
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a resource is on Instagram.
|
||||
* @param {URL} completeURL
|
||||
*/
|
||||
function verifyURL(completeURL) {
|
||||
const params = completeURL.searchParams
|
||||
if (!params.get("url")) return {status: "fail", value: [400, "Must supply `url` query parameter"]}
|
||||
try {
|
||||
var url = new URL(params.get("url"))
|
||||
} catch (e) {
|
||||
return {status: "fail", value: [400, "`url` query parameter is not a valid URL"]}
|
||||
}
|
||||
// check url protocol
|
||||
if (url.protocol !== "https:") return {status: "fail", value: [400, "URL protocol must be `https:`"]}
|
||||
// check url host
|
||||
if (!verifyHost(url.host)) return {status: "fail", value: [400, "URL host is not allowed"]}
|
||||
return {status: "ok", url}
|
||||
}
|
||||
|
||||
function proxyImage(url, width) {
|
||||
const params = new URLSearchParams()
|
||||
if (width) params.set("width", width)
|
||||
@@ -23,7 +51,7 @@ function proxyVideo(url) {
|
||||
*/
|
||||
function proxyExtendedOwner(owner) {
|
||||
const clone = {...owner}
|
||||
clone.profile_pic_url = proxyImage(clone.profile_pic_url)
|
||||
clone.profile_pic_url = proxyProfilePic(clone.profile_pic_url, clone.id)
|
||||
return clone
|
||||
}
|
||||
|
||||
@@ -31,3 +59,5 @@ module.exports.proxyImage = proxyImage
|
||||
module.exports.proxyProfilePic = proxyProfilePic
|
||||
module.exports.proxyVideo = proxyVideo
|
||||
module.exports.proxyExtendedOwner = proxyExtendedOwner
|
||||
module.exports.verifyHost = verifyHost
|
||||
module.exports.verifyURL = verifyURL
|
||||
|
||||
@@ -3,27 +3,10 @@ const sharp = require("sharp")
|
||||
const constants = require("../../lib/constants")
|
||||
const collectors = require("../../lib/collectors")
|
||||
const {request} = require("../../lib/utils/request")
|
||||
const {verifyURL} = require("../../lib/utils/proxyurl")
|
||||
const db = require("../../lib/db")
|
||||
require("../../lib/testimports")(constants, request, db)
|
||||
require("../../lib/testimports")(constants, request, db, verifyURL)
|
||||
|
||||
/**
|
||||
* Check that a resource is on Instagram.
|
||||
* @param {URL} completeURL
|
||||
*/
|
||||
function verifyURL(completeURL) {
|
||||
const params = completeURL.searchParams
|
||||
if (!params.get("url")) return {status: "fail", value: [400, "Must supply `url` query parameter"]}
|
||||
try {
|
||||
var url = new URL(params.get("url"))
|
||||
} catch (e) {
|
||||
return {status: "fail", value: [400, "`url` query parameter is not a valid URL"]}
|
||||
}
|
||||
// check url protocol
|
||||
if (url.protocol !== "https:") return {status: "fail", value: [400, "URL protocol must be `https:`"]}
|
||||
// check url host
|
||||
if (!["fbcdn.net", "cdninstagram.com"].some(host => url.host.endsWith(host))) return {status: "fail", value: [400, "URL host is not allowed"]}
|
||||
return {status: "ok", url}
|
||||
}
|
||||
|
||||
function statusCodeIsAcceptable(status) {
|
||||
return (status >= 200 && status < 300) || status === 304
|
||||
|
||||
Reference in New Issue
Block a user