Merge pull request from GHSA-24m5-7vjx-9x37

* Restrict emby endpoints and proxy segments

* Dont allow path traversal in segments

* Restrict qbittorrent proxy endpoints

* Restrict npm proxy endpoints

* Restrict flood proxy endpoints

* Restrict tdarr proxy endpoints

* Restrict xteve proxy endpoints

* Restrict transmission proxy endpoints

* disallow non-mapped endpoints

this change drops all requests that have un-mapped endpoint queries

allowedEndpoints is added as a method to pass proxy requests via a regex on the endpoint

most widgets with custom proxies use either no endpoint, or a static one

Co-Authored-By: Ben Phelps <ben@phelps.io>
This commit is contained in:
shamoon 2024-06-02 20:11:03 -07:00
parent 8823b04291
commit 52cce0ee21
22 changed files with 79 additions and 35 deletions

View file

@ -18,6 +18,11 @@ export default async function handler(req, res) {
const serviceProxyHandler = widget.proxyHandler || genericProxyHandler;
if (serviceProxyHandler instanceof Function) {
// quick return for no endpoint services
if (!req.query.endpoint) {
return serviceProxyHandler(req, res);
}
// map opaque endpoints to their actual endpoint
if (widget?.mappings) {
const mapping = widget?.mappings?.[req.query.endpoint];
@ -38,6 +43,15 @@ export default async function handler(req, res) {
if (req.query.segments) {
const segments = JSON.parse(req.query.segments);
for (const key in segments) {
if (!mapping.segments.includes(key)) {
logger.debug("Unsupported segment: %s", key);
return res.status(403).json({ error: "Unsupported segment" });
} else if (segments[key].includes("/")) {
logger.debug("Unsupported segment value: %s", segments[key]);
return res.status(403).json({ error: "Unsupported segment value" });
}
}
req.query.endpoint = formatApiCall(endpoint, segments);
}
@ -66,7 +80,14 @@ export default async function handler(req, res) {
return serviceProxyHandler(req, res, map);
}
return serviceProxyHandler(req, res);
if (widget.allowedEndpoints instanceof RegExp) {
if (widget.allowedEndpoints.test(req.query.endpoint)) {
return serviceProxyHandler(req, res);
}
}
logger.debug("Unmapped proxy request.");
return res.status(403).json({ error: "Unmapped proxy request." });
}
logger.debug("Unknown proxy service type: %s", type);