From 7553827223edb9b54a7cbc87c451cb6140549592 Mon Sep 17 00:00:00 2001 From: Dominik Henneke Date: Fri, 11 Sep 2020 13:05:53 +0200 Subject: [PATCH] feat(proxy-backend): support limiting the proxied HTTP methods --- docs/plugins/proxying.md | 5 ++++- plugins/proxy-backend/package.json | 1 + plugins/proxy-backend/src/service/router.ts | 14 ++++++++++++-- yarn.lock | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/plugins/proxying.md b/docs/plugins/proxying.md index 658df3dda1..1951f41763 100644 --- a/docs/plugins/proxying.md +++ b/docs/plugins/proxying.md @@ -52,7 +52,10 @@ configuration will lead to the proxy acting on backend requests to The value inside each route is either a simple URL string, or an object on the format accepted by -[http-proxy-middleware](https://www.npmjs.com/package/http-proxy-middleware). +[http-proxy-middleware](https://www.npmjs.com/package/http-proxy-middleware). It +is also possible to limit the forwarded HTTP methods with the configuration +`allowedMethods`, for example `allowedMethods: ['GET']` to enforce read-only +access. If the value is a string, it is assumed to correspond to: diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 9f3bc16103..efda451fd5 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -22,6 +22,7 @@ "@backstage/backend-common": "^0.1.1-alpha.21", "@backstage/config": "^0.1.1-alpha.21", "@types/express": "^4.17.6", + "@types/http-proxy-middleware": "^0.19.3", "express": "^4.17.1", "express-promise-router": "^3.0.3", "http-proxy-middleware": "^0.19.1", diff --git a/plugins/proxy-backend/src/service/router.ts b/plugins/proxy-backend/src/service/router.ts index 5c5e17b872..7cd5f37598 100644 --- a/plugins/proxy-backend/src/service/router.ts +++ b/plugins/proxy-backend/src/service/router.ts @@ -18,10 +18,11 @@ import { Config } from '@backstage/config'; import express from 'express'; import Router from 'express-promise-router'; import createProxyMiddleware, { - Config as ProxyConfig, + Config as ProxyMiddlewareConfig, Proxy, } from 'http-proxy-middleware'; import { Logger } from 'winston'; +import http from 'http'; export interface RouterOptions { logger: Logger; @@ -30,6 +31,10 @@ export interface RouterOptions { pathPrefix: string; } +export interface ProxyConfig extends ProxyMiddlewareConfig { + allowedMethods?: string[]; +} + // Creates a proxy middleware, possibly with defaults added on top of the // given config. function buildMiddleware( @@ -58,7 +63,12 @@ function buildMiddleware( // Attach the logger to the proxy config fullConfig.logProvider = () => logger; - return createProxyMiddleware(fullConfig); + // Only permit the allowed HTTP methods if configured + const filter = (_pathname: string, req: http.IncomingMessage): boolean => { + return fullConfig?.allowedMethods?.includes(req.method!) ?? true; + }; + + return createProxyMiddleware(filter, fullConfig); } export async function createRouter( diff --git a/yarn.lock b/yarn.lock index 6865bdc256..11bb8a3fd8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4209,7 +4209,7 @@ resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.0.tgz#682477dbbbd07cd032731cb3b0e7eaee3d026b69" integrity sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA== -"@types/http-proxy-middleware@*": +"@types/http-proxy-middleware@*", "@types/http-proxy-middleware@^0.19.3": version "0.19.3" resolved "https://registry.npmjs.org/@types/http-proxy-middleware/-/http-proxy-middleware-0.19.3.tgz#b2eb96fbc0f9ac7250b5d9c4c53aade049497d03" integrity sha512-lnBTx6HCOUeIJMLbI/LaL5EmdKLhczJY5oeXZpX/cXE4rRqb3RmV7VcMpiEfYkmTjipv3h7IAyIINe4plEv7cA==