CVE-2021-4437 (published 2024-02-12T20:15Z)

A vulnerability, which was classified as problematic, has been found in dbartholomae lambda-middleware frameguard up to 1.0.4. Affected by this issue is some unknown functionality of the file packages/json-deserializer/src/JsonDeserializer.ts of the component JSON Mime-Type Handler. The manipulation leads to inefficient regular expression complexity. Upgrading to version 1.1.0 is able to address this issue. The patch is identified as f689404d830cbc1edd6a1018d3334ff5f44dc6a6. It is recommended to upgrade the affected component. VDB-253406 is the identifier assigned to this vulnerability.


Weakness information:
cwe_id: CWE-1333
cwe_name: Inefficient Regular Expression Complexity
description: The product uses a regular expression with an inefficient, possibly exponential worst-case computational complexity that consumes excessive CPU cycles.
extended_description: Some regular expression engines have a feature called "backtracking". If the token cannot match, the engine "backtracks" to a position that may result in a different token that can match.
                Backtracking becomes a weakness if all of these conditions are met:
                
                    The number of possible backtracking attempts are exponential relative to the length of the input.
                    The input can fail to match the regular expression.
                    The input can be long enough.
                
		
		  Attackers can create crafted inputs that
		  intentionally cause the regular expression to use
		  excessive backtracking in a way that causes the CPU
		  consumption to spike.
		
            
            

Fix information:
repo_url: https://github.com/dbartholomae/lambda-middleware
commit_details: repo_url: https://github.com/dbartholomae/lambda-middleware
author: Matt Jenner
author_date: 2021-08-31 00:03:23+01:00
msg: fix(json-deserializer): fixed codeQL vulnerability

Removed the regex used to identify a JSON mime-type as this was potentially vulnerable to
'Regular expression Denial of Service attacks' and making changes to make the regex more restrictive (but compliant with RFC 6838) did not pass tests for this issue online.

This now matches based on the last segment of a mimetype being json or json; this should match all the expected mime types.

Updated unit-tests with additional tests for a variety of compatible mime types.
repository: repo_url: https://github.com/dbartholomae/lambda-middleware
repo_name: dbartholomae/lambda-middleware
description: A collection of middleware for AWS lambda functions.
repo_language: TypeScript
owner: dbartholomae
file_changes: filename: JsonDeserializer.test.ts
change_type: ModificationType.MODIFY
diff: @@ -29,16 +29,23 @@ describe("jsonDeserializer", () => {
     },
   };
 
-  it("deserializes objects if the event has a json content-type header", async () => {
-    const event: APIGatewayProxyEvent = createEvent({
-      headers: { "Content-Type": "application/json" },
-      body: JSON.stringify(testObject),
-    });
+  describe("deserializes objects the event has a valid json content-type header:", () => {
+    it.each([
+      ["subtype is json", "application/json"],
+      ["subtype structured syntax specifier is json", "application/ld+json"],
+      ["semicolon is appended", "application/json;"],
+      ["whitespace is appended", "application/json;   "],
+    ])("%s (%p)", async (_string, mimeType: string) => {
+      const event: APIGatewayProxyEvent = createEvent({
+        headers: { "Content-Type": mimeType },
+        body: JSON.stringify(testObject),
+      });
 
-    await handlerWithMiddleware(event, createContext());
-    expect(processedEvent.bodyObject).toMatchObject(
-      JSON.parse(JSON.stringify(testObject))
-    );
+      await handlerWithMiddleware(event, createContext());
+      expect(processedEvent.bodyObject).toMatchObject(
+        JSON.parse(JSON.stringify(testObject))
+      );
+    });
   });
 
   describe("sets the request bodyObject to null if:", () => {

programming_language: TypeScript
filename: JsonDeserializer.ts
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,4 @@
 import { PromiseHandler } from "@lambda-middleware/utils";
-import debugFactory, { IDebugger } from "debug";
 import {
   APIGatewayProxyEvent,
   APIGatewayProxyResult,
@@ -8,8 +7,6 @@ import {
 import { APIGatewayProxyObjectEvent } from "./types/APIGatewayProxyObjectEvent";
 import { RequestBodyNotJsonError } from "./customErrors/RequestBodyNotJsonError";
 
-const logger: IDebugger = debugFactory("@lambda-middleware/json-serializer");
-
 export const jsonDeserializer = <E extends APIGatewayProxyEvent>() => (
   handler: PromiseHandler<APIGatewayProxyObjectEvent<E>, APIGatewayProxyResult>
 ) => async (event: E, context: Context): Promise<APIGatewayProxyResult> => {
@@ -50,6 +47,13 @@ const isJsonMimeType = (event: APIGatewayProxyEvent) => {
     return false;
   }
 
-  const mimePattern = /^application\/(.+\+)?json(;.*)?$/;
-  return mimePattern.test(contentTypeHeader);
+  const mimeParts = contentTypeHeader.split("/");
+
+  if (mimeParts.length != 2) {
+    return false;
+  }
+
+  const lastSubtypePart = mimeParts[1].toLowerCase().split("+").pop()?.trim();
+
+  return lastSubtypePart === "json" || lastSubtypePart === "json;";
 };

programming_language: TypeScript