From b0ff599b2c32b83d7d45c41ef215372044ccda23 Mon Sep 17 00:00:00 2001 From: Peter Somogyvari Date: Mon, 9 Oct 2023 10:49:24 -0700 Subject: [PATCH] fix(cmd-api-server): add runtime type validation to HTTP verbs pulled from OAS This addresses the shortcomings of the linter fix provided in #2751, which uses unchecked casts to the linter warnings go away. With the fix of #2751, at runtime, the possibility of a crash is still there exactly as before, but it has silenced the linter about calling that possibility out. We now use a type guard to check the type of the object before casting it and therefore ensure that at runtime the cast will not produce a crash. [skip ci] Depends on #2751 Depends on #2754 Signed-off-by: Peter Somogyvari --- .../src/main/typescript/api-server.ts | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/cactus-cmd-api-server/src/main/typescript/api-server.ts b/packages/cactus-cmd-api-server/src/main/typescript/api-server.ts index ab154b9b5f..583991c39b 100644 --- a/packages/cactus-cmd-api-server/src/main/typescript/api-server.ts +++ b/packages/cactus-cmd-api-server/src/main/typescript/api-server.ts @@ -46,6 +46,7 @@ import { installOpenapiValidationMiddleware } from "@hyperledger/cactus-core"; import { Bools, + isExpressHttpVerbMethodName, Logger, LoggerProvider, newRex, @@ -563,6 +564,7 @@ export class ApiServer { * @param app */ async getOrCreateWebServices(app: express.Express): Promise { + const fnTag = `${this.className}#getOrCreateWebServices()}`; const { log } = this; const { logLevel } = this.options.config; const pluginRegistry = await this.getOrInitPluginRegistry(); @@ -595,10 +597,11 @@ export class ApiServer { const { "/api/v1/api-server/healthcheck": oasPath } = OAS.paths; const { http } = oasPath.get["x-hyperledger-cactus"]; const { path: httpPath, verbLowerCase: httpVerb } = http; - (app as express.Express)[httpVerb as keyof express.Express]( - httpPath, - healthcheckHandler, - ); + if (!isExpressHttpVerbMethodName(httpVerb)) { + const eMsg = `${fnTag} Invalid HTTP verb "${httpVerb}" in cmd-api-server OpenAPI specification for HTTP path: "${httpPath}"`; + throw new RuntimeError(eMsg); + } + app[httpVerb](httpPath, healthcheckHandler); this.wsApi.on("connection", (socket: SocketIoSocket) => { const { id } = socket; @@ -629,14 +632,19 @@ export class ApiServer { const { "/api/v1/api-server/get-prometheus-exporter-metrics": oasPathPrometheus, } = OAS.paths; + const { http: httpPrometheus } = oasPathPrometheus.get["x-hyperledger-cactus"]; + const { path: httpPathPrometheus, verbLowerCase: httpVerbPrometheus } = httpPrometheus; - (app as express.Express)[httpVerbPrometheus as keyof express.Express]( - httpPathPrometheus, - prometheusExporterHandler, - ); + + if (!isExpressHttpVerbMethodName(httpVerbPrometheus)) { + const eMsg = `${fnTag} Invalid HTTP verb "${httpVerbPrometheus}" in cmd-api-server OpenAPI specification for HTTP path: "${httpPathPrometheus}"`; + throw new RuntimeError(eMsg); + } + + app[httpVerbPrometheus](httpPathPrometheus, prometheusExporterHandler); } async startGrpcServer(): Promise {