CVE-2018-11757 (published 2018-07-23T17:29Z)

In Docker Skeleton Runtime for Apache OpenWhisk, a Docker action inheriting the Docker tag openwhisk/dockerskeleton:1.3.0 (or earlier) may allow an attacker to replace the user function inside the container if the user code is vulnerable to code exploitation.

Severity: HIGH
CVSS v2 base score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 9.8, CRITICAL (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/apache/incubator-openwhisk-runtime-docker
commit_details: repo_url: https://github.com/apache/incubator-openwhisk-runtime-docker
author: Rodric Rabbah
author_date: 2018-07-05 15:19:21-04:00
msg: Do not allow re-init of the action exec.

Disables re-initialization of the executable unless explicitly permitted
via an environment variable PROXY_ALLOW_REINIT == "1", which is generally
useful for local testing and development.
repository: repo_url: https://github.com/apache/incubator-openwhisk-runtime-docker
repo_name: apache/openwhisk-runtime-docker
description: Apache OpenWhisk SDK for building Docker "blackbox" runtimes
repo_language: Python
owner: apache
file_changes: filename: actionproxy.py
change_type: ModificationType.MODIFY
diff: @@ -203,9 +203,12 @@ class ActionRunner:
 
 proxy = flask.Flask(__name__)
 proxy.debug = False
+# disable re-initialization of the executable unless explicitly allowed via an environment
+# variable PROXY_ALLOW_REINIT == "1" (this is generally useful for local testing and development)
+proxy.rejectReinit = 'PROXY_ALLOW_REINIT' not in os.environ or os.environ['PROXY_ALLOW_REINIT'] != "1"
+proxy.initialized = False
 runner = None
 
-
 def setRunner(r):
     global runner
     runner = r
@@ -213,6 +216,13 @@ def setRunner(r):
 
 @proxy.route('/init', methods=['POST'])
 def init():
+    if proxy.rejectReinit is True and proxy.initialized is True:
+        msg = 'Cannot initialize the action more than once.'
+        sys.stderr.write(msg + '\n')
+        response = flask.jsonify({'error': msg})
+        response.status_code = 403
+        return complete(response)
+
     message = flask.request.get_json(force=True, silent=True)
     if message and not isinstance(message, dict):
         flask.abort(404)
@@ -228,6 +238,7 @@ def init():
         status = False
 
     if status is True:
+        proxy.initialized = True
         return ('OK', 200)
     else:
         response = flask.jsonify({'error': 'The action failed to generate or locate a binary. See logs for details.'})

programming_language: Python
filename: ActionProxyContainerTests.scala
change_type: ModificationType.MODIFY
diff: @@ -245,4 +245,5 @@ class ActionProxyContainerTests extends BasicActionRunnerTests with WskActorSyst
   testUnicode(stdUnicodeSamples)
   testEnv(stdEnvSamples)
   testLargeInput(stdLargeInputSamples)
+  testInitCannotBeCalledMoreThanOnce(codeNotReturningJson) // any code sample will do
 }

programming_language: Scala