Fix issue with single quotes in payload for NodeJS lambda in local execution mode
diff --git a/localstack/services/awslambda/lambda_executors.py b/localstack/services/awslambda/lambda_executors.py
index 17969408fdbc7..272525cbb7f38 100644
--- a/localstack/services/awslambda/lambda_executors.py
+++ b/localstack/services/awslambda/lambda_executors.py
@@ -1112,7 +1112,7 @@ def execute_in_container(
 
 class LambdaExecutorLocal(LambdaExecutor):
     def _execute_in_custom_runtime(
-        self, cmd: str, lambda_function: LambdaFunction = None
+        self, cmd: Union[str, List[str]], lambda_function: LambdaFunction = None
     ) -> InvocationResult:
         """
         Generic run function for executing lambdas in custom runtimes.
@@ -1313,15 +1313,17 @@ def execute_javascript_lambda(
         function = handler.split(".")[-1]
         event_json_string = "%s" % (json.dumps(json_safe(event)) if event else "{}")
         context_json_string = "%s" % (json.dumps(context.__dict__) if context else "{}")
-        cmd = (
-            "node -e 'require(\"%s\").%s(%s,%s).then(r => process.stdout.write(JSON.stringify(r)))'"
+        cmd = [
+            "node",
+            "-e",
+            'require("%s").%s(%s,%s).then(r => process.stdout.write(JSON.stringify(r)))'
             % (
                 main_file,
                 function,
                 event_json_string,
                 context_json_string,
-            )
-        )
+            ),
+        ]
         LOG.info(cmd)
         result = self._execute_in_custom_runtime(cmd, lambda_function=lambda_function)
         return result
diff --git a/tests/integration/test_lambda.py b/tests/integration/test_lambda.py
index 9de25f54252a7..eff6d56f59ec7 100644
--- a/tests/integration/test_lambda.py
+++ b/tests/integration/test_lambda.py
@@ -1527,6 +1527,37 @@ def test_invoke_nodejs_lambda(self):
             # clean up
             testutil.delete_lambda_function(TEST_LAMBDA_NAME_JS)
 
+    def test_invoke_nodejs_lambda_with_payload_containing_quotes(self):
+        handler_file = os.path.join(THIS_FOLDER, "lambdas", "lambda_handler.js")
+        function_name = "test_lambda_%s" % short_uid()
+        testutil.create_lambda_function(
+            func_name=function_name,
+            zip_file=testutil.create_zip_file(handler_file, get_content=True),
+            runtime=LAMBDA_RUNTIME_NODEJS14X,
+            handler="lambda_handler.handler",
+        )
+
+        test_string = "test_string' with some quotes"
+        body = '{"test_var": "%s"}' % test_string
+        try:
+            rs = self.lambda_client.invoke(
+                FunctionName=function_name,
+                Payload=body,
+            )
+            assert 200 == rs["ResponseMetadata"]["HTTPStatusCode"]
+
+            payload = rs["Payload"].read()
+            response = json.loads(to_str(payload))
+            assert "response from localstack lambda" in response["body"]
+
+            events = get_lambda_log_events(function_name)
+            assert len(events) > 0
+            assert test_string in str(events[0])
+
+        finally:
+            # clean up
+            testutil.delete_lambda_function(function_name)
+
 
 class TestCustomRuntimes(LambdaTestBase):
     @classmethod

Closes #4671 .

Replaces the current execution by using the array-based command representation which does not need a shell to run (and has therefore no problem with string escapes using quotes).